Question
Let's say I have the following array tile1
[[80 80 80]
[80 80 80]
[80 80 80]
[80 80 80]]
I want to replace every [80 80 80]
element with the array [1 5 10]
. How can I do that?
What I have tried
I tried
print(tile1==[80,80,80])
And I thought that was pretty useful but then I realized that is the same as
print(tile1==80)
So when I tried
tile1[tile1==[80,80,80]]=[1,5,10]
of course it failed. I could only assign values based on basic elements like tile1[tile1==[80,80,80]]=5
CodePudding user response:
Those aren't "entire elements", they are swaths of memory called rows. Numpy arrays are not like lists. Lists store references to nested elements. Numpy arrays are blocks of memory. Shapes and slices represent views with different strides, not multiple layers of indirection.
You can assign to slices using broadcasting. In this case, you need to specify an index that marks all rows containing the elements you want with a boolean and tell the index to fill all columns.
Your replacement array will correctly broadcast to the columns. However, let's look at the index.
tile1 == 80
This results in an array of the same shape as tile1
because of broadcasting. ==
does an elementwise comparison. So does this:
tile1 == [80, 80, 80]
So how do you get a boolean for each row instead of each element? You use np.all
along the appropriate axis:
np.all(tile1 == 80, axis=1)
Or as I like to phrase it using the method version:
(tile1 == 80).all(axis=1)
And that's about it. The resulting mask has as many elements as tile1
has rows, so you can use it directly as you did before:
tile1[(tile1 == 80).any(1)] = [1, 5, 10]
This works because when you leave out trailing indices, they are implicitly set to :
or ...
. This is a standard feature of basic indexing. You are assigning a 3-element sequence to an (n, 3)
-shaped index. n
is determined by the number of True
elements in the mask, and 3
is the shape of the remaining dimension of tile1
.
CodePudding user response:
This might work but will require some testing, I'm just checking if the values are the same across all columns. In this example its 80
arr = array([[80, 80, 80],
[80, 80, 80],
[80, 80, 80],
[80, 80, 80]])
arr[arr.all(1)] = [1, 5, 10]
array([[ 1, 5, 10],
[ 1, 5, 10],
[ 1, 5, 10],
[ 1, 5, 10]])