How to work with numpy.where? [duplicate] - python

This question already has an answer here:
Matching an array to a row in Numpy
(1 answer)
Closed 5 years ago.
I want to find indexes of array like x = np.array([[1, 1, 1], [2, 2, 2]]) where elements equals to y = np.array([1, 1, 1]). So I did this:
In: np.where(x == y)
Out: (array([0, 0, 0]), array([0, 1, 2]))
It is the correct answer. But I expect to get only index 0 because the zero element of x is equal to y.

You need to use (x == y).all(axis=1) to reduce the comparison result over axis=1 first, i.e all elements are equal:
np.where((x == y).all(axis=1))[0]
# array([0])

Related

finding the minimum value in an array with returned values [duplicate]

This question already has answers here:
How to return all the minimum indices in numpy
(5 answers)
Closed 1 year ago.
I have an array for example:
[1 2 3 4
2 3 4 0
5 4 0 6]
And I want to find the indexes of all the values that are closer to to the value 3.9 (in my example,4)
I tried using :
import numpy as np
def find_nearest(array, value):
idx = (np.abs(array - value)).argmin()
and
np.where(array== array.min())
but none of the options gives me the correct answer.
I do excpect to get:
(3,1),(1,2),(2,1)
In my original code, I iterate an array with the shape of 3648X5472 so "FOR" loops might be too heavy.
hope to get some help here, thank you
You can use:
a = np.array([[1, 2, 3, 4],
[2, 3, 4, 0],
[5, 4, 0, 6]])
v = 3.9
b = abs(a-v)
xs, ys = np.where(b == np.min(b))
output:
>>> xs
array([0, 1, 2])
>>> ys
array([3, 2, 1])
Alternative output:
>>> np.c_[np.where(b == np.min(b))]
array([[0, 3],
[1, 2],
[2, 1]])
# or
>>> np.argwhere(b==np.min(b))
You are pretty close. When you found the index of the first closest value, you can find indices of the equal values with `np.argwhere:
closest = array[np.abs(array - value).argmin()]
np.argwhere(array == closest)

Test existence of subarray in ndarrray [duplicate]

This question already has answers here:
testing whether a Numpy array contains a given row
(5 answers)
Closed 1 year ago.
For a numpy array of shape (n, 2), n points with 2 coordinates, what is the best way (fastest for large n) to test if a particular point is already in the array. E.g.
test_point = np.array([1, 2])
array_A = array([[1, 3], [2, 2], [2, 1]]) # test on this should return False
array_B = array([[1, 2], [2, 2], [2, 1]]) # test on this should return True
(array_A == test_point).all(axis=1).any()
Explanation:
array_A == test_point applies broadcasting rules and returns array of booleans with shape equal to array_A.
.all(axis=1) returns True for rows if all values are True
.any() returns True if any value in column is True
Kindly verify if this is what you were anticipating:
import numpy as np
test = np.array([1,2])
sample = np.array([[1, 2], [2, 2]])
result = any([all(sample[i,:] == test) for i in range(sample.shape[0])])

argsort get order of each element [duplicate]

This question already has answers here:
Rank items in an array using Python/NumPy, without sorting array twice
(11 answers)
Closed 3 years ago.
I have an array and I want to get the order of each element.
a=[1.83976,1.57624,1.00528,1.55184]
np.argsort(a)
the above code return
array([2, 3, 1, 0], dtype=int64)
but I want to get the array of the order of each element.
e.g.
[0, 1, 3, 2]
means a[0] is largest number (0th)
a[1] is 1th
a[2] is 3rd
a[3] is 2nd
Ill explain,np.argsort(np.argsort(a)) gives the element in there order like 1.83976 is the highest value in the array so it is assigned the highest value 3. I just subtracted the value from len(a)-1 to get your output.
>>> import numpy as np
>>> a=[1.83976,1.57624,1.00528,1.55184]
>>> np.argsort(a)
array([2, 3, 1, 0])
>>> np.argsort(np.argsort(a))
array([3, 2, 0, 1])
>>> [len(a)-i for i in np.argsort(np.argsort(a))]
[1, 2, 4, 3]
>>> [len(a)-1-i for i in np.argsort(np.argsort(a))]
[0, 1, 3, 2]
>>> np.array([len(a)-1]*len(a))-np.argsort(np.argsort(a))
array([0, 1, 3, 2])
By default argsort returnes indexes of sorted elements in ascending order. As you need descending order, argsort(-a) will give you right sorted indexes. To get the rank of elements you need to apply argsort again.
a = np.array([1.83976,1.57624,1.00528,1.55184])
indx_sorted = np.argsort(-a)
np.argsort(indx_sorted)
>>> array([0, 1, 3, 2])

numpy: find index in sorted array (in an efficient way) [duplicate]

This question already has answers here:
Transform a set of numbers in numpy so that each number gets converted into a number of other numbers which are less than it
(4 answers)
Closed 4 years ago.
I would like to sort a numpy array and find out where each element went.
numpy.argsort will tell me for each index in the sorted array, which index in the unsorted array goes there. I'm looking for something like the inverse: For each index in the unsorted array, where does it go in the sorted array.
a = np.array([1, 4, 2, 3])
# a sorted is [1,2,3,4]
# the 1 goes to index 0
# the 4 goes to index 3
# the 2 goes to index 1
# the 3 goes to index 2
# desired output
[0, 3, 1, 2]
# for comparison, argsort output
[0, 2, 3, 1]
A simple solution uses numpy.searchsorted
np.searchsorted(np.sort(a), a)
# produces [0, 3, 1, 2]
I'm unhappy with this solution, because it seems very inefficient. It sorts and searches in two separate steps.
This fancy indexing fails for arrays with duplicates, look at:
a = np.array([1, 4, 2, 3, 5])
print(np.argsort(a)[np.argsort(a)])
print(np.searchsorted(np.sort(a),a))
a = np.array([1, 4, 2, 3, 5, 2])
print(np.argsort(a)[np.argsort(a)])
print(np.searchsorted(np.sort(a),a))
You can just use argsort twice on the list.
At first the fact that this works seems a bit confusing, but if you think about it for a while it starts to make sense.
a = np.array([1, 4, 2, 3])
argSorted = np.argsort(a) # [0, 2, 3, 1]
invArgSorted = np.argsort(argSorted) # [0, 3, 1, 2]
You just need to invert the permutation that sorts the array. As shown in the linked question, you can do that like this:
import numpy as np
def sorted_position(array):
a = np.argsort(array)
a[a.copy()] = np.arange(len(a))
return a
print(sorted_position([0.1, 0.2, 0.0, 0.5, 0.8, 0.4, 0.7, 0.3, 0.9, 0.6]))
# [1 2 0 5 8 4 7 3 9 6]

Convert discontinuous numpy array to continuous array Python [duplicate]

This question already has answers here:
numpy replace groups of elements with integers incrementally
(2 answers)
Closed 4 years ago.
Hi I have a numpy array like
a = np.array([1,1,1,3,3,6,6,6,6,6,6])
I want to convert it to a continuous array like below
b = np.array([0,0,0,1,1,2,2,2,2,2,2])
I have a code for this using for loop
def fun1(a):
b = a.copy()
for i in range(1,a.shape[0]):
if a[i] != a[i-1]:
b[i] = b[i-1]+1
else:
b[i] = b[i-1]
b = b - b.min()
return b
Is there a way to vectorize this using numpy? I can use numba to make it faster but I was wondering if there is way to do it with just numpy.
You can do the following with np.unique, using the return_inverse argument. According to the docs:
return_inverse : bool, optional
If True, also return the indices of the unique array (for the specified axis, if provided) that can be used to reconstruct ar.
a = np.array([1,1,1,3,3,6,6,6,6,6,6])
_, b = np.unique(a, return_inverse=True)
>>> b
array([0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2])
Edit If the list starts out unsorted, and you want such a continuous array as displayed in your output, you can do the same as above, but passing a sorted array to np.unique:
a = np.array([1,3,1,3,3,6,6,3,6,6,6])
_, b = np.unique(sorted(a), return_inverse=True)
>>> b
array([0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2])

Categories

Resources