如何使用聚合方法从pandas系列中获取唯一值?

时间:2017-06-30 16:07:14

标签: python python-3.x pandas

考虑这个dataframe

df = pandas.DataFrame(numpy.random.randint(0,100,size=(200, 4)), columns=list('ABCD'))
df['E'] = list(numpy.arange(1001, 1021)) * 10
df['F'] = ['c', 'b', 'b', 'a', 'd'] * 20 + ['d', 'a', 'b', 'b', 'c'] * 20

我想按专栏分组' E'但我想汇总一些功能。例如,来自列A,B,D和sum列C的count值。使用列' F'我想在数组中获得唯一值。

所以我试过了:

params = {
  'A': 'sum',
  'B': 'sum',
  'C': 'count',
  'D': 'sum',
  'F': pandas.Series.unique
}
df_ = df.groupby('E').agg(params).reset_index()

返回错误:Exception: Must produce aggregated value

我尝试了这段代码,因为在另一个例子中它有效。从那时起,我一直在尝试使用相同的方法来过滤不同的数据,但没有结果。

如果我使用pandas.Series.nuniquelambda x: x.nunique(),它会计算唯一值并且可以正常使用。但是,如何使用pandas aggregate方法获取唯一值?

为了完成这项工作,我编写了一个带有for loop的函数,该函数将列名作为参数。但是,我希望这可以有更好的方法。

2 个答案:

答案 0 :(得分:4)

错误:

这是因为pandas.Series.unique返回唯一值的数组,agg将其解释为尝试将不同的值广播到不同的行,因此拒绝。您使用返回pandas SeriesIndex的函数会收到相同的错误。

解决方案:

如果您通过了稍后使用的功能pandas.Series.nunique

params = {
  'A': 'sum',
  'B': 'sum',
  'C': 'count',
  'D': 'sum',
  'F': pd.Series.nunique
}

df.groupby('E').agg(params).reset_index()
Out[69]: 
       E   C  F    A    B    D
0   1001  10  2  500  463  595
1   1002  10  2  484  493  348
2   1003  10  1  507  400  479
...
17  1018  10  1  606  454  410
18  1019  10  2  537  522  724
19  1020  10  2  541  532  486

它应该可以正常工作。

如果你想要自己的唯一值,你可以将lambda函数提供给agg,只要它将返回值识别为聚合值而不是SeriesIndexnp.ndarray或子类。

例如:

params = {
  'A': 'sum',
  'B': 'sum',
  'C': 'count',
  'D': 'sum',
  'F': lambda x: ','.join(sorted(pd.Series.unique(x)))
}

df.groupby('E').agg(params).reset_index()
Out[82]: 
       E   C    F    A    B    D
0   1001  10  c,d  500  463  595
1   1002  10  a,b  484  493  348
2   1003  10    b  507  400  479
...
17  1018  10    b  606  454  410
18  1019  10  a,b  537  522  724
19  1020  10  c,d  541  532  486

或者,有点傻:

params = {
  'A': 'sum',
  'B': 'sum',
  'C': 'count',
  'D': 'sum',
  'F': lambda x: pd.DataFrame(pd.Series.unique(x))
}

df.groupby('E').agg(params).reset_index()
Out[92]: 
       E   C     F    A    B    D
0   1001  10     0
              0  c
              1  d  500  463  595
1   1002  10     0
              0  b
              1  a  484  493  348
2   1003  10     0
              0  b  507  400  479
...
17  1018  10     0
              0  b  606  454  410
18  1019  10     0
              0  a
              1  b  537  522  724
19  1020  10     0
              0  d
              1  c  541  532  486

答案 1 :(得分:2)

只需更改sp_who2'F'的功能:

params