基于掩码数组过滤NumPy数组的Python实现

3
假设我有一个长度为N的数据numpy数组,以及一个长度为N的位掩码数组。
data = [1,2,3,4,5,6,7,8,9,0]
mask = [0,1,0,1,0,1,0,1,0,1]

有没有一种无需循环的numpy方法来创建一个新的数组,该数组基于数据创建,只有当masks [i]!= 0时,它才会获取data的所有条目?就像这样:

func(data, mask) = [2,4,6,8,0]

或者等价于循环符号表示:

ans = []
for idx in range(mask):
    if mask[idx]:
        ans.append(data[idx])
ans = numpy.array(ans)

谢谢!


2
你的问题比链接的重复问题还要简单,因为你只在一个维度上工作。所需的代码是...等一下...data[mask != 0]。是的,这种简化正是Numpy的核心卖点之一。当然,你需要使用Numpy数组,而不是普通的Python列表。 - Karl Knechtel
2
你应该查看:numpy文档中的解决方案。在你的情况下,只需执行:np.ma.array(data, mask=mask).data(在此之前将列表转换为数组)。 - Memristor
@Memristor 当我尝试np.ma.array(data, mask=mask).data时,我只得到了原始数组。不太清楚你发的链接如何能用来获得OP想要的结果。 - Mark
是的,看起来.data给出了原始数组。.tolist()给出了掩码列表,但并不会移除掩码值。它们总是被fill_value(可以是None或自定义值)填充。 - tdy
@MarkM 抱歉,你必须先获取 x = np.ma.array(...) 的结果,然后使用 x[~x.mask].data,它会移除掩码为0的元素;另一种方法是使用 wherenp.where([1, 0, 1, 0, 1], [1, 2, 3, 4, 5], 0),它不会移除元素,而是用0替代。 - Memristor
1个回答

6

你可以使用布尔值数组过滤numpy数组。你从一个整数数组开始,你不能直接使用它,但你当然可以将1和0解释为布尔值,然后直接使用它作为掩码:

import numpy as np

data = np.array([1,2,3,4,5,6,7,8,9,0])
mask = np.array([0,1,0,1,0,1,0,1,0,1])

data[mask.astype(bool)]
# array([2, 4, 6, 8, 0])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接