为numpy数组赋值的花式索引

时间:2015-02-22 21:31:12

标签: python arrays numpy

我有一个二维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

不起作用,因为它使数据的副本不是视图。什么是正确的方法?

3 个答案:

答案 0 :(得分:5)

使用步骤= 2的切片:

A[1::2,1::2] = 1

或显式传递所有索引:

A[[1,1,3,3],[1,3,1,3]] = 1

答案 1 :(得分:3)

通常,当您使用数组以这种方式索引另一个数组时,numpy期望每个数组RC等具有相同的形状。例如,假设您要从此数组中提取非零值:

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

产生相同的结果。