This question is about replacing entire arrays if they fulfil conditions. It is not about replacing individual values in an ndarray - as in this and this question for example.
Problem
I have an input array inarray
. As an example:
import numpy as np
inarray = \
np.array([[[1,1,1,1],
[2,2,2,2]],
[[3,3,3,3],
[4,4,4,4]]])
I would like to replace the rows containing [1,1,1,1]
by [9,9,9,9]
.
I suspect there is a more efficient way of doing this than my method below. What is it?
My attempt
I do:
inarray[np.equal(inarray,np.array([1,1,1,1])).all(axis=2)]=np.array([9,9,9,9])
This line changes inarray
to be:
array([[[9, 9, 9, 9],
[2, 2, 2, 2]],
[[3, 3, 3, 3],
[4, 4, 4, 4]]])
as expected.
Problem with other methods
One suggested way by this answer is to use:
inarray[inarray == [1,1,1,1]] = [9,9,9,9]
The problem with this is that when [1,1,1,1]
appears multiple times, this fails:
inarray = \
np.array([[[1,1,1,1],
[2,2,2,2]],
[[1,1,1,1],
[4,4,4,4]]])
inarray[inarray == [1,1,1,1]] = [9,9,9,9]
Output:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [81], in <cell line: 1>()
----> 1 inarray[inarray == [1,1,1,1]] = [9,9,9,9]
ValueError: NumPy boolean array indexing assignment cannot assign 4 input values to the 8 output values where the mask is true
Expected result is inarray
having been changed to:
array([[[9, 9, 9, 9],
[2, 2, 2, 2]],
[[9, 9, 9, 9],
[4, 4, 4, 4]]])
CodePudding user response:
If I understand your question correctly, this should work
inarray[inarray == [1,1,1,1]] = [9,9,9,9]
It basically matches where inarray equals [1,1,1,1]
and makes it [9,9,9,9]
Edit
Well you can then modify slightly your code to this
inarray[(inarray==np.array([1,1,1,1])).all(axis=2)]=[9,9,9,9]
But it really does not make a big difference