在一列中查找唯一值并排序。

281

我有一个pandas数据框。我想按升序打印其中一列的唯一值。这是我的做法:

import pandas as pd
df = pd.DataFrame({'A':[1,1,3,2,6,2,8]})
a = df['A'].unique()
print a.sort()

问题在于我得到的输出是 None


7
a.sort() 会修改 a 的值并且不返回任何结果,因此可以替换为:a.sort(); print a - stellasia
注意:unique()返回一个numpy.ndarray,因此sort()实际上是numpy.ndarray.sort()方法。这就是为什么行为出乎意料的原因。drop_duplicates()返回一个pandas系列或数据帧,允许使用sort_values() - wisbucky
9个回答

369

sorted(iterable):返回一个由 iterable 中的项排序后组成的新列表。

CODE

import pandas as pd
df = pd.DataFrame({'A':[1,1,3,2,6,2,8]})
a = df['A'].unique()
print(sorted(a))

输出

[1, 2, 3, 6, 8]

1
如果你的列中包含具有模糊布尔值的数据,例如 pandas 的 NAType,那么这种方法就无法正常工作 - 使用 sorted() 将会引发 TypeError 错误。 - Elliot Young

46

sort 方法会原地排序并不返回任何内容:

In [54]:
df = pd.DataFrame({'A':[1,1,3,2,6,2,8]})
a = df['A'].unique()
a.sort()
a

Out[54]:
array([1, 2, 3, 6, 8], dtype=int64)

在调用sort之后,您需要再次调用print a

例如:

In [55]:
df = pd.DataFrame({'A':[1,1,3,2,6,2,8]})
a = df['A'].unique()
a.sort()
print(a)

[1 2 3 6 8]

原因是unique()返回一个numpy.ndarray,所以sort()实际上是numpy.ndarray.sort()方法。这就是为什么行为出乎意料。drop_duplicates()返回一个pandas系列或数据框,允许使用sort_values() - wisbucky

35
您还可以使用 drop_duplicates() 代替 unique()。
df = pd.DataFrame({'A':[1,1,3,2,6,2,8]})
a = df['A'].drop_duplicates()
a.sort()
print a

13
在一个包含14107693行的数据框中,使用Pandas 0.18版本,发现drop_duplicates()unique()快3倍。 - fixxxer
11
df['A'].drop_duplicates().sort_values() 是我最喜欢的代码。 - GitHunter0

19
更快的代码
对于大型数据框:
df['A'].drop_duplicates().sort_values()

9
如果您提供所述声明的证据,这个答案会更有趣。 - saQuist
3
drop_duplicates()unique()更好,因为它可以处理多列(数据框),而不仅仅是单列(序列)。 - wisbucky
不是最快的代码。试试sorted(df.A.unique())。它比df.A.sort_values().unique()好,但肯定不是最快的代码。 - undefined

15
今天我自己也遇到了这个问题。 我认为你的代码返回“None”(正是我使用相同方法得到的)的原因是:
a.sort()

调用排序函数来改变列表 a 的值。在我的理解中,这是一条修改命令。要查看结果,您需要使用print(a)。

我的解决方案是尝试让所有东西都保留在Pandas中:

pd.Series(df['A'].unique()).sort_values()

我喜欢 pandas 的解决方案,因为它将 NaN 值放置在末尾,并且可以处理混合类型的数组。 - m13op22

14

我更喜欢一行代码:

print(sorted(df['Column Name'].unique()))

7
我建议使用numpy的排序功能,因为这正是pandas在后台所做的:
import numpy as np
np.sort(df.A.unique())

但是在pandas中完成所有操作也是有效的。


4

另一种方法是使用set数据类型。

Sets的一些特点:无序,可以包含不同的数据类型,集合中的元素不能重复,可变。

解决您的问题:

df = pd.DataFrame({'A':[1,1,3,2,6,2,8]})
sorted(set(df.A))

List类型的答案:

[1, 2, 3, 6, 8]

1

很惊讶没有人提出这个建议:

df['A'].sort_values().unique()

1
好的,是的,这个方法可以运行,但是先对整个数组进行排序而不是在缩小的集合上进行排序是没有意义的。这就是为什么其他答案都会先使用“set”->“sort”的原因。 - tdy
哦,是的,它并不像效率那样高。看起来更清晰,但运行效果不如以前好。 - russhoppa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接