使用Pandas groupby连接来自几行的字符串

我想合并几个字符串在一个数据框架基于groupedby在Pandas。

这是我目前为止的代码:

import pandas as pd
from io import StringIO


data = StringIO("""
"name1","hej","2014-11-01"
"name1","du","2014-11-02"
"name1","aj","2014-12-01"
"name1","oj","2014-12-02"
"name2","fin","2014-11-01"
"name2","katt","2014-11-02"
"name2","mycket","2014-12-01"
"name2","lite","2014-12-01"
""")


# load string as stream into dataframe
df = pd.read_csv(data,header=0, names=["name","text","date"],parse_dates=[2])


# add column with month
df["month"] = df["date"].apply(lambda x: x.month)

我希望最终的结果是这样的:

enter image description here

我不明白我如何可以使用groupby,并在“文本”列中应用字符串的某种连接。感谢任何帮助!

255148 次浏览

你可以根据'name''month'列进行分组,然后调用transform,它将返回与原始df对齐的数据,并应用一个lambda,其中我们join文本项:

In [119]:


df['text'] = df[['name','text','month']].groupby(['name','month'])['text'].transform(lambda x: ','.join(x))
df[['name','text','month']].drop_duplicates()
Out[119]:
name         text  month
0  name1       hej,du     11
2  name1        aj,oj     12
4  name2     fin,katt     11
6  name2  mycket,lite     12

我通过传递感兴趣的列的列表df[['name','text','month']]来代替原来的df,然后调用drop_duplicates

编辑实际上我可以调用apply,然后调用reset_index:

In [124]:


df.groupby(['name','month'])['text'].apply(lambda x: ','.join(x)).reset_index()


Out[124]:
name  month         text
0  name1     11       hej,du
1  name1     12        aj,oj
2  name2     11     fin,katt
3  name2     12  mycket,lite

更新

lambda在这里是不必要的:

In[38]:
df.groupby(['name','month'])['text'].apply(','.join).reset_index()


Out[38]:
name  month         text
0  name1     11           du
1  name1     12        aj,oj
2  name2     11     fin,katt
3  name2     12  mycket,lite

EdChum的答案为你提供了很大的灵活性,但如果你只是想将字符串连接到列表对象的列中,你也可以:

output_series = df.groupby(['name','month'])['text'].apply(list)

对我来说,上面的解决方案很接近,但添加了一些不需要的/n'sdtype:object,所以这里是一个修改版本:

df.groupby(['name', 'month'])['text'].apply(lambda text: ''.join(text.to_string(index=False))).str.replace('(\\n)', '').reset_index()

我们可以groupby 'name'和'month'列,然后调用Panda的DataFrame对象的agg()函数。

agg()函数提供的聚合功能允许在一次计算中计算每个组的多个统计信息。

df.groupby(['name', 'month'], as_index = False).agg({'text': ' '.join})

enter image description here

如果您想连接您的“文本”;在列表中:

df.groupby(['name', 'month'], as_index = False).agg({'text': list})

虽然,这是一个老问题。但以防万一。我使用下面的代码,它似乎工作像一个魅力。

text = ''.join(df[df['date'].dt.month==8]['text'])

请试试这行代码:-

df.groupby(['name','month'])['text'].apply(','.join).reset_index()

感谢所有其他的答案,下面的可能是最简洁的,感觉更自然。在一个或多个选定列上使用df.groupby("X")["A"].agg()聚合。

df = pandas.DataFrame({'A' : ['a', 'a', 'b', 'c', 'c'],
'B' : ['i', 'j', 'k', 'i', 'j'],
'X' : [1, 2, 2, 1, 3]})


A  B  X
a  i  1
a  j  2
b  k  2
c  i  1
c  j  3


df.groupby("X", as_index=False)["A"].agg(' '.join)


X    A
1  a c
2  a b
3    c


df.groupby("X", as_index=False)[["A", "B"]].agg(' '.join)


X    A    B
1  a c  i i
2  a b  j k
3    c    j