[英]Efficiently finding range of indices for positive values in 2D numpy array
[英]Finding indices of values in 2D numpy array
我正在尝试从一个numpy数组中获取索引值,我尝试使用相交而不是徒劳。 我只是想在2个数组中查找类似的值。 一个是2D,我要选择一列,另一个是1D,仅是要搜索的值列表,因此实际上只有2个1D数组。
我们将此数组称为:
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97612, 1],
[ 1, 97697, 1],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97944, 1],
[ 1, 97955, 2]])
我们正在搜索说, values = numpy.array([97612, 97633, 97697, 97999, 97943, 97944])
所以我尝试:
numpy.where(a[:, 1] == values)
而且,我期望有一堆值的索引,但是取而代之的是,我取回一个空的数组,它吐出[(array([], dtype=int64),)]
。
如果我尝试这样做:
numpy.where(a[:, 1] == 97697)
它给了我(array([2]),)
,这是我所期望的。
我在这里缺少数组的怪异之处吗? 还是有可能更简单的方法来做到这一点? 如我所料,查找数组索引和匹配数组似乎不起作用。 当我想通过指数或唯一值找到数组的并集或相交时,它似乎无法正常工作。 任何帮助都将是超级。 谢谢。
编辑:根据沃伦斯的要求:
import numpy
a = numpy.array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97612, 1],
[ 1, 97697, 1],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97944, 1],
[ 1, 97955, 2]])
values = numpy.array([97612, 97633, 97697, 97999, 97943, 97944])
我发现numpy.in1d
将为我提供该操作的布尔值的正确真值表,并带有一个应映射到原始数据的相同长度的1d数组。 现在我唯一的问题是如何处理,例如删除或修改那些索引处的原始数组。 我可以用一个循环努力地完成它,但是据我所知,numpy中有更好的方法。 我已经找到了,用numpy掩盖的真值表应该是非常强大的。
np.where
带一个参数是相当于np.nonzero
。 它为您提供条件(输入数组)为True
的索引。
在您的示例中,您正在检查a[:,1]
和values
之间a[:,1]
元素方式相等性
a[:, 1] == values
False
因此,它将为您提供正确的结果:输入中没有索引为True
。
您应该改用np.isin
np.isin(a[:,1], values)
array([False, False, True, True, False, False, False, False, True, False], dtype=bool)
现在您可以使用np.where
来获取索引
np.where(np.isin(a[:,1], values))
(array([2, 3, 8]),)
并使用它们来寻址原始数组
a[np.where(np.isin(a[:,1], values))]
array([[ 1, 97612, 1],
[ 1, 97697, 1],
[ 1, 97944, 1]])
使用简单的相等性检查的最初解决方案确实可以与正确的broadcasting
一起工作:
np.where(a[:,1] == values[..., np.newaxis])[1]
array([2, 3, 8])
编辑 : 鉴于您似乎在使用上述结果来索引和操作数组时遇到问题,这里有几个简单的示例
现在,您应该有两种方法来访问原始数组中的匹配元素,即二进制掩码或np.where
的索引。
mask = np.isin(a[:,1], values) # np.in1d if np.isin is not available
idx = np.where(mask)
假设您要将所有匹配的行都设置为零
a[mask] = 0 # or a[idx] = 0
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 0, 0, 0],
[ 0, 0, 0],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 0, 0, 0],
[ 1, 97955, 2]])
或者您要将匹配行的第三列乘以100
a[mask, 2] *= 100
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97612, 100],
[ 1, 97697, 100],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97944, 100],
[ 1, 97955, 2]])
或者您想删除匹配的行(此处使用索引比使用掩码更方便)
np.delete(a, idx, axis=0)
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97955, 2]])
只是一个想法:
尝试展平2D数组并使用numpy.intersect1d进行比较。
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.ndarray.flatten.html
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.intersect1d.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.