1

我有一个像这样的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]

艾尔认为前面的几行可以完成这项工作,我想知道如何以更快的方式进行切片。也可以通过以下方式:

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

所需的输出是

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

非常感谢!

4

2 回答 2

1

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

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

这就是ix_产生的结果 - 一个数组元组,一个是 (2,1) 的形状,另一个是 (1,2)。它们一起索引一个 (2,2) 块:

In [76]: np.ix_([1,2],[2,3])
Out[76]: 
(array([[1],
        [2]]), array([[2, 3]]))
于 2018-01-26T18:30:00.167 回答
0

对于连续行和列的情况,您可以像这样使用基本切片:

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

于 2018-01-26T15:42:05.063 回答