[英]Python numpy array integer indexed flat slice assignment
Was experimenting with numpy and found this strange behavior. 正在尝试numpy并发现这种奇怪的行为。 This code works ok:
该代码可以正常工作:
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> a[:, 1].flat[:] = np.array([-1, -1])
>>> a
array([[ 1, -1, 3],
[ 4, -1, 6]])
But why this code doesn't change to -1 elements of 0 and 2 column? 但是为什么这段代码不会更改为-1元素(0和2列)?
>>> a[:, [0, 2]].flat[:] = np.array([-1, -1])
>>> a
array([[ 1, -1, 3],
[ 4, -1, 6]])
And how to write the code so that would change to -1 elements of 0 and 2 columns like this? 以及如何编写代码,使其变成这样的0和2列的-1元素?
UPD: use of flat
or smt similar is necessarily in my example UPD:在我的示例中必须使用
flat
或smt类似
UPD2: I made example in question basing on this code: UPD2:我根据以下代码制作了有问题的示例:
img = imread(img_name)
xor_mask = np.zeros_like(img, dtype=np.bool)
# msg_bits looks like array([ True, False, False, ..., False, False, True], dtype=bool)
xor_mask[:, :, channel].flat[:len(msg_bits)] = np.ones_like(msg_bits, dtype=np.bool)
And after assignment to xor mask with channel == 0 or 1 or 2 code works ok, but if channel == [1,2] or smt like this, assignment does not happen 在使用channel == 0或1或2代码分配给xor掩码后,可以正常工作,但是如果channel == [1,2]或smt这样,则不会发生分配
In first example by flattening the slice you don't change the shape and actually the
python
Numpy doesn't create a new object. 在第一个示例中,通过展平切片不会改变形状,实际上
python
Numpy不会创建新对象。 so assigning to flattened slice is like assigning to actual slice. 因此,分配给扁平化切片就像分配给实际切片一样。 But by flattening a 2d array you're changing the shape and hence numpy makes a copy of it.
但是通过展平2D数组,您可以更改形状,因此numpy会复制它。
also you don't need to flatten your slice to add to it: 同样,您也不需要展平切片以添加到其中:
In [5]: a[:, [0, 2]] += 100
In [6]: a
Out[6]:
array([[101, 2, 103],
[104, 5, 106]])
As others has pointed out .flat
may create a copy of the original vector, so any updates to it would be lost. 正如其他人指出的那样,
.flat
可能会创建原始矢量的副本,因此对它的任何更新都将丢失。 But flat
tening a 1D slice is fine, so you can use a for
loop to update multiple indexes. 但是,对1D切片进行
flat
很好,因此您可以使用for
循环更新多个索引。
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
a[:, 1].flat = np.array([-1, -1])
print a
# Use for loop to avoid copies
for idx in [0, 2]:
a[:, idx].flat = np.array([-1, -1])
print a
Note that you don't need to use flat[:]
: just flat
is enough (and probably more efficient). 请注意,您不需要使用
flat[:]
:仅使用flat
就足够了(并且可能更有效)。
You could just remove the flat[:]
from a[:, [0, 2]].flat[:] += 100
: 您只需
from a[:, [0, 2]].flat[:] += 100
删除flat[:]
:
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> a[:, 1].flat[:] += 100
>>> a
array([[ 1, 102, 3],
[ 4, 105, 6]])
>>> a[:, [0, 2]] += 100
>>> a
array([[101, 102, 103],
[104, 105, 106]])
But you say it is necessary... Can't you just reshape
whatever you are trying to add to the initial array instead of using flat
? 但是您说这是有必要的...您能不能只是
reshape
要添加到初始数组的内容,而不是使用flat
?
The second index call makes a copy of the array while the first returns a reference to it: 第二个索引调用复制数组,而第一个返回对该数组的引用:
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = a[:,1].flat
>>> b[0] += 100
>>> a
array([[ 1, 102, 3],
[ 4, 5, 6]])
>>> b =a[:,[0,2]].flat
>>> b[0]
1
>>> b[0] += 100
>>> a
array([[ 1, 102, 3],
[ 4, 5, 6]])
>>> b[:]
array([101, 3, 4, 6])
It appears that when the elements you wish to iterate upon in a flat
maner are not adjacent numpy makes an iterator over a copy of the array. 似乎当您希望以
flat
方式迭代的元素不相邻时,numpy会在数组副本上进行迭代。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.