【问题标题】:match non-unique, un-sorted array to indexes in unique, sorted array将非唯一的、未排序的数组与唯一的、排序的数组中的索引匹配
【发布时间】:2016-03-12 16:39:46
【问题描述】:

我有一个排序的、唯一的 numpy 字符数组:

import numpy as np
vocab = np.asarray(['a', 'aaa', 'b', 'c', 'd', 'e', 'f']) 

我还有另一个未排序的数组(实际上我有数百万个):

sentence = np.asarray(['b', 'aaa', 'b', 'aaa', 'b', 'z']) 

第二个数组比第一个数组小得多,并且还可能包含原始数组中没有的值。

我想要做的是将第二个数组中的值与其对应的索引相匹配,返回nan 或一些特殊值用于不匹配。

例如:

sentence_idx = np.asarray([2, 1, 2, 1, 2, np.nan]) 

我用 np.in1d 尝试了几个不同的匹配函数迭代,但它似乎总是在包含重复单词的句子上分解。

我也尝试了几种不同的列表理解,但它们太慢了,无法在我的数百万个句子的集合中运行。

那么,在 numpy 中完成此任务的最佳方法是什么?在 R 中,我会使用 match 函数,但似乎没有 numpy 等效项。

【问题讨论】:

    标签: python arrays r numpy


    【解决方案1】:

    您可以使用漂亮的工具进行此类搜索 np.searchsorted,就像这样 -

    # Store matching indices of 'sentence' in 'vocab' when "left-searched"
    out = np.searchsorted(vocab,sentence,'left').astype(float)
    
    # Get matching indices of 'sentence' in 'vocab' when "right-searched".
    # Now, the trick is that non-matches won't have any change between left 
    # and right searches. So, compare these two searches and look for the 
    # unchanged ones, which are the invalid ones and set them as NaNs.
    right_idx = np.searchsorted(vocab,sentence,'right')
    out[out == right_idx] = np.nan
    

    示例运行 -

    In [17]: vocab = np.asarray(['a', 'aaa', 'b', 'c', 'd', 'e', 'f']) 
        ...: sentence = np.asarray(['b', 'aaa', 'b', 'aaa', 'b', 'z'])
        ...: 
    
    In [18]: out = np.searchsorted(vocab,sentence,'left').astype(float)
        ...: right_idx = np.searchsorted(vocab,sentence,'right')
        ...: out[out == right_idx] = np.nan
        ...: 
    
    In [19]: out
    Out[19]: array([  2.,   1.,   2.,   1.,   2.,  nan])
    

    【讨论】:

    • 谢谢!这正是我一直在寻找的。快速提问,np.searchsorted 如何决定不匹配返回什么?例如。 np.searchsorted(vocab,sentence,'left').astype(float) 在最后一个位置返回 7。
    • @Zach 它查看将该元素(在本例中为最后一个元素)放在按字母顺序排序的数组中的位置。 z 是最后一个字母,因为vocab 中没有任何东西是z,因此vocab 的左侧没有可以放置z 的元素。因此,z 的索引输出将是 len(vocab)+1。考虑另一种情况:您有'_' 而不是'z'。在这种情况下,按字母排序并且没有匹配项,它将是0。考虑另一种情况:我们有'a' 而不是'z'。同样,索引 o/p 将是 0。但这一次,seacrshorted(...'right') 将不同于 '_' 的情况。
    猜你喜欢
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2011-06-17
    相关资源
    最近更新 更多