【发布时间】:2012-10-07 06:33:08
【问题描述】:
如何使用 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]
使用简单的解决方案应该可以编写一个简单的函数。但是由于我需要多次执行此操作,是否有任何快速简洁的方法来执行此操作?
【问题讨论】:
如何使用 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]
使用简单的解决方案应该可以编写一个简单的函数。但是由于我需要多次执行此操作,是否有任何快速简洁的方法来执行此操作?
【问题讨论】:
您可以使用 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()]
这个答案非常类似于:
def unique(array):
uniq, index = np.unique(array, return_index=True)
return uniq[index.argsort()]
但是,numpy.unique 在内部使用了不稳定的排序,因此不能保证您获得任何特定的索引,即第一个或最后一个。
我认为有序的字典也可以工作:
def unique(array):
uniq = OrderedDict()
for i in array:
uniq[i] = 1
return uniq.keys()
【讨论】:
unique 使用np.unique 的return_index 参数是否存在问题,它可能会产生不正确的结果?这个unique 可能会返回一个序列,其中一些元素不遵守原始序列强加的顺序,例如,(纯粹用于演示)unique([1,0,1]) --> [0, 1]?
np.unique 的文档 (docs.scipy.org/doc/numpy/reference/generated/numpy.unique.html) 指出使用 return_index=True 返回的索引将指示 第一次 次出现,因此您的第二次 unique 应该是安全的并且正确,对吧?
您可以使用return_index 参数来做到这一点:
【讨论】:
pandas.unique()。默认不排序。
a[np.sort(np.unique(a, return_index=True)[1])]