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

est*_*pdl 2 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
Run Code Online (Sandbox Code Playgroud)

我想按列 'E' 分组,但我想聚合一些函数。例如sum来自 A、B、Dcount列和C 列的值。对于列“F”,我想在数组中获取唯一值。

所以我试过:

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

返回错误: Exception: Must produce aggregated value

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

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

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

WeN*_*Ben 7

'F'只需更改in的功能params

params = {
  'A': 'sum',
  'B': 'sum',
  'C': 'count',
  'D': 'sum',
  'F': (lambda x: list(x.unique()))
}
df_ = df.groupby('E').agg(params).reset_index()
Run Code Online (Sandbox Code Playgroud)


EFT*_*EFT 5

错误:

发生这种情况是因为pandas.Series.unique返回唯一值的数组,这agg解释为尝试将不同的值广播到不同的行,因此拒绝。使用返回 pandasSeriesIndex.

解决方案:

如果传递以后使用的函数,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
Run Code Online (Sandbox Code Playgroud)

它应该可以正常工作。

如果你想自己独特的价值观,可以养活一个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
Run Code Online (Sandbox Code Playgroud)

或者,有点傻:

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
Run Code Online (Sandbox Code Playgroud)