如何选择numpy数组索引的反向?
我有一大堆数据,我需要比较一组样本和这个数组中所有其他元素之间的距离。下面是我数据集的一个非常简单的例子。
import numpy as np
import scipy.spatial.distance as sd
data = np.array(
[[ 0.93825827, 0.26701143],
[ 0.99121108, 0.35582816],
[ 0.90154837, 0.86254049],
[ 0.83149103, 0.42222948],
[ 0.27309625, 0.38925281],
[ 0.06510739, 0.58445673],
[ 0.61469637, 0.05420098],
[ 0.92685408, 0.62715114],
[ 0.22587817, 0.56819403],
[ 0.28400409, 0.21112043]]
)
sample_indexes = [1,2,3]
# I'd rather not make this
other_indexes = list(set(range(len(data))) - set(sample_indexes))
sample_data = data[sample_indexes]
other_data = data[other_indexes]
# compare them
dists = sd.cdist(sample_data, other_data)
有没有办法在numpy数组中找到不是样本索引的索引?在我上面的例子中,我创建了一个叫做other_indexes的列表。出于各种原因,我不想这样做(数据集太大、线程问题、系统内存非常非常少等等)。有没有办法做到类似的事情……
other_data = data[ indexes not in sample_indexes]
我听说numpy的掩码可以做到这一点,但我试过……
other_data = data[~sample_indexes]
结果给我报错。我必须创建一个掩码吗?
4 个回答
-3
我对 numpy
的具体细节不太了解,但我可以给你一个大致的解决办法。假设你有一个这样的列表:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
。
接下来,你创建一个你不想要的索引列表:
inds = [1, 3, 6]
。
现在,只需这样做:
good_data = [x for x in a if x not in inds]
,这样就得到了 good_data = [0, 2, 4, 5, 7, 8, 9]
。
5
你也可以使用 setdiff1d
这个函数:
In [11]: data[np.setdiff1d(np.arange(data.shape[0]), sample_indexes)]
Out[11]:
array([[ 0.93825827, 0.26701143],
[ 0.27309625, 0.38925281],
[ 0.06510739, 0.58445673],
[ 0.61469637, 0.05420098],
[ 0.92685408, 0.62715114],
[ 0.22587817, 0.56819403],
[ 0.28400409, 0.21112043]])
13
你可以试试 in1d
这个东西。
In [5]:
select = np.in1d(range(data.shape[0]), sample_indexes)
In [6]:
print data[select]
[[ 0.99121108 0.35582816]
[ 0.90154837 0.86254049]
[ 0.83149103 0.42222948]]
In [7]:
print data[~select]
[[ 0.93825827 0.26701143]
[ 0.27309625 0.38925281]
[ 0.06510739 0.58445673]
[ 0.61469637 0.05420098]
[ 0.92685408 0.62715114]
[ 0.22587817 0.56819403]
[ 0.28400409 0.21112043]]
44
mask = np.ones(len(data), np.bool)
mask[sample_indexes] = 0
other_data = data[mask]
这段代码可能看起来不太优雅,毕竟本来可以用一行代码搞定,但它的效率还不错,而且占用的内存也很少。
如果你最关心的是内存问题,使用np.delete可以避免创建一个掩码,而使用花式索引的话反正会创建一个副本。
再想想,np.delete并不会修改原来的数组,所以它其实就是你想要的那种一行代码。