I have a array of [2 2 3 4 4 5 6 6 6], and want to delete all minimum values from it.
The output should be [3 4 4 5 6 6 6].
I tried like following code, but it deleted a single 2, and left [2 3 4 4 5 6 6 6].
import numpy as np
a = np.array([2,2,3,4,4,5,6,6,6])
b= np.delete(a, a.argmin())
Python has a built-in function for finding min
val = min(values)
b =[v for v in values if v != val]
Use Boolean or “mask” index arrays
Numpy: Indexing
min() or not to a.min() depends on the array size.
For small arrays, use python built-in min
For large arrays, use numpy min
Test the timing for your particular usage.
b = a[a > min(a)]
[b]:
array([3, 4, 4, 5, 6, 6, 6])
The size of numpy arrays is immutable but you can create a copy of this array using this simple oneliner:
arr = np.array([2, 2, 3, 4, 4, 5, 6, 6, 6])
arr[arr!=np.min(arr)]
Output:
array([3, 4, 4, 5, 6, 6, 6])
You can get the indices that are greater than minimum value and slice the array as in this answer.
out = a[a>a.min()]
Notice this is faster than using np.delete as explained in the linked answer.
Related
When using matrix in numpy, I want to change the value of one element in a matrix using the index, but the result I got is strange.
How can I change one value in indexing method?
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
mat1 = np.mat(arr)
mat1[1][0] = 3
print(arr)
[[1 2 3 4]
[3 3 3 3]]
Do the following change:
mat1[1][0] = 3 -> mat1[1,0] = 3
Let's say I have four different vectors from a measurement, where each index corresponds to a certain time. Meaning that the values "1, 4, 7, 10" or also "2, 5, 8, 11" of the following example belong together. I now want to create a matrix, which allows to be accessed by time index. With time index I mean 0, 1 or 2 in the following example. I hope the following examples makes it a bit clearer.
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.array([7, 8, 9])
d = np.array([10, 11, 12])
mat = np.array([[a, b],
[c, d]])
mat[0] then returns
[[1 2 3]
[4 5 6]]
but I want that it returns is
[[1 4]
[7 10]]
How can I achieve this?
Since mat is a 3-dim array (and not a matrix), you should use:
print(mat[:,:,0])
This question already has answers here:
Replace all elements of Python NumPy Array that are greater than some value
(8 answers)
Closed 9 months ago.
I have numpy array with random numbers. For example like this
[7 1 2 0 2 3 4 0 5]
and I want to replace every number at the same time if number from this array = 7, I want to replace it with 2 , also if number = 2, replace it with 3. So it will be like [2 1 3 0 3 3 4 0 5] . I have tried it with np.where but can't change any of them.
It's better to use np.select if you've multiple conditions:
a = np.array([7, 1, 2, 0, 2, 3, 4, 0, 5])
a = np.select([a == 7, a == 2], [2, 3], a)
OUTPUT:
[2 1 3 0 3 3 4 0 5]
Numpy provide the comparison to a scalar with the standard == operator, such that arr == v return a boolean array. Taking arr[arr == v] takes the subset (or slice) of arr where the condition is met so this snippet should work.
import numpy as np
arr = np.array([7, 1, 2, 0, 2, 3, 4, 0, 5])
arr[arr == 7] = 2
arr
array([2, 1, 2, 0, 2, 3, 4, 0, 5])
I have two arrays:
import numpy as np
a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b = np.array([8,2,5,0])
I would like to replace the elements of a with -3 if the same elements appear in b. I would like to do this with a for loop with/without an if condition. Here's what I have:
for i in range(len(a)):
if a[i] == b[i]:
a[i] == -3
print(a)
And I get this error:
IndexError Traceback (most recent call last)
<ipython-input-19-5f8874f38b74> in <module>()
7
8 for i in range(len(a)):
----> 9 if a[i] == b[i]:
10 a[i] == -3
11
IndexError: index 4 is out of bounds for axis 0 with size 4
From my understanding it's a size discrepancy. Is there a way to solve my issue with arrays of different sizes?
Others have pointed out that the real issue is that you can't check membership by looping over both arrays at the same time. Using Python's in operator is a good alternative.
However, if we're in Numpy, we can use the Numpy element-wise version of the same thing:
a[np.isin(a, b)] = -3
np.isin(a,b) returns a boolean ndarray indicating whether each element of a was in b, which we can use to index a and only set the values that were in b to -3.
You are using the indices from a to access elements from b, which is much shorter. You quickly overshoot the length of b and encounter an error. Recommend you try the following:
import numpy as np
a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b = np.array([8,2,5,0])
for i,v in enumerate(a):
if v in b:
a[i] = -3
print(a)
Out:
[-3 1 -3 3 4 -3 6 7 -3 9]
Explaining this behavior in depth might take a bit more space than I want to fill here but there's a pretty good tutorial here that can help you wrap your head around using listss in Python.
The following will work for a python list. This is not a numpy based solution
a=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b=[8,2,5,0]
common=set(a).intersection(b) # {8, 0, 2, 5}
for i in range(len(a)):
if a[i] in common:
a[i]=-3
print(a) # [-3, 1, -3, 3, 4, -3, 6, 7, -3, 9]
I want to get the top N (maximal) args & values across an entire numpy matrix, as opposed to across a single dimension (rows / columns).
Example input (with N=3):
import numpy as np
mat = np.matrix([[9,8, 1, 2], [3, 7, 2, 5], [0, 3, 6, 2], [0, 2, 1, 5]])
print(mat)
[[9 8 1 2]
[3 7 2 5]
[0 3 6 2]
[0 2 1 5]]
Desired output: [9, 8, 7]
Since max isn't transitive across a single dimension, going by rows or columns doesn't work.
# by rows, no 8
np.squeeze(np.asarray(mat.max(1).reshape(-1)))[:3]
array([9, 7, 6])
# by cols, no 7
np.squeeze(np.asarray(mat.max(0)))[:3]
array([9, 8, 6])
I have code that works, but looks really clunky to me.
# reshape into single vector
mat_as_vector = np.squeeze(np.asarray(mat.reshape(-1)))
# get top 3 arg positions
top3_args = mat_as_vector.argsort()[::-1][:3]
# subset the reshaped matrix
top3_vals = mat_as_vector[top3_args]
print(top3_vals)
array([9, 8, 7])
Would appreciate any shorter way / more efficient way / magic numpy function to do this!
Using numpy.partition() is significantly faster than performing full sort for this purpose:
np.partition(np.asarray(mat), mat.size - N, axis=None)[-N:]
assuming N<=mat.size.
If you need the final result also be sorted (besides being top N), then you need to sort previous result (but presumably you will be sorting a smaller array than the original one):
np.sort(np.partition(np.asarray(mat), mat.size - N, axis=None)[-N:])
If you need the result sorted from largest to lowest, post-pend [::-1] to the previous command:
np.sort(np.partition(np.asarray(mat), mat.size - N, axis=None)[-N:])[::-1]
One way may be with flatten and sorted and slice top n values:
sorted(mat.flatten().tolist()[0], reverse=True)[:3]
Result:
[9, 8, 7]
The idea is from this answer: How to get indices of N maximum values in a numpy array?
import numpy as np
import heapq
mat = np.matrix([[9,8, 1, 2], [3, 7, 2, 5], [0, 3, 6, 2], [0, 2, 1, 5]])
ind = heapq.nlargest(3, range(mat.size), mat.take)
print(mat.take(ind).tolist()[0])
Output
[9, 8, 7]