Pandas groupby - 一组不同的值

Bar*_*ich 4 python dataframe pandas pandas-groupby

我有这个数据框

x = pd.DataFrame.from_dict({'cat1':['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C'], 'cat2':['X', 'X', 'Y', 'Y', 'Y', 'Y', 'Z', 'Z']})

  cat1 cat2
0    A    X
1    A    X
2    A    Y
3    B    Y
4    B    Y
5    C    Y
6    C    Z
7    C    Z
Run Code Online (Sandbox Code Playgroud)

我想分组cat1,然后聚合cat2为不同值的集合,例如

  cat1 cat2
0    A    (X, Y)
1    B    (Y,)
2    C    (Y, Z)
Run Code Online (Sandbox Code Playgroud)

这是具有更多列的更大数据框的一部分,每个列都有自己的聚合函数,那么如何将此功能传递给聚合字典?

jez*_*ael 5

将 lambda 函数与setor 一起使用unique,还将输出转换为tuples:

x = pd.DataFrame.from_dict({'cat1':['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C'], 
                            'cat2':['X', 'X', 'Y', 'Y', 'Y', 'Y', 'Z', 'Z'],
                             'col':range(8)})
print (x)
  cat1 cat2  col
0    A    X    0
1    A    X    1
2    A    Y    2
3    B    Y    3
4    B    Y    4
5    C    Y    5
6    C    Z    6
7    C    Z    7

a = x.groupby('cat1').agg({'cat2': lambda x: tuple(set(x)), 'col':'sum'})
print (a)
        cat2  col
cat1             
A     (Y, X)    3
B       (Y,)    7
C     (Y, Z)   18
Run Code Online (Sandbox Code Playgroud)

或者:

a = x.groupby('cat1').agg({'cat2': lambda x: tuple(x.unique()), 'col':'sum'})
print (a)
        cat2  col
cat1             
A     (X, Y)    3
B       (Y,)    7
C     (Y, Z)   18
Run Code Online (Sandbox Code Playgroud)

编辑:

f = lambda x: tuple(x.unique())
f.__name__ = 'my_name'
a = x.groupby('cat1')['cat2'].agg(['min', 'max', 'nunique', f])
print (a)
     min max  nunique my_name
cat1                         
A      X   Y        2  (X, Y)
B      Y   Y        1    (Y,)
C      Y   Z        2  (Y, Z)
Run Code Online (Sandbox Code Playgroud)

如果只有一个lambda函数或列名没有问题<lambda>

a = x.groupby('cat1')['cat2'].agg(['min', 'max', 'nunique', lambda x: tuple(x.unique())])
print (a)
     min max  nunique <lambda>
cat1                          
A      X   Y        2   (X, Y)
B      Y   Y        1     (Y,)
C      Y   Z        2   (Y, Z)
Run Code Online (Sandbox Code Playgroud)