python - 更新多重索引 np.array 中的元素

标签 python numpy indexing

我有一个 2D numpy 数组,需要通过多层索引更新元素选择。对我来说,执行此操作的明显方法不起作用,因为 numpy 似乎只是更新数组的副本,而不是数组本身:

import numpy as np

# Create an array and indices that should be updated
arr = np.arange(9).reshape(3,3)
idx = np.array([[0,2], [1,1],[2,0]])
bool_idx = np.array([True, True, False])

# This line does not work as intended since the original array stays unchanged
arr[idx[:,0],idx[:,1]][bool_idx] = -1 * arr[idx[:,0],idx[:,1]][bool_idx]

这是结果输出:

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

但是,我期望这个输出:

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

最佳答案

我们需要使用给定的mask屏蔽索引,然后索引到arr并分配新值。对于索引,我们可以使用 tuple(masked_indices) 来索引,或者使用索引数组的两列来进行整数索引,从而为我们提供了两种方法。

方法#1:

arr[tuple(idx[bool_idx].T)] *= -1

方法#2:

idx_masked = idx[bool_idx]
arr[idx_masked[:,0],idx_masked[:,1]] *= -1

为什么原来的方法不起作用?

在 LHS 上,您正在执行 arr[idx[:,0],idx[:,1]][bool_idx],这本质上是两个步骤:arr[idx[:, 0],idx[:,1]],它在幕后调用 arr.__getitem__(indexer)*。当索引器是切片时,元素的规律性允许 NumPy 返回 View (通过修改步幅和偏移量)。当索引器是任意 bool 掩码或任意整数数组时,所选元素通常没有规律性,因此无法返回 View 。我们将 arr[idx[:,0],idx[:,1]] 称为 arr2

在下一步中,使用组合的arr[idx[:,0],idx[:,1]][bool_idx],即arr2[bool_idx] ,在底层它调用 arr2.__setitem__(mask),它是为了修改 arr2 而实现的,因此不会传播回 arr .

*灵感来自 - https://stackoverflow.com/a/38768993/ .

有关 __getitem__ 的更多信息, __setitem__ .

为什么本文中发布的方法有效?

因为两者都直接使用了 arr 上的 indexer 和修改 arrarr.__setitem__(indexer)

关于python - 更新多重索引 np.array 中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55313976/

相关文章:

python - if else 与数学映射小序列

python - Healpy lmax 的默认格式

python - Yocto,安装 Numpy

java - 如何使用 Java 索引整个硬盘/文件系统?

javascript - Python 将 JavascriptSerializer 转换为日期时间?

python - phantomjs 带有非英文 url

python - 在Python中一起打印多个表

java - Java 有 IndexSet 和 Range 类吗?

python - 在 pandas 数据框列(又名 pd.series)中查找数组元素位置

python:导入引用全局范围的函数