【问题标题】:How to select inverse of indexes of a numpy array?如何选择 numpy 数组的索引的倒数?
【发布时间】:2019-08-09 12:50:03
【问题描述】:

我有一大组数据,我需要将一组样本与该数组的距离与该数组的所有其他元素的距离进行比较。下面是我的数据集的一个非常简单的示例。

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]

这给了我一个错误。我必须创建一个面具吗?

【问题讨论】:

  • 可以安排data,使第一行N形成sample_data,其余的形成other_data吗?如果是这样,您可以使用返回 views 的基本切片定义 sample_dataother_data。这将需要很少的额外内存,因为视图共享相同的底层数据
  • 另外,如果您的内存非常有限,您可以考虑使用np.memmap 创建基于文件的数组。

标签: python numpy scipy


【解决方案1】:
mask = np.ones(len(data), np.bool)
mask[sample_indexes] = 0
other_data = data[mask]

对于单行语句来说,这不是最优雅的,但它相当高效,而且内存开销也很小。

如果内存是您最关心的问题,np.delete 将避免创建掩码,而花式索引无论如何都会创建一个副本。

三思而后行; np.delete 不会修改现有数组,因此它几乎就是您要查找的单行语句。

【讨论】:

  • np.delete 不会创建删除指定元素的数组的新副本吗?我宁愿不创建一个新数组,我宁愿从现有的数组中读取。
  • 是的,删除会创建一个副本。如果内存真的那么紧,您是否考虑过将数据存储在 pytables 数组中并对其进行操作?见 f.I. pytables.github.io/usersguide/…
  • 注意;如果删除的数量确实很小,那么一个 python 循环将这些元素交换到数组的末尾,然后创建数组的视图,将是一个简单有效的解决方案
  • 好的,这适用于我的目的。你说我可以做一个 python 循环来将元素交换到数组的末尾。可以在 numpy 数组中就地交换元素吗?我该怎么做?谢谢
【解决方案2】:

你可能想试试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]]

【讨论】:

  • 运行这个 ''''a=np.array([[1,2],[3,4], [5,6]]) a[~np.array([0, 1])] ''''
【解决方案3】:

您也可以使用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]])

【讨论】:

    【解决方案4】:

    我不熟悉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]

    【讨论】:

    • 这将创建大量 python 对象,因此与 numpy 相比内存效率非常低
    猜你喜欢
    • 1970-01-01
    • 2021-07-20
    • 2018-08-26
    • 2014-04-21
    • 1970-01-01
    • 2019-03-11
    • 2021-03-10
    • 2017-12-07
    • 1970-01-01
    相关资源
    最近更新 更多