【问题标题】:Replacing part of Numpy 2D Array using list in both rows and columns使用行和列中的列表替换 Numpy 2D 数组的一部分
【发布时间】:2018-02-21 22:26:55
【问题描述】:

我们先导入numpy

import numpy as np

例如,我有一个矩阵 A,

A = np.identity(10)

我还有另外两个矩阵,

B = np.random.sample((4, 4))
C = np.random.sample((6, 6))

此外,我有两个索引列表,

idx_1 = [1, 2, 4, 7]
idx_2 = [0, 3, 5, 6, 8, 9]

现在我想用 B 替换 A 的 idx_1 行和列,用 C 替换 A 的 idx_2 行和列。最终的 A 矩阵将是块对角矩阵。

实现这一目标的有效方法是什么?

我尝试如下但我没有改变A,我不知道为什么,但我也没有得到任何错误。

A[idx_1][:,idx_1] = B

【问题讨论】:

  • 您能否详细说明“现在我想用 B 替换 A 的 idx_1 行和列”会是什么样子?比如,该步骤的实际输出
  • A[[idx_1] * 4, [idx_1] * 4] = B
  • 您不能使用级联索引,因为第一个索引会创建一个副本。您必须使用一个索引表达式A[...] = B,同时对行和列进行索引。

标签: python arrays python-3.x numpy replace


【解决方案1】:
In [99]: A = np.identity(10).astype(int)
In [100]: A
Out[100]: 
array([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])
In [101]: idx_1 = [1, 2, 4, 7]

我可以选择一组对角线值:

In [102]: A[idx_1, idx_1]
Out[102]: array([1, 1, 1, 1])
In [103]: A[idx_1, idx_1] = [10,20,30,40]
In [104]: A
Out[104]: 
array([[ 1,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0, 10,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 20,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  1,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0, 30,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  1,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  1,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0, 40,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  1,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  1]])

但您似乎想要替换 (4,4) 值块。我们必须在索引上构造一对broadcast 到形状的索引,即 (4,1) 数组和 (1,4) 数组。

In [105]: np.ix_(idx_1, idx_1)
Out[105]: 
(array([[1],
        [2],
        [4],
        [7]]), array([[1, 2, 4, 7]]))

In [106]: A[np.ix_(idx_1, idx_1)]
Out[106]: 
array([[10,  0,  0,  0],
       [ 0, 20,  0,  0],
       [ 0,  0, 30,  0],
       [ 0,  0,  0, 40]])
In [107]: A[np.ix_(idx_1, idx_1)] += 1
In [108]: A
Out[108]: 
array([[ 1,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0, 11,  1,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  1, 21,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  0,  0,  1,  0,  0,  0,  0,  0,  0],
       [ 0,  1,  1,  0, 31,  0,  0,  1,  0,  0],
       [ 0,  0,  0,  0,  0,  1,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  1,  0,  0,  0],
       [ 0,  1,  1,  0,  1,  0,  0, 41,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  1,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  1]])

嵌套列表的等效索引是:

In [109]: A[[[1],[2],[4],[7]],[[1,2,4,7]]]
Out[109]: 
array([[11,  1,  1,  1],
       [ 1, 21,  1,  1],
       [ 1,  1, 31,  1],
       [ 1,  1,  1, 41]])

关于您的索引尝试:

In [110]: A[idx_1]   # A[idx_1,:]
Out[110]: 
array([[ 0, 11,  1,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  1, 21,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  1,  1,  0, 31,  0,  0,  1,  0,  0],
       [ 0,  1,  1,  0,  1,  0,  0, 41,  0,  0]])
In [111]: A[idx_1][:,idx_1]
Out[111]: 
array([[11,  1,  1,  1],
       [ 1, 21,  1,  1],
       [ 1,  1, 31,  1],
       [ 1,  1,  1, 41]])

In[111] 分两步评估;选择第一行,然后选择列。

A[idx_1][:,idx_1] = B

B 的值将替换 Out[110] 中的列。但这是来自A 的值的副本,而不是view。因此,在使用 numpy 时,很好地掌握视图和副本之间以及基本索引和高级索引之间的区别非常重要。

【讨论】:

    猜你喜欢
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 2011-05-19
    • 2018-11-19
    • 2019-10-17
    • 1970-01-01
    相关资源
    最近更新 更多