我有一个二维numpy数组:
A = np.zeros(16).reshape(4,4)
我希望(1, 1), (1,3), (3,1)
和(3,3)
单元格的值为1.
A[[1,3], [1:3]] = 1
仅将{1}分配给(1,1)
和(3,3)
。
A[[1,3], :][:, [1, 3]] = 1
不起作用,因为它使数据的副本不是视图。什么是正确的方法?
答案 0 :(得分:5)
使用步骤= 2的切片:
A[1::2,1::2] = 1
或显式传递所有索引:
A[[1,1,3,3],[1,3,1,3]] = 1
答案 1 :(得分:3)
通常,当您使用数组以这种方式索引另一个数组时,numpy
期望每个数组R
,C
等具有相同的形状。例如,假设您要从此数组中提取非零值:
>>> a
array([[1, 3, 0, 0],
[0, 0, 0, 0],
[2, 4, 0, 0],
[0, 0, 0, 0]])
您将创建一个行索引数组R
:
>>> R
array([[0, 2],
[0, 2]])
列索引数组C
:
>>> C
array([[0, 0],
[1, 1]])
并像这样传递给他们:
>>> a[R, C]
array([[1, 2],
[3, 4]])
请注意,这些可以是您喜欢的任何形状 - 输出将采用相同的形状:
>>> RR
array([0, 2, 0, 2])
>>> CC
array([0, 0, 1, 1])
>>> a[RR, CC]
array([1, 2, 3, 4])
但是,如果你的索引数组中有重复,那么你可以通过使用广播来省去一些麻烦。唯一的问题是结果数组必须广播能。这意味着你需要明确地给它们额外的尺寸。我将使用切片语法来保留额外的维度。
>>> r = R[0:1,:]
>>> c = C[:,0:1]
>>> r
array([[0, 2]])
>>> c
array([[0],
[1]])
>>> a[r, c]
array([[1, 2],
[3, 4]])
如果您没有明确地给予他们额外的维度,numpy
会尽力理解您已经过去的内容,但它不会像预期的那样始终如一地工作。用0:1
替换0
切片会删除额外的维度:
>>> rr = r[0,:]
>>> cc = c[:,0]
>>> rr
array([0, 2])
>>> cc
array([0, 1])
>>> a[rr, c]
array([[1, 2],
[3, 4]])
>>> a[r, cc]
array([[1, 4]])
>>> a[rr, cc]
array([1, 4])
第一个(a[rr, c]
)有效,因为numpy
可以从c
的形状告诉它应该广播。但其他两个都不明确,所以numpy
假设你并不意味着他们被广播。
但请注意,numpy
也提供了使平面阵列可播放的快捷方式。这可以派上用场!
>>> a[numpy.ix_(rr, cc)]
array([[1, 3],
[2, 4]])
答案 2 :(得分:0)
-fno-objc-arc
这里发生的是行索引[[1],[3]]具有形状(2,1),因此它们可以针对具有形状(1的列索引[[1,3]]进行广播,2),得到行/列索引的形状(2,2)数组。因此,我们可以将上述内容视为简短形式:
>>> A = np.zeros(16).reshape(4,4)
>>> A[[[1],[3]], [[1, 3]]] = 1
>>> A
array([[ 0., 0., 0., 0.],
[ 0., 1., 0., 1.],
[ 0., 0., 0., 0.],
[ 0., 1., 0., 1.]])
产生相同的结果。