Index of an element in a numpy array - python

Given a matrix like the following:
A = np.array([[1,2,3],
[3,4,5],
[4,5,6]])
How can I pinpoint the index of an element of interest. For example, assume I would like to find the index of 2 in the first row of the np.array, like so:
A[0,:].index(2), but clearly this does not work because A[0,:] is not a list.

You can compare the array to the value 2, and then use where.
For example, to find the location of 2 in the first row of A:
In [179]: np.where(A[0, :] == 2)[0]
Out[179]: array([1])
In [180]: j = np.where(A[0, :] == 2)[0]
In [181]: A[0, j]
Out[181]: array([2])
where also works with higher-dimensional arrays. For example, to find 2 in the full array A:
In [182]: i, j = np.where(A == 2)
In [183]: A[i,j]
Out[183]: array([2])

Related

Remove duplicate index in 2D array

I have this 2D numpy array here:
arr = np.array([[1,2],
[2,2],
[3,2],
[4,2],
[5,3]])
I would like to delete all duplicates corresponding to the previous index at index 1 and get an output like so:
np.array([[1,2],
[5,3]])
However, when I try my code it errors.
Here is my code:
for x in range(0, len(arr)):
if arr[x][1] == arr[x-1][1]:
arr = np.delete(arr, x, 0)
>>> IndexError: index 3 is out of bounds for axis 0 with size 2
Rather than trying to delete from the array, you can use np.unique to find the indices of first occurrences of the unique values in the second columns and use that to pull those values out:
import numpy as np
arr = np.array([[1,2],
[2,2],
[3,2],
[4,2],
[5,3]])
u, i = np.unique(arr[:,1], return_index=True)
arr[i]
# array([[1, 2],
# [5, 3]])

How to find list rows and columns index in Python

I am trying to print row and column index in list.
I've used (loop below) this but Its one or the other..
a = [[0,0,1],
[0,1,0],
[1,0,0]]
def a():
x = 0
for sol in solutions:
print(sol)
for row in sol:
print(row)
I am trying to print
(0,2) (1,1) (2,0)
Index of 1s
Thank You
You can use enumerate to generate indices for a list:
for row, sublist in enumerate(a):
for column, item in enumerate(sublist):
if item:
print((row, column))
This outputs:
(0, 2)
(1, 1)
(2, 0)
If you like numpy you can turn it into a numpy array and use argwhere()
import numpy as np
a = [[0,0,1],
[0,1,0],
[1,0,0]]
a = np.array(a)
answer = np.argwhere(a==1)
This will output:
[[0 2]
[1 1]
[2 0]]

How to group values in matrix with items of unequal length

Lets say I have a simple array:
a = np.arange(3)
And an array of indices with the same length:
I = np.array([0, 0, 1])
I now want to group the values based on the indices.
How would I group the elements of the first array to produce the result below?
np.array([[0, 1], [2], dtype=object)
Here is what I tried:
a = np.arange(3)
I = np.array([0, 0, 1])
out = np.empty(2, dtype=object)
out.fill([])
aslists = np.vectorize(lambda x: [x], otypes=['object'])
out[I] += aslists(a)
However, this approach does not concatenate the lists, but only maintains the last value for each index:
array([[1], [2]], dtype=object)
Or, for a 2-dimensional case:
a = np.random.rand(100)
I = (np.random.random(100) * 5 //1).astype(int)
J = (np.random.random(100) * 5 //1).astype(int)
out = np.empty((5, 5), dtype=object)
out.fill([])
How can I append the items from a to out based on the two index arrays?
1D Case
Assuming I being sorted, for a list of arrays as output -
idx = np.unique(I, return_index=True)[1]
out = np.split(a,idx)[1:]
Another with slicing to get idx for splitting a -
out = np.split(a, np.flatnonzero(I[1:] != I[:-1])+1)
To get an array of lists as output -
np.array([i.tolist() for i in out])
Sample run -
In [84]: a = np.arange(3)
In [85]: I = np.array([0, 0, 1])
In [86]: out = np.split(a, np.flatnonzero(I[1:] != I[:-1])+1)
In [87]: out
Out[87]: [array([0, 1]), array([2])]
In [88]: np.array([i.tolist() for i in out])
Out[88]: array([[0, 1], [2]], dtype=object)
2D Case
For 2D case of filling into a 2D array with groupings made from indices in two arrays I and J that represent the rows and columns where the groups are to be assigned, we could do something like this -
ncols = 5
lidx = I*ncols+J
sidx = lidx.argsort() # Use kind='mergesort' to keep order
lidx_sorted = lidx[sidx]
unq_idx, split_idx = np.unique(lidx_sorted, return_index=True)
out.flat[unq_idx] = np.split(a[sidx], split_idx)[1:]

cut some rows and columns where values are 255

I am trying to get rid of all rows and columns in a grayscale numpy array where the values are 255.
My array could be:
arr = [[255,255,255,255],
[255,0,0,255],
[255,255,255,255]]
The result should be:
arr = [0,0]
I can just interating over the array, but there should be a pythonic way to solve the problem.
For the rows i tried:
arr = arr[~(arr==255).all(1)]
This works really well, but i cannot find an equal solution for colums.
Given boolean arrays for rows and columns:
In [26]: rows
Out[26]: array([False, True, False], dtype=bool)
In [27]: cols
Out[27]: array([False, True, True, False], dtype=bool)
np.ix_ creates ordinal indexers which can be used to index arr:
In [32]: np.ix_(rows, cols)
Out[32]: (array([[1]]), array([[1, 2]]))
In [33]: arr[np.ix_(rows, cols)]
Out[33]: array([[0, 0]])
Therefore you could use
import numpy as np
arr = np.array([[255,255,255,255],
[255,0,0,255],
[255,255,255,255]])
mask = (arr != 255)
rows = mask.all(axis=1)
cols = mask.all(axis=0)
print(arr[np.ix_(rows, cols)])
which yields the 2D array
[[0 0]]
For the columns, you can simply transpose the array:
arr = arr.T[~(arr.T==255).all(1)].T
arr = arr[~(arr==255).all(1)]
which results in
>> print(arr)
[[0 0]]

Python comparing two 3 dimensional numpy arrays

I have two numpy arrays:
A.shape = (nA,x,y)
and
B.shape = (nB,x,y).
I want to find all subarrays such that
A(i,:,:) == B(j,:,:).
I know I can write a double for loop and use
np.array_equal(A(i,:,:),B(j,:,:)
However, is there a more efficient method?
You should only need to loop through one of the arrays, since you wouldn't find any additional unique subarrays after that, and you can do this with a simple list comprehension.
subarrays = [x for x in A if x in B]
If you only want the indices instead of storing the whole subarray, you can do:
indices = [x[0] for x in enumerate(A) if x[1] in B]
Utilizing Steven Rouk's solution, here is a method to get the indices for the subarrays that are equal:
indicesForMatches = [(i,j) for i,subArrayOfA in enumerate(A) for j,subArrayOfB in enumerate(B) if np.array_equal(subArrayOfA,subArrayOfB)]
You can use NumPy broadcasting for a vectorized solution, like so -
mask = ((A[:,None,:,:] == B).all(2)).all(2)
A_idx,B_idx = np.where(mask)
You can use reshaping to avoid double .all() usages and get the mask, like so -
mask = (A.reshape(A.shape[0],1,-1) == B.reshape(B.shape[0],-1)).all(-1)
Sample run -
In [41]: # Setup input arrays and force some indices to be same between A and B
...: nA = 4
...: nB = 5
...: x = 3
...: y = 2
...:
...: A = np.random.randint(0,9,(nA,x,y))
...: B = np.random.randint(0,9,(nB,x,y))
...:
...: A[2,:,:] = B[1,:,:]
...: A[3,:,:] = B[4,:,:]
...:
In [42]: mask = ((A[:,None,:,:] == B).all(2)).all(2)
...: A_idx,B_idx = np.where(mask)
...:
In [43]: A_idx, B_idx
Out[43]: (array([2, 3]), array([1, 4]))
In [44]: mask = (A.reshape(A.shape[0],1,-1) == B.reshape(B.shape[0],-1)).all(-1)
...: A_idx,B_idx = np.where(mask)
...:
In [45]: A_idx, B_idx
Out[45]: (array([2, 3]), array([1, 4]))

Categories