修改numpy中的索引对象

Posted

技术标签:

【中文标题】修改numpy中的索引对象【英文标题】:Modify indexed object in numpy 【发布时间】:2018-06-29 09:45:44 【问题描述】:

我想根据一些索引更新np.array

a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.array([1,2])
a[b, :][:, b] += 1

之后,a 没有改变,因为只是修改了一个副本。 如何修改原始对象?

【问题讨论】:

问题是a[b,:]是一个副本。 [:,b]+=... 正在修改该副本,而不是原始 a 【参考方案1】:

使用numpy.ix_ 创建一个开放网格并将其用于索引。使用ix_ 可以利用广播,它可以节省空间,因为它不需要创建索引的完整补充

>>> import numpy as np
>>> np.ix_(b,b)
(array([[1],
       [2]]), array([[1, 2]]))
>>>
>>> a[np.ix_(b,b)] += 10
>>> a
array([[ 0,  1,  2],
       [ 3, 14, 15],
       [ 6, 17, 18]])
>>>

对于这个用例,最好使用ix_,但也可以使用numpy.meshgrid。它的缺点是创建更大的索引集。

>>> np.meshgrid(b,b)
[array([[1, 2],
       [1, 2]]), array([[1, 1],
       [2, 2]])]

>>> a[np.meshgrid(b,b)] *= -1
>>> a
array([[  0,   1,   2],
       [  3, -14, -15],
       [  6, -17, -18]])
>>>

Numpy 的 meshgrid 更常用,如 What is purpose of meshgrid in Python? 和 Meshgrids and disambiguating rows and columns from Cartesian coordinates 中所述

【讨论】:

【参考方案2】:

首先使用数组b选择行,并限制从位置1开始的列以提取右下角的正方形。

>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])   

# select the square on the lower right corner and increment it
>>> a[b, 1:] += 1
>>> a
array([[ 1,  2,  3],
       [ 4,  6,  7],
       [ 7,  9, 10]])

或者,你也可以使用这个:

>>> a[b, b[0]:] += 1
>>> a
array([[ 1,  2,  3],
       [ 4,  6,  7],
       [ 7,  9, 10]])

【讨论】:

这将增加下面两行,而不是右下角的正方形。预期输出为 array([[ 1, 2, 3],[ 4, 6, 7],[ 7, 9, 10]]) 这适用于问题中的特定b 数组,但不会推广到任意b 数组。对于这种特殊情况,您可以使用b[1:,1:] += 1,但我认为这不是问题所在。 @jakevdp 我想你的意思是a[1:, 1:] += 1 但这相当于a[b, 1:] += 1 ;) 你说得对,我是想说a[1:, 1:]。我更大的观点是,以不回答所提出的更普遍问题的方式解决特定的简化示例并不是特别有用。【参考方案3】:

您需要一步完成索引。对于您正在尝试做的事情,这将起作用:

a[b[:, np.newaxis], b] += 1
print(a)
# array([[ 1,  2,  3],
#        [ 4,  6,  7],
#        [ 7,  9, 10]])

当您对具有多个索引列表的数组进行索引时,这些列表将broadcast 一起索引到数组中。因此,如果您有一个 2x1 索引和一个 1x2 索引,则生成的数组切片为 2x2,在这种情况下引用您希望修改的数组的 2x2 部分。

【讨论】:

以上是关于修改numpy中的索引对象的主要内容,如果未能解决你的问题,请参考以下文章

Numpy之ndarray的查询和修改 - 索引和切片

数据分析2 numpy(ndarray数组,属性,创建,索引切片,运算,函数,随机数), Pandas(Series创建,缺失值处理,特性,索引,DataFrame)

Numpy 切片和索引

为什么在似乎是数据副本的操作上修改原始数据?

在 NumPy 中跟踪多索引和修改值

NumPy之 索引技巧