按组计算每列的唯一值数量

9
考虑以下数据框:
      A      B  E
0   bar    one  1
1   bar  three  1
2  flux    six  1
3  flux  three  2
4   foo   five  2
5   foo    one  1
6   foo    two  1
7   foo    two  2

我希望能够找到每个 A 值对应的其他列中独一无二的值的数量。

  1. I thought the following would do it:

    df.groupby('A').apply(lambda x: x.nunique())
    

    but I get an error:

    AttributeError: 'DataFrame' object has no attribute 'nunique'
    
  2. I also tried with:

    df.groupby('A').nunique()
    

    but I also got the error:

    AttributeError: 'DataFrameGroupBy' object has no attribute 'nunique'
    
  3. Finally I tried with:

    df.groupby('A').apply(lambda x: x.apply(lambda y: y.nunique()))
    

    which returns:

          A  B  E
    A            
    bar   1  2  1
    flux  1  2  2
    foo   1  3  2
    

    and seems to be correct. Strangely though, it also returns the column A in the result. Why?


1
就我个人而言,你的第三种方法对我有效(对于“E”列,我得到了“2 1 1”),这也是我会建议的方法。 - DSM
2个回答

12

DataFrame对象没有nunique,只有Series有。您必须选择要在哪一列上应用nunique()。您可以使用简单的点运算符来完成这个操作:

df.groupby('A').apply(lambda x: x.B.nunique())

会打印:

A
bar     2
flux    2
foo     3

并执行:

df.groupby('A').apply(lambda x: x.E.nunique())

将会打印:

A
bar     1
flux    2
foo     2

您也可以使用一个函数调用来完成此操作:

df.groupby('A').aggregate({'B': lambda x: x.nunique(), 'E': lambda x: x.nunique()})

将会打印出:

      B  E
A
bar   2  1
flux  2  2
foo   3  2
为了回答你关于为什么递归lambda函数也打印出"A"列的问题,这是因为当你进行groupby/apply操作时,你现在正在遍历三个DataFrame对象。每个DataFrame对象都是原始DataFrame的子DataFrame。对其应用操作将应用于每个Series。你正在对应用nunique()运算符的每个DataFrame上执行三个Series。
在每个DataFrame上评估的第一个Series是A Series,并且由于你对A进行了groupby,所以你知道在每个DataFrame中,A Series只有一个唯一值。这就解释了为什么最终会给出一个A结果列,其中包含所有的1。

谢谢 - 我本来希望避免遍历数据框,但可能没有其他选择。 - Amelio Vazquez-Reina

3

我遇到了同样的问题。 将pandas升级到最新版本后,该问题得到了解决。

df.groupby('A').nunique()

在Pandas 0.19.2版本中,上述代码无法正常工作。我将其升级到了Pandas 0.21.1版本,然后它就可以运行了。

您可以使用以下代码检查版本:

print('Pandas version ' + pd.__version__)

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