生成将一个数组索引到另一个数组的布尔掩码

Posted

技术标签:

【中文标题】生成将一个数组索引到另一个数组的布尔掩码【英文标题】:Generating a boolean mask indexing one array into another array 【发布时间】:2012-09-05 02:53:33 【问题描述】:

很难解释我想用文字做什么,所以这里有一个例子。

假设我们有以下输入:

In [76]: x
Out[76]: 
0    a
1    a
2    c
3    a
4    b

In [77]: z
Out[77]: ['a', 'b', 'c', 'd', 'e']

我想得到:

In [78]: ii
Out[78]: 
array([[1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0]])

ii 是一个布尔掩码数组,可应用于z 以取回原始x

我目前的解决方案是编写一个函数,将z 转换为list 并使用index 方法获取z 中元素的索引,然后生成除索引之外的一行零哪里有一个。这个函数被应用到x 的每一行以获得想要的结果。

【问题讨论】:

那么,您的问题是什么?写这个函数?当然,np.choose(["abcde".index(i) for i in x], "abcde") 之类的东西不适合你? 好吧,当我运行你的线路时,我得到了array(['a', 'a', 'c', 'a', 'b'], dtype='|S1')。我想要的是['a', 'a', 'c', 'a', 'b'] 的掩码(5 个布尔元素的列表)。这是否更清楚? 您是在寻找一种更快的方法还是只是更短的输入方式,例如:np.array([[j == i for j in z] for i in x], dtype=int)跨度> @WouterOvermeire 理想地寻找两者 【参考方案1】:

第一种可能性:

>>> choices = np.diag([1]*5)
>>> choices[[z.index(i) for i in x]]

如其他地方所述,您可以将列表理解 [z.index(i) for i in x] 更改为 np.searchsorted(z, x)

>>> choices[np.searchsorted(z, x)]

请注意,正如@seberg 的评论中所建议的,您应该使用np.eye(len(x)) 而不是np.diag([1]*len(x))np.eye 函数直接为您提供一个二维数组,其中对角线为 1,其他位置为 0。

【讨论】:

第一个就是我要找的。​​span> 我认为不要使用np.diag([1]*5),而是使用np.eye(5)【参考方案2】:

这是对 z 进行排序的 numpy 方法。你没有具体说明...如果熊猫需要不同的东西,我不知道:

# Assuming z is sorted.
indices = np.searchsorted(z, x)

现在我真的不知道你为什么想要一个布尔掩码,这些索引可以应用于 z 以返回 x 并且更紧凑。

z[indices] == x # if z included all x.

【讨论】:

不幸的是它们没有排序,我的例子有误导性。我还需要掩码,因为之后我将它们乘以一些概率矩阵:kaggle.com/c/predict-closed-questions-on-stack-overflow/forums/… 如果它们是唯一的,如果您关心速度,请先自行排序。至于布尔数组的创建,我可能会建议像a = np.zeros((...,...), dtype=bool); a[np.ix_[np.arange(...), z]] = 1 这样的东西。不过没关系。 如果我对它们进行排序,那么我将不得不对我必须匹配的所有其他数组和矩阵的列进行排序。不确定是否值得。【参考方案3】:

很惊讶没有人提到numpy.equalouter方法:

In [51]: np.equal.outer(s, z)
Out[51]: 
array([[ True, False, False, False, False],
       [ True, False, False, False, False],
       [False, False,  True, False, False],
       [ True, False, False, False, False],
       [False,  True, False, False, False]], dtype=bool)

In [52]: np.equal.outer(s, z).astype(int)
Out[52]: 
array([[1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0]])

【讨论】:

以上是关于生成将一个数组索引到另一个数组的布尔掩码的主要内容,如果未能解决你的问题,请参考以下文章

使用掩码和其他数组替换数组中的值

科学计算基础软件包NumPy入门讲座:掩码数组

科学计算基础软件包NumPy入门讲座:掩码数组

如何将一个数组的值解包到另一个数组的特定索引中?

如何使用布尔数组将np.infs清零数组的所有索引?

如何在 C# 中将数组的一部分复制到另一个数组?