【问题标题】:numpy.unique with order preservednumpy.unique 保留顺序
【发布时间】:2013-03-26 12:41:00
【问题描述】:
['b','b','b','a','a','c','c']

numpy.unique 给出

['a','b','c']

我怎样才能保留原始订单

['b','a','c']

很好的答案。奖金问题。为什么这些方法都不适用于这个数据集? http://www.uploadmb.com/dw.php?id=1364341573这是问题numpy sort wierd behavior

【问题讨论】:

标签: python numpy


【解决方案1】:

unique() 很慢,O(Nlog(N)),但你可以通过以下代码来做到这一点:

import numpy as np
a = np.array(['b','a','b','b','d','a','a','c','c'])
_, idx = np.unique(a, return_index=True)
print(a[np.sort(idx)])

输出:

['b' 'a' 'd' 'c']

Pandas.unique() 对于大数组 O(N) 来说要快得多:

import pandas as pd

a = np.random.randint(0, 1000, 10000)
%timeit np.unique(a)
%timeit pd.unique(a)

1000 loops, best of 3: 644 us per loop
10000 loops, best of 3: 144 us per loop

【讨论】:

  • O(N) 的复杂性在任何地方都没有提到,因此只是一个实现细节。文档只是简单地指出它numpy.unique 快得多,但这可能只是意味着它的常数更小,或者复杂度可能介于线性和 NlogN 之间。
  • 您将如何保留pandas.unique() 的排序?据我所知,它不允许任何参数。
  • @F Lekschas, pandas.unique() 似乎将顺序保留为默认值
【解决方案2】:

使用np.uniquereturn_index 功能。这将返回元素首次出现在输入中的索引。然后argsort 那些索引。

>>> u, ind = np.unique(['b','b','b','a','a','c','c'], return_index=True)
>>> u[np.argsort(ind)]
array(['b', 'a', 'c'], 
      dtype='|S1')

【讨论】:

    【解决方案3】:
    a = ['b','b','b','a','a','c','c']
    [a[i] for i in sorted(np.unique(a, return_index=True)[1])]
    

    【讨论】:

    • 这只是已接受答案的较慢版本
    【解决方案4】:

    如果您尝试删除已排序的可迭代对象的重复项,您可以使用itertools.groupby 函数:

    >>> from itertools import groupby
    >>> a = ['b','b','b','a','a','c','c']
    >>> [x[0] for x in groupby(a)]
    ['b', 'a', 'c']
    

    这更像是 unix 'uniq' 命令,因为它假定列表已经排序。当你在未排序的列表上尝试时,你会得到这样的结果:

    >>> b = ['b','b','b','a','a','c','c','a','a']
    >>> [x[0] for x in groupby(b)]
    ['b', 'a', 'c', 'a']
    

    【讨论】:

    • 几乎所有时间numpy 使用numpy 解决问题的速度更快,纯python 解决方案会很慢,因为numpy 是专门的。
    【解决方案5】:
    #List we need to remove duplicates from while preserving order
    
    x = ['key1', 'key3', 'key3', 'key2'] 
    
    thisdict = dict.fromkeys(x) #dictionary keys are unique and order is preserved
    
    print(list(thisdict)) #convert back to list
    
    output: ['key1', 'key3', 'key2']
    

    【讨论】:

      【解决方案6】:

      如果你想删除重复的条目,比如Unix工具uniq,这是一个解决方案:

      def uniq(seq):
        """
        Like Unix tool uniq. Removes repeated entries.
        :param seq: numpy.array
        :return: seq
        """
        diffs = np.ones_like(seq)
        diffs[1:] = seq[1:] - seq[:-1]
        idx = diffs.nonzero()
        return seq[idx]
      

      【讨论】:

      • 这仅适用于数字。使用!= 而不是-
      【解决方案7】:

      使用 OrderedDict(比列表理解更快)

      from collections import OrderedDict  
      a = ['b','a','b','a','a','c','c']
      list(OrderedDict.fromkeys(a))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-08
        • 2017-06-18
        • 2012-05-31
        • 2014-01-21
        • 2014-12-01
        • 2011-09-06
        • 1970-01-01
        相关资源
        最近更新 更多