pandasgroupby:如何得到string的联合

我有这样的数据框:

ABC 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”列做同样的事情。 由于该列包含string,sum()不起作用(尽pipe您可能认为它会连接string)。 我真正想看到的是每个组的一个或一组string,即

 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 

所以我希望任何Series方法都可以工作。 有任何想法吗?

 In [4]: df = read_csv(StringIO(data),sep='\s+') In [5]: df Out[5]: ABC 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 

当您应用自己的function时,不会自动排除非数字列。 但是,这比向groupby应用.sum()要慢

 In [8]: df.groupby('A').apply(lambda x: x.sum()) Out[8]: ABC 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]: ABC A 1 2 1.615586 {This, string} 2 4 0.421821 {is, !} 3 3 0.463468 {a} 4 4 0.643961 {random} 

您可以使用apply方法将任意函数应用于分组数据。 所以,如果你想要一套,套用。 如果你想要一个列表,应用list

 >>> d AB 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 

如果你想要别的东西,只要写一个你想要的function,然后apply它。

您可以使用aggregate (或agg )函数来连接值。 (未经testing的代码)

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

一个简单的解决scheme是:

 >>> df.groupby(['A','B']).c.unique().reset_index()