以最 pythonian 的方式在 ndarray 的子 ndarray 中写入。Python 2 中文文档

Writting in sub-ndarray of a ndarray in the most pythonian way. Python 2

提问人:Rafael Valero 提问时间:1/26/2018 最后编辑:kmario23Rafael Valero 更新时间:4/27/2019 访问量:462

问:

我有一个像这样的ndarray:

number_of_rows = 3
number_of_columns = 3
a = np.arange(number_of_rows*number_of_columns).reshape(number_of_rows,number_of_columns)
a

array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

但我想要这样的东西:

array([[0, 100, 101],
       [3, 102, 103],
       [6, 7, 8]])

为此,我想避免一一做,我宁愿在数组或矩阵中做,因为稍后我想扩展代码。 不,我更改了初始矩阵的子矩阵(用数学术语来说,就这个例子 ndarray 而言)。在此示例中,考虑的列是 [1,2] 和行 [0,1]。

columns_to_keep = [1,2] 
rows_to_keep = [0,1]

我的第一次尝试是:

a[rows_to_keep,:][:,columns_to_keep] = np.asarray([[100,101],[102,103]])

但是这不会修改初始 a,我没有任何错误,所以 a=

array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

因此,我实现了一段代码来完成这项工作:

b = [[100, 101],[102, 103]]

for i in range(len(rows_to_keep)):
    a[i,columns_to_keep] = b[i]

Al 认为前面的几行可以完成这项工作,我想知道如何以更快的方式进行切片。在某种程度上,还可以:

columns_to_keep = [0,2] 
rows_to_keep = [0,2]

所需的输出是

array([[100, 1, 101],
       [3, 4, 5],
       [102, 7, 103]]).

非常感谢!

python-2.7 多维数组 切片 numpy-ndarray

评论

0赞 hpaulj 1/27/2018
a[[1,2],...]是 的副本。每个索引操作都是独立执行的。您需要在一次索引操作中为行和列编制索引。我建议阅读 numpy 索引:docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.htmla

答:

0赞 kmario23 1/26/2018 #1

对于连续行和列的情况,可以使用如下基本切片:

In [634]: a
Out[634]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [635]: b = np.asarray([[100, 101],[102, 103]])

In [636]: a[:rows_to_keep[1]+1, columns_to_keep[0]:] = b

In [637]: a
Out[637]: 
array([[  0, 100, 101],
       [  3, 102, 103],
       [  6,   7,   8]])

1赞 hpaulj 1/27/2018 #2

使用类似列表的索引称为高级索引。它本身生成一个副本,而不是一个视图。您必须使用一个索引表达式,而不是两个索引表达式来分配或更改值。也就是说,这是一个副本,修改了该副本,而不是原始副本。[1,2]a[[1,2],:]a[[1,2],:][:,[1,2]] += 100a

In [68]: arr = np.arange(12).reshape(3,4)

使用切片进行索引;这是基本索引:

In [69]: arr[1:,2:]
Out[69]: 
array([[ 6,  7],
       [10, 11]])

In [70]: arr[1:,2:] += 100

In [71]: arr
Out[71]: 
array([[  0,   1,   2,   3],
       [  4,   5, 106, 107],
       [  8,   9, 110, 111]])

对列表进行相同的索引需要相互“广播”的数组。 是生成这些内容的便捷方法:ix_

In [73]: arr[np.ix_([1,2],[2,3])]
Out[73]: 
array([[106, 107],
       [110, 111]])

In [74]: arr[np.ix_([1,2],[2,3])] -= 100

In [75]: arr
Out[75]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

这是生成的内容 - 数组的元组,一个是 (2,1) 的形状,另一个是 (1,2)。它们一起索引一个 (2,2) 块:ix_

In [76]: np.ix_([1,2],[2,3])
Out[76]: 
(array([[1],
        [2]]), array([[2, 3]]))

评论

0赞 Rafael Valero 1/29/2018
谢谢!。'a[np.ix_(rows_to_keep, columns_to_keep)] = b' 这是我的情况的解决方案。