numpy独特而无排序

kua*_*kid 24 python numpy

如何在不对结果进行排序的情况下使用numpy unique,只是按序列中出现的顺序排序?像这样的东西?

a = [4,2,1,3,1,2,3,4]

np.unique(a) = [4,2,1,3]

而不是

np.unique(a) = [1,2,3,4]

使用天真的解决方案应该可以编写一个简单的函数.但是,由于我需要多次这样做,有没有快速和简洁的方法来做到这一点?

del*_*del 41

您可以使用以下return_index参数执行此操作:

>>> import numpy as np
>>> a = [4,2,1,3,1,2,3,4]
>>> np.unique(a)
array([1, 2, 3, 4])
>>> indexes = np.unique(a, return_index=True)[1]
>>> [a[index] for index in sorted(indexes)]
[4, 2, 1, 3]

  • 有效,但这确实应该作为 np.unique 的选项内置。 (4认同)
  • 从[这个答案](/sf/answers/1094625871/)只需使用`pandas.unique()`。默认情况下它不排序。 (4认同)
  • 是的,这获得了唯一索引,但是排序是否必要?需要排序的迭代与仅在数组中搜索唯一项相同,因此无法避免时间复杂性。但是numpy.unique返回一个新的数组对象。我们应该能够避免这种空间复杂性。 (2认同)

Bi *_*ico 5

您可以通过执行numpy这样的操作来做到这一点,mergsort是稳定的,因此您可以选择每个值的第一个或最后一个出现:

def unique(array, orderby='first'):
    array = np.asarray(array)
    order = array.argsort(kind='mergesort')
    array = array[order]
    diff = array[1:] != array[:-1]
    if orderby == 'first':
        diff = np.concatenate([[True], diff])
    elif orderby == 'last':
        diff = np.concatenate([diff, [True]])
    else:
        raise ValueError
    uniq = array[diff]
    index = order[diff]
    return uniq[index.argsort()]
Run Code Online (Sandbox Code Playgroud)

这个答案非常类似于:

def unique(array):
    uniq, index = np.unique(array, return_index=True)
    return uniq[index.argsort()]
Run Code Online (Sandbox Code Playgroud)

但是,numpy.unique在内部使用不稳定的排序方式,因此不能保证您会获取任何特定的索引,例如first或last。

我认为命令字典也可能有效:

def unique(array):
    uniq = OrderedDict()
    for i in array:
         uniq[i] = 1
    return uniq.keys()
Run Code Online (Sandbox Code Playgroud)