I would like to "concatenate" results of detections of
positions of specific values in my array "Coord3".
I have a double criteria on my array for 2 specific dimension of it.
I get some redondant positions and i would like to gather it in order to apply a mask
of this values.
As example with a moderate array :
import numpy as np
Coord3 = np.array([[[[ 0., 0.],
[ 0., 1.],
[ 0., 2.]],
[[ 1., 0.],
[ 1., 1.],
[ 1., 2.]],
[[ 2., 0.],
[ 2., 1.],
[ 2., 2.]]],
[[[ 1., 0.],
[ 1., 1.],
[ 1., 2.]],
[[ 2., 0.],
[ 2., 1.],
[ 2., 2.]],
[[ 4., 0.],
[ 3., 1.],
[ 4., 2.]]],
[[[ 2., 0.],
[ 2., 1.],
[ 2., 2.]],
[[ 3., 0.],
[ 3., 1.],
[ 3., 2.]],
[[ 4., 0.],
[ 4., 1.],
[ 4., 4.]]]])
#I apply my double criteria in 2 shapes of my array Coord3
plaY=[]
for i in range(Coord3.shape[0]):
holding_list = zip(*np.where(Coord3[i,:,:,0] > 3))
plaY.append(holding_list)
plaY_array = np.asarray(plaY)
#plaY_array
#Out[1088]: array([[], [(2, 0), (2, 2)], [(2, 0), (2, 1), (2, 2)]], dtype=object)
plaX=[]
for i in range(Coord3.shape[0]):
holding_list = zip(*np.where(Coord3[i,:,:,1] > 2))
plaX.append(holding_list)
plaX_array = np.asarray(plaX)
#plaX_array
#Out[1097]: array([[], [], [(2, 2)]], dtype=object)
So (2,0) and (2,2) are redondant and i would like to supress it and to gather all in an unique array... as :
np.array([[2, 0], [2, 2],....])
--- EDIT LATER ------------------------------------------
I could concatenate for each specific time
plaY_array = plaY_array[:,np.newaxis]
plaX_array = plaX_array[:,np.newaxis]
test = plaX_array + plaY_array
#I get that :
#test
#array([[[[]]],
#[[[(2, 0), (2, 2)]]],
#[[[(2, 0), (2, 1), (2, 2), (2, 2)]]]], dtype=object)
So now i have to suppress just the (2,2) redondant in the "third slice", it could be interesting to know the coordinates for each specific time (so i let the (2,2) in "2nd slice"
You could turn the list of coordinates into a set to remove duplicates:
In [21]: set(zip(*(np.where(Coord3[:,:,:,0] > 3)[1:])))
Out[21]: {(2, 0), (2, 1), (2, 2)}
plaY_array = np.array(list(set(zip(*(np.where(Coord3[:,:,:,0] > 3)[1:])))))
plaX_array = np.array(list(set(zip(*(np.where(Coord3[:,:,:,1] > 2)[1:])))))
print(plaY_array)
# [[2 0]
# [2 1]
# [2 2]]
print(plaX_array)
# [[2 2]]
Also note that you can eliminate the for-loop
for i in range(Coord3.shape[0]):
by calling np.where(Coord3[:,:,:,0] > 3) instead of np.where(Coord3[i,:,:,0] > 3)
for each i:
In [16]: np.where(Coord3[:,:,:,0] > 3)
Out[16]: (array([1, 1, 2, 2, 2]), array([2, 2, 2, 2, 2]), array([0, 2, 0, 1, 2]))
The i values are in the first array, but since you don't care about those, you can just drop the first array.
Related
How can i use two for loops to replace the values in x with the row number, starting at 1, so it should be [[1,1,1,1,1],[2,2,2,2,2] … [5,5,5,5,5]]
x=np.ones((5,5))
print(x)
Thanks
Don't use for loops in numpy, use broadcasting:
x=np.ones((5,5))
x[:] = np.arange(x.shape[0])[:, None]+1
Updated x:
array([[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.],
[5., 5., 5., 5., 5.]])
Alternatives:
x[:] = np.arange(x.shape[0])[:, np.newaxis]+1
Or:
x[:] = np.arange(x.shape[0]).reshape(-1, 1)+1
I have
blank = np.zeros(shape = im.shape, dtype = np.float32)
which generates
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]], dtype=float32)
I have [label2poly[label]] which is dtype('int32')
[array([[ 716, 1],
[ 710, 281],
[ 727, 322],
[ 756, 369],
[ 793, 399],
[ 863, 406],
[ 952, 416],
[ 978, 412],
[ 416, 1]])]
When I try cv2.fillPoly(blank, [label2poly[label]], 255) it outputs
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]], dtype=float32)`
where it should have been something like
array([[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 255., ..., 0., 0., 0.],
[ 0., 0., 255., ..., 0., 0., 0.],
...,
[ 0., 255., 255., ..., 255., 255., 255.],
[ 0., 255., 255., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.]], dtype=float32)
I am trying to create multiple masks. Would appreciate any help.
Initialization of blank:
blank = np.zeros(shape=[5, 5], dtype=np.float32)
print(blank)
Output:
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
Initialization of label followed by a call to fillPoly() which uses is as a mask to fill blank with 255 at specific positions:
label = np.array([[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]], dtype=np.int32)
cv2.fillPoly(blank, [label], 255)
print(blank)
Output:
[[ 0. 0. 0. 0. 0.]
[ 0. 255. 255. 255. 0.]
[ 0. 255. 255. 255. 0.]
[ 0. 255. 255. 255. 0.]
[ 0. 0. 0. 0. 0.]]
I'm new to numpy and I must be doing something stupid here, but all I want is to generate an array of 4-dimention probability distributions. I don't understand why my vectorised function is returning this weird object which claims to be of type np.ndarray but doesn't print like one. Also, it returns error when I call self.inputSpace[:,0].
Here's the entire content of test.py:
import numpy as np
def generateDist(i,j,k):
return np.squeeze(np.array([i*j,i*(1-j),(1-i)*k,(1-i)*(1-k)]))
generateDist = np.vectorize(generateDist,otypes=[np.ndarray])
class distributionSpace():
def __init__(self):
self.grid = 3 # set to 3 for simplicity
self.inputSpace = np.array([])
def generateDistribution(self):
alpha = np.linspace(0.,1.,self.grid)
beta = np.linspace(0.,1.,self.grid)
gamma = np.linspace(0.,1.,self.grid)
i , j , k = np.meshgrid(alpha,beta,gamma)
i = np.squeeze(i.flatten())
j = np.squeeze(j.flatten())
k = np.squeeze(k.flatten())
self.inputSpace = generateDist(i,j,k)
print(self.inputSpace)
return self
if __name__ == '__main__':
distributionSpace().generateDistribution()
And here's the result I got:
$ python3 test.py
[array([ 0., 0., 0., 1.]) array([ 0. , 0. , 0.5, 0.5])
array([ 0., 0., 1., 0.]) array([ 0. , 0.5, 0. , 0.5])
array([ 0. , 0.5 , 0.25, 0.25]) array([ 0. , 0.5, 0.5, 0. ])
array([ 0., 1., 0., 0.]) array([ 0., 1., 0., 0.])
array([ 0., 1., 0., 0.]) array([ 0., 0., 0., 1.])
array([ 0. , 0. , 0.5, 0.5]) array([ 0., 0., 1., 0.])
array([ 0.25, 0.25, 0. , 0.5 ]) array([ 0.25, 0.25, 0.25, 0.25])
array([ 0.25, 0.25, 0.5 , 0. ]) array([ 0.5, 0.5, 0. , 0. ])
array([ 0.5, 0.5, 0. , 0. ]) array([ 0.5, 0.5, 0. , 0. ])
array([ 0., 0., 0., 1.]) array([ 0. , 0. , 0.5, 0.5])
array([ 0., 0., 1., 0.]) array([ 0.5, 0. , 0. , 0.5])
array([ 0.5 , 0. , 0.25, 0.25]) array([ 0.5, 0. , 0.5, 0. ])
array([ 1., 0., 0., 0.]) array([ 1., 0., 0., 0.])
array([ 1., 0., 0., 0.])]
Found an answer here for people who are searching :
Using Numpy Vectorize on Functions that Return Vectors
tl;dr:
self.inputSpace = np.array(generateDist(i,j,k).tolist())
For example, if I have a NumPy array
import numpy as np
a = np.arange(10)
b = np.zeros(5)
How can I insert b to the beginning of a?
I know I can make a new array of size len(a)+len(b) and do slice assignment, but is there a way to directly insert the array?
How about this:
c = np.hstack([b, a])
You can use numpy.concatenate:
>>> np.concatenate((b, a))
array([ 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6., 7.,
8., 9.])
This should be easy...
I want to concatenate arrays A, B and C. It is possible that one or more of them may not exist or be empty. I want the remaining arrays to be concatenated. If, for example, B is empty, I want to concatenate A with C.
I've read these questions that seem relevant:
How can I check whether the numpy array is empty or not?
How do you 'remove' a numpy array from a list of numpy arrays?
I assume there's a 1-2 line way to do this.
Concatenating empty arrays is not a problem:
In [1]: a = np.arange(10)
In [2]: b = np.array([])
In [3]: c = np.arange(3)
In [4]: np.concatenate((a,b,c))
Out[4]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 0., 1., 2.])
For 2D arrays:
In [1]: a = np.arange(12.0).reshape((4,3))
In [2]: b = np.arange(24.0).reshape((8,3))
In [3]: c = np.array([])
In [4]: np.concatenate([x for x in [a,b,c] if x.size > 0])
Out[4]:
array([[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.],
[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.],
[ 12., 13., 14.],
[ 15., 16., 17.],
[ 18., 19., 20.],
[ 21., 22., 23.]])