Python numpy数组整数索引平片分配

Python numpy数组整数索引平片分配,python,arrays,python-2.7,numpy,slice,Python,Arrays,Python 2.7,Numpy,Slice,在用numpy做实验时发现了这种奇怪的行为。 此代码正常工作: >>> a = np.array([[1, 2, 3], [4, 5, 6]]) >>> a[:, 1].flat[:] = np.array([-1, -1]) >>> a array([[ 1, -1, 3], [ 4, -1, 6]]) 但为什么这段代码不改为0和2列的-1元素呢 >>> a[:, [0, 2]].flat[:

在用numpy做实验时发现了这种奇怪的行为。 此代码正常工作:

>>> a = np.array([[1, 2, 3], [4, 5, 6]])    
>>> a[:, 1].flat[:] = np.array([-1, -1])
>>> a 
array([[ 1, -1,  3],
       [ 4, -1,  6]])
但为什么这段代码不改为0和2列的-1元素呢

>>> a[:, [0, 2]].flat[:] = np.array([-1, -1])
>>> a 
array([[ 1, -1,  3],
       [ 4, -1,  6]])
如何编写代码,使其变成0和2列的-1元素

UPD:在我的示例中,必须使用
flat
或类似的smt

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)

在使用channel==0或1或2代码分配给xor mask后,工作正常,但如果channel==1,2]或smt是这样,在第一个示例中,通过展平切片,分配不会发生,您不会更改形状,实际上python Numpy不会创建新对象。所以指定给展平切片就像指定给实际切片一样。但是,通过展平2d阵列,您可以更改形状,因此numpy可以复制它

此外,您无需展平切片即可添加:

In [5]: a[:, [0, 2]] += 100

In [6]: a
Out[6]: 
array([[101,   2, 103],
       [104,   5, 106]])

在第一个示例中,通过展平切片,您不会更改形状,实际上python Numpy不会创建新对象。所以指定给展平切片就像指定给实际切片一样。但是,通过展平2d阵列,您可以更改形状,因此numpy可以复制它

此外,您无需展平切片即可添加:

In [5]: a[:, [0, 2]] += 100

In [6]: a
Out[6]: 
array([[101,   2, 103],
       [104,   5, 106]])

您可以从[:,[0,2]]中删除
平面[:]
。平面[:]+=100

>>> 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]])
但是你说这是必要的。。。您是否可以只向初始数组添加任何内容,而不使用
平面

第二个索引调用生成数组的副本,而第一个索引调用返回对该数组的引用:

>>> 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])

当您希望在
平面中迭代的元素不相邻时,numpy会在数组的副本上生成一个迭代器。

您可以从[:,[0,2]]平面中删除
平面[:]
。平面[:]+=100

>>> 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]])
但是你说这是必要的。。。您是否可以只向初始数组添加任何内容,而不使用
平面

第二个索引调用生成数组的副本,而第一个索引调用返回对该数组的引用:

>>> 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])

当您希望在
flat
中迭代的元素不相邻时,numpy会对数组的副本进行迭代。

正如其他人指出的那样
。flat
可能会创建原始向量的副本,因此对它的任何更新都将丢失。但是
flat
tening一个1D切片是可以的,所以您可以使用
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

请注意,您不需要使用
flat[:]
:只要
flat
就足够了(而且可能更有效)。

正如其他人所指出的
。flat
可能会创建原始向量的副本,因此对它的任何更新都将丢失。但是
flat
tening一个1D切片是可以的,所以您可以使用
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


请注意,您不需要使用
flat[:]
:只要
flat
就足够了(而且可能更有效)。

这个例子从另一个问题来看,必须使用
flat
。你能解释一下如何使用
flat
?@请将用例添加到问题中,这样很难回答。这个例子来自其他问题,必须使用
flat
。你能解释一下如何使用
flat
。正如下面已经回答的,
flat
可能会创建一个副本,因此您的更新可能不会更改原始阵列。解释你为什么需要
flat
,也许你能找到解决办法。@lbolla更新的问题@Юааааааааааааааа。我将再次发布问题,但问题公式正确,不清楚为什么需要使用
flat
。正如下面已经回答的,
flat
可能会创建一个副本,因此您的更新可能不会更改原始阵列。解释你为什么需要
flat
,也许你能找到解决办法。@lbolla更新的问题@Юааааааааааааааа。我将再次发布问题,但有正确的问题公式。有什么不喜欢的?没什么,但我正在学习numpy,并期望在这种情况下使用numpy结构。好吧,您似乎固定使用
平面
,但
平面
必须在您的情况下创建一个副本,因此无法使用。我认为你只需要“调整”你的期望……但是等等。For loop不适合我的需要:
xor\u mask[:,:,channel].flat[:len(msg\u bits)]=np.like(msg\u bits,dtype=np.bool)
For ch in channel:xor\u mask[:,:,ch].flat[:len(msg\u bits)]=np.like(msg\u bits,dtype=np.bool)
逻辑上做不同的处理你必须相应地中断
msg\u位。我不知道你为什么热衷于使用
flat
,所以我不能给你一个有意义的建议。这有什么不好呢?没什么,但我正在学习numpy,并期望在这种情况下使用一些numpy构造。好吧,你似乎已经习惯于使用
flat
,但是
flat
必须在你的情况下创建一个副本,所以它不能被使用。我认为你只需要“调整”你的期望……但是等等。For loop不适合我的需要:
xor\u mask[:,:,channel].flat[:len(msg\u bits)]=np.like(msg\u bits,dtype=np.bool)
For ch in channel:xor\u mask[:,:,ch].flat[:len(msg\u bits)]=np.like(msg\u bits,dtype=np.bool)
逻辑上做不同的处理你必须相应地中断
msg\u位。我不知道你为什么喜欢使用
flat
,所以我不能给你一个有意义的建议。