【问题标题】:Changing values in Numpy array according to index根据索引更改 Numpy 数组中的值
【发布时间】:2021-12-30 15:05:03
【问题描述】:

当我使用索引一次来更改值时,它可以工作。 但是,当我两次使用索引来更改值时,什么都没有改变。 为什么我不能两次使用索引来更改值?

import numpy as np

a = np.arange(100)
a[np.array([10,20,30,40,50])] = 1

print(a[np.array([10,20,30,40,50])])

# array([1, 1, 1, 1, 1]) which can be modified as 1

a = np.arange(100)
(a[np.array([10,20,30,40,50])])[np.array([1,2,3])] = 1

print((a[np.array([10,20,30,40,50])])[np.array([1,2,3])])

# array([20, 30, 40]) which can not be modified as 1

【问题讨论】:

  • (a[np.array([10,20,30,40,50])]) 创建一个新的,而不是 view

标签: python arrays numpy


【解决方案1】:

这是一个关于 NumPy 中的视图和副本的令人困惑的问题。 我发现这个问题[Numpy: views vs copy by slicing] 与这个问题相似,@Maltimore 提到的这个文档[Views versus copies in NumPy] 可以解释。

NumPy Fancy Indexing 返回 numpy 数组的副本而不是视图。
但是,当使用花哨的索引将值设置为 numpy 数组时,python 解释器所做的是调用 __setitem__ 函数。以代码为例。

在这一行:

a[np.array([10,20,30,40,50])] = 1

python实际上做的是

a.__setitem__(np.array([10,20,30,40,50]), 1)

即不需要创建视图或副本,因为可以就地评估该方法(即不涉及创建新对象)。

将此行分解为以下代码:

# (a[np.array([10,20,30,40,50])])[np.array([1,2,3])] = 1
a_copy = a[np.array([10,20,30,40,50])]
a_copy[np.array([1,2,3])] = 1

print(a[np.array([10,20,30,40,50])])
# [10, 20, 30, 40, 50]

print(a_copy)
# [10,  1,  1,  1, 50]

结果这行修改了副本的值,所以原来的numpy数组不变。

【讨论】:

    猜你喜欢
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 2013-06-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多