【问题标题】:Find indices of a list of values in a not sorted numpy array在未排序的 numpy 数组中查找值列表的索引
【发布时间】:2016-10-13 13:07:37
【问题描述】:

我指的是一个类似的问题:Find indices of a list of values in a numpy array

在这种情况下,我们有一个已排序的主数组和另一个我们想要在主数组中查找索引的数组。

master = np.array([1,2,3,4,5])
search = np.array([4,2,2,3])

建议的解决方案是:

>>> master = np.array([1,2,3,4,5])
>>> search = np.array([4,2,2,3])
>>>np.searchsorted(master, search)
array([3, 1, 1, 2])

但是如果master没有排序呢? 例如,如果我有两个这样的数组,其中第一个没有排序:

>>>master = np.array([2,3,5,4,1])
>>>search = np.array([3,2,1,4,5])

我明白了:

>>> np.searchsorted(master, search)
array([1, 0, 0, 2, 5])

但我想:

array([1,0,4,3,2])

即在 master 中搜索项的索引。

如何使用 numpy 的本机函数获取它们?(不使用 [np.where(master==i) for i in search])

谢谢

编辑: 在这种情况下,搜索数组是 master 的排列。然后我想找到master的索引是如何排列的,以给出一个像search这样的排列数组。

一般情况下,搜索数组包含一些可能包含或不包含在主文件中的项目,例如:

>>>master = np.array([2,3,5,4,1])
>>>search = np.array([1,4,7])

【问题讨论】:

  • 这是一个 XY 问题吗?您只是想找到给定数组的 permutation 吗?因为这很容易做到。
  • 那么你想避免排序吗?结果不是您所期望的,因为searchsorted 背后的算法假定输入是经过排序的(就像在二进制搜索中一样)。
  • 在我的具体情况下,search 是 master 的排列(那么我的意思是找到导致搜索数组的 master 排列的索引)

标签: python arrays numpy


【解决方案1】:

免责声明:我为an earlier revision of the question 写了这个答案。如果你想解决附录中的问题(当我们不只是寻找数组的排列时),see Will's answer

如果一切都失败了,您需要暂时对主数组进行排序,然后在匹配元素后反转所需的排序顺序:

import numpy as np

master = np.array([2,3,5,4,1])
search = np.array([3,2,1,4,5])

# sorting permutation and its reverse
sorti = np.argsort(master)
sorti_inv = np.empty(sorti.shape,dtype=np.int64)
sorti_inv[sorti] = np.arange(sorti.size)

# get indices in sorted version
tmpind = np.searchsorted(master,search,sorter=sorti)

# transform indices back to original array with inverse permutation
final_inds = tmpind[sorti_inv]

上面的结果是正确的

array([1, 0, 4, 3, 2])

正如您在评论中指出的那样,您的特定 searchmaster 是彼此的排列。在这种情况下,您可以选择对 both 数组进行排序,并将逆排列与其他直接排列结合使用:

sorti = np.argsort(master)
sorti_inv = np.empty(sorti.shape,dtype=np.int64)
sorti_inv[sorti] = np.arange(sorti.size)
sorti_s = np.argsort(search)
final_inds = sorti_s[sorti_inv]

人们应该考虑搜索两个数组与在另一个数组的排序版本中搜索一个数组所需的工作量。我真的不知道哪个更快。

【讨论】:

  • 这个答案的第一部分通常是错误的(尽管它适用于提供的测试用例) - 假设问题要求 final_inds 使得 np.array_equal(master[final_inds], search)True
  • @以后有机会我会仔细看看,谢谢。从时间戳来看,我什至可能都没有看到这个问题的编辑。
  • @Will 抱歉,我忘了跟进您的评论。你是对的,因为我怀疑我没有看到这个问题的编辑。作为最简单的解决方案,我在顶部放置了免责声明,如果读者正在寻找更普遍的问题,他们会指出您的答案。
【解决方案2】:

这是对原始问题的回答。 (问题Edit没有指定当search不是master的子集时应该返回什么)

import numpy as np

def get_indices(master, search):

    if not set(search).issubset(set(master)):
        raise ValueError('search must be a subset of master')

    sorti = np.argsort(master)

    # get indices in sorted version
    tmpind = np.searchsorted(master,search,sorter=sorti)

    final_inds = sorti[tmpind]

    return final_inds


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

final_inds = get_indices(master, search)

assert( np.array_equal(master[final_inds], search) )

final_inds 的结果是

array([3, 1, 0, 4, 4])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多