I have the foll. code in numpy:
mask_cntr = np.copy(map_ccodes)
mask_cntr[mask_cntr == cntr] = 1.0
mask_cntr[mask_cntr != 1.0] = 0.0
Here, I am copying the 2D array map_ccodes to mask_cntr, and assigning the values that equal cntr in that array to 1.0, and all others to 0.0.
Is there a faster and more pythonic way to do this in numpy?
np.where function accepts conditions and returns an output based on the condition being True or False:
np.where(mask_cntr == cntr, 1.0, 0.0)
Try
mask_cntr = 1.0*(map_ccodes==cntr)
I am assuming that cntr == 1 from your code?
Why do you need a separate mask anyway? You can always use the map_ccodes==cntr argument anywhere ...
Related
import numpy as np
array = np.random.uniform(0.0, 1.0, (100, 2))
array[(array[:, 1:2] < 3.0).flatten()][:][1:2] = 4.0
I want to change the second value of the rows who is less than 3.0 to 4.0, but the above code does not work. I tried to search a little bit, it appears that fancy slicing always just operates on a copy of the original array. Is that true? How to do the correct assignment in this case?
Just use multi index (boolean index for the 1st dimension & integer index for 2nd dimension) to mutate in place:
array[array[:, 1] < 3, 1] = 4
array
# array([[2.59733369e-01, 4.00000000e+00],
# [5.08406931e-01, 4.00000000e+00],
# ...
I have this array:
a=array([[0. , 0.3, 0.2],
[0.5, 0. , 0.1]])
and this custom min method:
def custom_min(l_):
return min([x for x in l_ if x>0])
How do I apply that over the rows to select some of them? For example, if for a row custom_min > 0.1, that row should be selected: i.e.,
b = [[0. , 0.3, 0.2]]
To be clear, I am looking for methods like this:
a[a[:,1] > 0.1]
First, you can use numpy.apply_along_axis to apply custom_min to each row.
I'd also rewrite custom_min to be more numpythonic: return min(l_[l_ > 0]).
Now that you have that custom min in a vector, you can again use logical indexing:
row_mask = result > 0.3 and filtered_array = a[row_mask, :]
EDIT:
Thinking a bit more about how to make everything use only numpy vectorized functions. We can first use numpy.where to replace everything smaller than 0 with infinity. That takes it out of consideration for the minimum:
row_wise_custom_mins = np.min(np.where(a > 0, a, np.inf), axis=1)
The "where" picks values form a if the condition is true and picks np.inf if the condition is false. Then we pick the minimum (along axis 1) and that's it.
Suppose I have a 1D numpy array (A) containing 5 elements:
A = np.array([ -4.0, 5.0, -3.5, 5.4, -5.9])
I need to add 5 to all the elements of A that are lesser than zero. What is the numpy way to do this without for-looping ?
It can be done using mask:
A[A < 0] += 5
The way it works is - the expression A < 0 returns a boolean array. Each cell corresponds to the predicate applied on the matching cell. In the current example:
A < 0 # [ True False True False True]
And then, the action is applied only on the cells that match the predicate. So in this example, it works only on the True cells.
I found another answer:
A = np.where(A<0, A+5, A)
I need to know if all the elements of an array of numpy are equal to a number
It would be like:
numbers = np.zeros(5) # array[0,0,0,0,0]
print numbers.allEqual(0) # return True because all elements are 0
I can make an algorithm but, there is some method implemented in numpy library?
You can break that down into np.all(), which takes a boolean array and checks it's all True, and an equality comparison:
np.all(numbers == 0)
# or equivalently
(numbers == 0).all()
If you want to compare floats, use np.isclose instead:
np.all(np.isclose(numbers, numbers[0]))
np.array_equal() also works (for Python 3).
tmp0 = np.array([0]*5)
tmp1 = np.array([0]*5)
np.array_equal(tmp0, tmp1)
returns True
The following version checks the equality of all entries of the array without requiring the repeating number.
numbers_0 = np.zeros(5) # array[0,0,0,0,0]
numbers.ptp() == 0.0 # True
# checking an array having some random repeating entry
numbers_r = np.ones((10, 10))*np.random.rand()
numbers_r.ptp() == 0.0 # True
Are numpy methods necessary? If all the elements are equal to a number, then all the elements are the same. You could do the following, which takes advantage of short circuiting.
numbers[0] == 0 and len(set(numbers)) == 1
This way is faster than using np.all()
I have a numpy pixel array (either 0 or 255), using .where I pull the tuples of where it is > 0. I now want to use those tuples to add 1 to a separate 2D numpy array. Is the best way to just use a for loop as shown below or is there a better numpy-like way?
changedtuples = np.where(imageasarray > 0)
#If there's too much movement change nothing.
if frame_size[0]*frame_size[1]/2 < changedtuples[0].size:
print "No change- too much movement."
elif changedtuples[0].size == 0:
print "No movement detected."
else:
for x in xrange(changedtuples[0].size):
movearray[changedtuples[1][x],changedtuples[0][x]] = movearray[changedtuples[1][x],changedtuples[0][x]]+1
movearray[imageasarray.T > 0] += 1
where is redundant. You can index an array with a boolean mask, like that produced by imageasarray.T > 0, to select all array cells where the mask has a True. The += then adds 1 to all those cells. Finally, the T is a transpose, since it looks like you're switching the indices around when you increment the cells of movearray.