I have a 2d numpy array as : arr= np.array([[2,5,10],[6,2,9]]). Now I want to convert this into 3d numpy array as I will place same number of 1's towards z-axis or the 3rd dimension, at that place replacing the element. For example, in place of 2, we will place two 1's and all other elements will be zero. So I place of two 1 and eight 0, since the matrix will be of size 2*3*10.
Is it possible? If yes, How can we achieve this?
you can try something like this :
arr3d= np.zeros((arr.shape[0] , arr.shape[1], max(map(max, arr))))
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
print(i,j,arr[i][j])
for k in range(arr[i][j]):
arr3d[i,j,k]=1
I know 3 loops :\
edited after suggestions from #hpaulj
This may be what you're asking...
Use numpy.reshape. This takes the array and reshapes it like so:
array = numpy.array([[1,4,1], [3, 1, 4]])
numpy.reshape(array, (array.shape[0], array.shape[1], 1).
array is now numpy.array([[[1,4,1], [3, 1, 4]]])
The 1 at the end is basically adding an extra dimension to the array. Shape just means the length of an X-Y-Z-whatever dimensional thing...
See the numpy docs for reshape at https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html.
Hope I helped!
Use broadcasting like so:
>>> x = np.array([[2,5,10],[6,2,9]])
>>>
>>> (x[..., None] > np.arange(10)).view('i1')
array([[[1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],
[[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0]]], dtype=int8)
Related
I'm new with numpy, trying to understand how to search for 2d array in another 2d array. I don't need indexes, just True/False
For example I've an array with shape 10x10, all ones and somewhere it has 2x2 zeroes:
ar = np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 0, 1, 1, 0, 1, 1, 0, 1],
[1, 1, 0, 1, 1, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
[1, 1, 0, 1, 1, 0, 1, 1, 1, 2],
[1, 1, 0, 1, 1, 0, 1, 1, 1, 1]]
)
and I have another array I want to find
ar2 = np.zeros((2,2))
I tried functions like isin and where, but they all search for any elements, not for entire shape of array.
Here's what I've come to - iterate over rows and cols, slice 2x2 array and compare it with zeroes array:
for r, c in np.ndindex(ar.shape):
if r-1>=0 and c-1>=0 and np.array_equal(ar[r - 1:r + 1, c - 1:c + 1], ar2):
print(f'found it {r}:{c}')
I'm not sure if this is the best solution, but at least it works. Maybe there is some easier and faster way to search for 2x2 zeroes?
I think using scikit image library can be one of the best ways to do so:
from skimage.util import view_as_windows
view_ = view_as_windows(ar, (2, 2))
res_temp = np.all((view_ == ar2[None, ...]), (-2, -1))
result = np.nonzero(res_temp)
# (array([4], dtype=int64), array([4], dtype=int64))
This will get indices. For same result as your code, indices must be added by one.
Based on this answer by Brenlla, I made this function which works with 2d arrays:
def find_array_in_array_2d(ar, ar2):
# Find all matches with first element of ar2
match_idx = np.nonzero(ar[:-ar2.shape[0]+1, :-ar2.shape[1]+1] == ar2[0, 0])
# Check remaining indices of ar2
for i, j in list(np.ndindex(ar2.shape))[1:]:
# End if no possible matches left
if len(match_idx[0]) == 0:
break
# Index into ar offset by i, j
nz2 = (match_idx[0] + i, match_idx[1] + j)
# Find remaining matches with selected element
to_keep = np.nonzero(ar[nz2] == ar2[i, j])[0]
match_idx = match_idx[0][to_keep], match_idx[1][to_keep]
return match_idx
print(find_array_in_array_2d(ar, ar2))
(array([4]), array([4]))
I think it will be faster than your method if ar is big and ar2 is small and especially when ar does not contain many values which are also in ar2.
I have a matrix
test = np.array([[0,1,0,0],[1,0,1,1],[0,1,0,1],[0,1,1,0]])
How do I reorder the columns so that they are like this matrix? (Basically the last row becomes the first row in reverse order and so on...)
np.array([[0,1,1,0],[1,0,1,0],[1,1,0,1],[0,0,1,0]])
Just reverse both axis
test[::-1,::-1]
array([[0, 1, 1, 0],
[1, 0, 1, 0],
[1, 1, 0, 1],
[0, 0, 1, 0]])
Update (ahh... Okay, I think I understand now.)
You can use negative steps for both the inner and outer steps.
test[::-1, ::-1]
Output:
array([[0, 1, 1, 0],
[1, 0, 1, 0],
[1, 1, 0, 1],
[0, 0, 1, 0]])
To reverse both the row and column you can use the np.flip, in your case:
test = np.array([[0,1,0,0],[1,0,1,1],[0,1,0,1],[0,1,1,0]])
reversed = np.flip(test, axis=[0,1])
I have a numpy array with binary values that I need to change in the following way: The value of every element must be shifted one column to the left but only within the same row. As an example, I have the following array:
>>> arr = np.array([[0,0,1,0],[1,0,0,0],[0,0,1,1]])
>>> arr
array([[0, 0, 1, 0],
[1, 0, 0, 0],
[0, 0, 1, 1]])
And it needs to be transformed to:
>>> arr
array([[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 1, 1, 0]])
I know that np.roll(arr,-1) would roll the values one cell to the left, but it doesn't seem to be able to roll them within the rows they belong to (i.e. the element on cell [1,0] goes to [0,3] instead of the desired [1,3]. Is there a way of doing this?
Thanks in advance.
roll accepts an axis parameter:
np.roll(arr,-1, axis=1)
array([[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 1, 1, 0]])
I have two arrays, one array that contains all indices of two arrays that meet a certain condition I had made previous to this. The other array is an array of booleans. I want to take the array of indices and find the same place in the array of booleans and replace those values.
So for example what I am looking to do is:
myIdxs = [0, 3, 5]
myBools = [1, 0, 0, 1, 1, 1, 0, 1, 0, 1]
and change myBools to:
myBools = [0, 0, 0, 0, 1, 0, 0, 1, 0, 1]
I've tried:
myBools = [myBools[i] for i in myIdx == 0]
But this does not give me the desired output.
I hope this works (not sure what you need):
myIdxs = [0, 3, 5]
myBools = [1, 1, 1, 1, 1, 0]
myBools = [myBools[i] if i in myIdxs else 0
for i in xrange(len(myBools))]
>>> print myBools
[1, 0, 0, 1, 0, 0]
Poorly worded question, but here are two answers, both are extremely simple and straightforward, and don't required complex list comprehension.
If you want to change the bit to the opposite value
myIdxs = [0, 3, 5]
myBools = [1, 0, 0, 1, 1, 1, 0, 1, 0, 1]
for i in myIdxs:
myBools[i] ^= 1 # Bitwise operator flips the bit
print(myBools)
If you want to change the bit to zero.
myIdxs = [0, 3, 5]
myBools = [1, 0, 0, 1, 1, 1, 0, 1, 0, 1]
for i in myIdxs:
myBools[i] = 0 # Sets bit to zero
print(myBools)
Output
The output is actually the same for both, given the input, but don't let that fool you they do two very different things.
[0, 0, 0, 0, 1, 0, 0, 1, 0, 1]
[0, 0, 0, 0, 1, 0, 0, 1, 0, 1]
Try using list comprehension with if-else statement.
[myBools[i] if i in myIdxs else 0 for i in range(len(myBools))]
Output
[1, 0, 0, 1, 0, 0]
import numpy as np
def calc_size(matrix, index):
return np.nonzero(matrix[index,:])[1].size
def swap_rows(matrix, frm, to):
matrix[[frm, to],:] = matrix[[to, frm],:]
Numpy - Python 2.7
How can I achieve that matrix's rows are sorted after the size of the nonzero entries? I already wrote these two methods for doing the work but I need to give it to a sorting engine? The fullest rows should be at the beginning!
If you have an array arr:
array([[0, 0, 0, 0, 0],
[1, 0, 1, 1, 1],
[0, 1, 0, 1, 1],
[1, 1, 1, 1, 1]])
You could sort the array's rows according to the number of zero entries by writing:
>>> arr[(arr == 0).sum(axis=1).argsort()]
array([[1, 1, 1, 1, 1],
[1, 0, 1, 1, 1],
[0, 1, 0, 1, 1],
[0, 0, 0, 0, 0]])
This first counts the number of zero entries in each row with (arr == 0).sum(axis=1): this produces the array [5, 1, 2, 0].
Next, argsort sorts the indices of this array by their corresponding value, giving [3, 1, 2, 0].
Lastly, this argsorted array is used to rearrange the rows of arr.
P.S. If you have a matrix m (and not an array), you may need to ravel before using argsort:
m[(m == 0).sum(axis=1).ravel().argsort()]