Pandas groupby:如何获得字符串的联合

2024-05-20 19:35:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个这样的数据框:

   A         B       C
0  1  0.749065    This
1  2  0.301084      is
2  3  0.463468       a
3  4  0.643961  random
4  1  0.866521  string
5  2  0.120737       !

呼叫

In [10]: print df.groupby("A")["B"].sum()

会回来的

A
1    1.615586
2    0.421821
3    0.463468
4    0.643961

现在我想对“C”列做“同样的”。因为该列包含字符串,sum()不起作用(尽管您可能认为它会连接字符串)。我真正想看到的是每个组的一个或一组字符串,即

A
1    {This, string}
2    {is, !}
3    {a}
4    {random}

我一直在想办法。

Series.unique()(http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.unique.html)不起作用,尽管

df.groupby("A")["B"]

是一个

pandas.core.groupby.SeriesGroupBy object

所以我希望任何系列方法都能奏效。有什么想法吗?


Tags: 数据字符串inpandasdfstringisrandom
3条回答

可以使用apply方法对分组数据应用任意函数。所以如果你想要一个集合,应用set。如果需要列表,请应用list

>>> d
   A       B
0  1    This
1  2      is
2  3       a
3  4  random
4  1  string
5  2       !
>>> d.groupby('A')['B'].apply(list)
A
1    [This, string]
2           [is, !]
3               [a]
4          [random]
dtype: object

如果你想要别的东西,只要写一个函数来做你想做的,然后apply

In [4]: df = read_csv(StringIO(data),sep='\s+')

In [5]: df
Out[5]: 
   A         B       C
0  1  0.749065    This
1  2  0.301084      is
2  3  0.463468       a
3  4  0.643961  random
4  1  0.866521  string
5  2  0.120737       !

In [6]: df.dtypes
Out[6]: 
A      int64
B    float64
C     object
dtype: object

应用自己的函数时,不会自动排除非数值列。不过,这比将.sum()应用于groupby要慢

In [8]: df.groupby('A').apply(lambda x: x.sum())
Out[8]: 
   A         B           C
A                         
1  2  1.615586  Thisstring
2  4  0.421821         is!
3  3  0.463468           a
4  4  0.643961      random

sum默认情况下连接

In [9]: df.groupby('A')['C'].apply(lambda x: x.sum())
Out[9]: 
A
1    Thisstring
2           is!
3             a
4        random
dtype: object

你想做什么就做什么

In [11]: df.groupby('A')['C'].apply(lambda x: "{%s}" % ', '.join(x))
Out[11]: 
A
1    {This, string}
2           {is, !}
3               {a}
4          {random}
dtype: object

在一个完整的框架上,一次一组地执行此操作。关键是返回一个Series

def f(x):
     return Series(dict(A = x['A'].sum(), 
                        B = x['B'].sum(), 
                        C = "{%s}" % ', '.join(x['C'])))

In [14]: df.groupby('A').apply(f)
Out[14]: 
   A         B               C
A                             
1  2  1.615586  {This, string}
2  4  0.421821         {is, !}
3  3  0.463468             {a}
4  4  0.643961        {random}

您可以使用aggregate(或agg)函数连接这些值。(未经测试的代码)

df.groupby('A')['B'].agg(lambda col: ''.join(col))

相关问题 更多 >