【问题标题】:how to assign to numpy array represented by iterator如何分配给迭代器表示的numpy数组
【发布时间】:2022-11-11 22:20:45
【问题描述】:

我有许多 numpy 数组 a,b,c, ...它们都应该根据布尔掩码数组 keep 进行修剪或根据索引数组 indices 重新排列.通过arr = arr[keep] 对单个数组执行此操作,但很乏味。因此,我想通过循环对所有数组执行此操作,但以下失败

for arr in [a,b,c]:
    arr = arr[keep]
for arr in [a,b,c]:
    arr = arr[indices]

我注意到,如果我使用arr[:] = arr[indices],即使arrindices 的形状不同(但在第一个轴上一致),索引也可以正常工作。但这不适用于掩蔽。那么如何以最少的副本一般地执行此操作(对于屏蔽或索引)?

为了完整起见,这里是测试用例

import numpy as np
a = np.random.random(5)
b = np.array([[1,-1],[2,-2],[3,-3],[4,-4],[4,-4]])

# first test with indexing (for sorting)
i = np.argsort(a)
B = b[i]  # for testing purposes
print(B)
for arr in [a,b]:
    arr = arr[i]
print(b)  # should match B

# second test with boolean (for masking)
k = a < 0.5
B = b[k]  # for testing purposes
print(B)
for arr in [a,b]:
    arr = arr[k]
print(b)  # should match B

【问题讨论】:

  • 这是一个基本的python迭代错误。 for i in alist: i=3 不会更改列表中的任何内容。
  • 创建一个新名单并附加得到的新值。
  • @hpaulj 是的,但这(过去)不是问题(我显然没有完全意识到这一点)。我已经编辑了问题以避免示例中的明确列表。我对隐式列表[a,b,c]的使用意味着会发生这个基本的python迭代错误。因此,在任何解决方案中都必须避免这种用法。

标签: python arrays list numpy indexing


【解决方案1】:

基于this answer 到一个类似的问题,我有以下解决方案。

list = [a,b,c]           # in practice, this could be many more numpy arrays
for i,arr in enumerate(list):
    list[i] = arr[keep]  # assign the list element to the new array, the modification of the old one
a,b,c = list             # unpack the new arrays from the list

我最初的尝试有两个重要的区别。首先,通过将赋值中的迭代器arr替换为list[i],改变了实际的列表条目(避免了常见的python迭代错误在对问题的评论中提到)。其次,通过先声明列表,然后更改它,然后解包到原始数组,最后还更改变量abc 以引用新/更改的数组。

当然,对于索引解决方案

for arr in [a,b,c]:
    arr[:] = arr[indices]

效率更高,因为没有创建新数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多