【问题标题】:combination of advanced indexing and basic slicing高级索引和基本切片的组合
【发布时间】:2019-05-09 02:55:28
【问题描述】:

我试图从 Numpy 文档中理解 combination of basic slicing and advanced indexing section。它说高级索引操作可能有不同的内存布局,但是我在下面的代码 sn-p 中观察到一些不同的行为:

a = np.random.randn(3,3)
# case1
a[:, :][a > 0] = 0
output:
array([[ 0.        , -1.07474179, -0.06313855],
       [ 0.        , -0.74049837, -1.7376245 ],
       [-0.93616586,  0.        , -2.2520479 ]])
# case2
a[:, (0, 1, 2)][a > 0] = 0
output:
array([[ 0.67667783, -1.07474179, -0.06313855],
       [ 0.74418166, -0.74049837, -1.7376245 ],
       [-0.93616586,  0.96351976, -2.2520479 ]])

在我看来,第二种情况是高级索引,所以不会对原来的a进行修改。 (如果我理解错了,请纠正我。)

但是,下面的情况好像关键不是高级索引。

a[:, (0, 1, 2)] = 0
output:
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])

这让我很困惑,你能给我一些想法吗? 提前致谢!

【问题讨论】:

  • a[:,:] 除了查看整个数组之外什么都不做,

标签: python numpy


【解决方案1】:

在您的情况 #2 a[:, (0, 1, 2)][a > 0] = 0 中,高级索引正在创建数组的副本,如 NumPy manual 中所述:

高级索引始终返回数据的副本

然后赋值操作改变这个副本,这意味着原始数组a 保持不变。复制是由[a<0] 触发的,这会导致解释器调用a.__getitem__((slice(None,None), (0, 1, 2))),从而生成一个复制。

在第三种情况下,a[:, (0, 1, 2)] = 0,解释器不需要创建副本。相反,它调用a.__setitem__((slice(None,None), (0, 1, 2)), 0) 直接修改原始数组。

NumPy Cookbook 中的条目“But fancy indexing does seem to return views sometimes, doesn't it?”中解释了这种行为

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 2022-07-21
    • 1970-01-01
    • 2022-01-16
    • 2021-05-30
    • 1970-01-01
    相关资源
    最近更新 更多