Related
I'm looking for a way to extract zones of ones in a binary numpy array to put different values, for instance, for the following array:
x=[[0,1,1,0,0,0],
[0,1,1,0,0,0],
[0,1,0,0,0,0],
[0,0,0,1,1,0],
[0,0,1,1,1,0],
[0,0,0,0,0,0]]
Expected result:
x=[[0,2,2,0,0,0],
[0,2,2,0,0,0],
[0,2,0,0,0,0],
[0,0,0,3,3,0],
[0,0,3,3,3,0],
[0,0,0,0,0,0]]
Use scipy.ndimage.label:
x=[[0,1,1,0,0,0],
[0,1,1,0,0,0],
[0,1,0,0,0,0],
[0,0,0,1,1,0],
[0,0,1,1,1,0],
[0,0,0,0,0,0]]
a = np.array(x)
from scipy.ndimage import label
b = label(a)[0]
output:
# b
array([[0, 1, 1, 0, 0, 0],
[0, 1, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0],
[0, 0, 0, 2, 2, 0],
[0, 0, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0]], dtype=int32)
to start labeling from 2:
b = (label(a)[0]+1)*a
output:
array([[0, 2, 2, 0, 0, 0],
[0, 2, 2, 0, 0, 0],
[0, 2, 0, 0, 0, 0],
[0, 0, 0, 3, 3, 0],
[0, 0, 3, 3, 3, 0],
[0, 0, 0, 0, 0, 0]])
I need to insert a matrix inside another one using numpy
The matrix i need to insert is like this one:
tetraminos = [[0, 1, 0],
[1, 1, 1]]
While the other matrix is like this:
board = numpy.array([
[6,0,0,0,0,0,0,0,0,0],
[6,0,0,0,0,0,0,0,0,0]
])
The code i'm actually using this one:
board[0:0 + len(tetraminos), 0:0 + len(tetraminos[0])] = tetraminos
The problem matrix that i'm getting is this one:
wrong_matrix = numpy.array([
[[0,1,0,0,0,0,0,0,0,0],
[1,1,1,0,0,0,0,0,0,0]]
])
while the expected result is:
expected_result = numpy.array([
[6,1,0,0,0,0,0,0,0,0],
[1,1,1,0,0,0,0,0,0,0]
])
The error is that, since the matrix contains 0, when i insert it inside the new one i lost the first value in the first row (the number 6), while i wanted to keep it
Full code:
import numpy
if __name__ == '__main__':
board = numpy.array([
[6,0,0,0,0,0,0,0,0,0],
[6,0,0,0,0,0,0,0,0,0]
])
tetraminos = [[0, 1, 0], [1, 1, 1]]
board[0:0 + len(tetraminos), 0:0 + len(tetraminos[0])] = tetraminos
print(board)
expected_result = numpy.array([
[6,1,0,0,0,0,0,0,0,0],
[1,1,1,0,0,0,0,0,0,0]
])
exit(1)
As long as you always want to put a constant value in there, you can treat your tetramino as a mask and use the np.putmask function:
>>> board = np.array([[6,0,0,0,0,0,0,0,0],[6,0,0,0,0,0,0,0,0]])
>>> board
array([[6, 0, 0, 0, 0, 0, 0, 0, 0],
[6, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> tetraminos = [[0,1,0],[1,1,1]]
>>> np.putmask(board[0:len(tetraminos),0:len(tetraminos[0])], tetraminos,1)
>>> board
array([[6, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0]])
You might do it in two steps:
tetraminos = np.array([0, 1, 0], [1, 1, 1])
temp = board[0:0 + len(tetraminos), 0:0 + len(tetraminos[0])]
board[0:0 + tetraminos.shape[0], 0:0 + tetraminos.shape[1]] = np.where(tetraminos == 0, temp, tetraminos)
Output:
array([[6, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0]])
A variant on the putmask
In [243]: board = np.array([
...: [6,0,0,0,0,0,0,0,0,0],
...: [6,0,0,0,0,0,0,0,0,0]
...: ])
In [244]: tetraminos = np.array([[0, 1, 0],
...: [1, 1, 1]])
In [245]: aview = board[:tetraminos.shape[0],:tetraminos.shape[1]]
Use the tetraminos as boolean to selection slots of aview to put values:
In [246]: aview[tetraminos.astype(bool)]=1
In [247]: board
Out[247]:
array([[6, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0]])
This could be generalized if tetraminos has other non-zero values.
matrix = np.array([[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]])
vector = np.array([0,0,0,0])
For vectors, you can edit every other element like so
vector[1::2] = 1
This gives
np.array([0,1,0,1])
However;
matrix[1::2] = 1
yields
np.array([[0,0,0,0],[1,1,1,1],[0,0,0,0],[1,1,1,1]])
I would like the output
np.array([[0,1,0,1],[0,1,0,1],[0,1,0,1],[0,1,0,1]])
There is a brute force approach to take the shape of the array, flatten it, use [1::2], and reshape, but i'm sure there is a more elegant solution i am missing.
Any help would be appreciated.
You can do something similar with multidimensional indexing
>>> matrix
array([[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]])
>>> matrix[:,1::2] = 1
>>> matrix
array([[0, 1, 0, 1],
[0, 1, 0, 1],
[0, 1, 0, 1],
[0, 1, 0, 1]])
In what I am working on, I have two numpy matrices, both the same size, filled with 0's and 1's for simplicity (but let's say it could be filled with any numbers). What I would like to know is a way to extract, from these two matrices, the position of the 1's that exist in the same position in both matrices.
For example, if I have the following two matrices and value
a = np.array([[0, 0, 0, 1, 0, 1],
[1, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 0, 1],
[1, 0 ,1, 1, 1, 0],
[0, 0, 1, 0, 0, 0]])
b = np.array([[0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 0]])
value = 1
then I would like a way to somehow get the information of all the locations where the value "1" exists in both matrices, i.e.:
result = [(0,5),(1,1),(2,3),(4,2)]
I guess the result could be thought of as an intersection, but in my case the position is important which is the reason I don't think np.intersect1d() would be much help. In the actual matrices I am working with, they are on the order of about 10,000 by 10,000, so this list would probably be a lot longer.
Thanks in advance for any help!
You could use numpy.argwhere:
import numpy as np
a = np.array([[0, 0, 0, 1, 0, 1],
[1, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 0, 1],
[1, 0, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 0]])
b = np.array([[0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 0]])
result = np.argwhere(a & b)
print(result)
Output
[[0 5]
[1 1]
[2 3]
[2 5]
[4 2]]
I want to cluster non-zero locations in a NumPy 2D array for MSER detection. Then I want to find the number of points in each cluster and remove those clusters which do not have number of points between some x and y (10 and 300).
I have tried clustering them by searching with neighbouring points but the method fails for concave-shaped non-zero clusters.
[[0, 1, 0, 0, 1],
[0, 1, 1, 1, 1],
[0, 0, 0, 0, 0],
[1, 1, 0, 1, 1],
[1, 0, 0, 1, 1]]
should output, for x=4 and y=5 (both included)
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 1, 1],
[0, 0, 0, 1, 1]]
I'm not sure I have understood your question correctly, but I think scikit-image's label and regionprops could get the job done.
In [6]: import numpy as np
In [7]: from skimage import measure, regionprops
In [8]: img = np.array([[0, 7, 0, 0, 7],
...: [0, 9, 1, 1, 4],
...: [0, 0, 0, 0, 0],
...: [2, 1, 0, 2, 1],
...: [1, 0, 0, 6, 4]])
...:
In [9]: arr = measure.label(img > 0)
In [10]: arr
Out[10]:
array([[0, 1, 0, 0, 1],
[0, 1, 1, 1, 1],
[0, 0, 0, 0, 0],
[2, 2, 0, 3, 3],
[2, 0, 0, 3, 3]])
In [11]: print('Label\t# pixels')
...: for region in measure.regionprops(arr):
...: print(f"{region['label']}\t{region['area']}")
...:
Label # pixels
1 6
2 3
3 4