166

我想根据 Pandas 中的 groupedby 合并数据框中的几个字符串。

到目前为止,这是我的代码:

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)

我希望最终结果如下所示:

在此处输入图像描述

我不明白如何使用 groupby 并在“文本”列中应用某种字符串连接。任何帮助表示赞赏!

4

7 回答 7

267

您可以按'name''month'列分组,然后调用transform它将返回与原始 df 对齐的数据并在我们join的文本条目中应用 lambda:

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,df[['name','text','month']]然后调用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
于 2014-12-04T15:54:19.520 回答
88

我们可以按“名称”和“月份”列分组,然后调用Panda 的DataFrame对象的函数。agg()

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

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

在此处输入图像描述

于 2019-12-11T10:48:40.930 回答
43

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

output_series = df.groupby(['name','month'])['text'].apply(list)
于 2017-08-28T19:18:24.227 回答
12

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

df.groupby(['name', 'month'], as_index = False).agg({'text': list})
于 2020-11-25T14:46:15.340 回答
10

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

df.groupby(['name', 'month'])['text'].apply(lambda text: ''.join(text.to_string(index=False))).str.replace('(\\n)', '').reset_index()
于 2018-06-28T15:00:16.840 回答
3

请尝试这行代码:-

df.groupby(['name','month'])['text'].apply(','.join).reset_index()
于 2021-10-28T10:17:32.857 回答
2

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

text = ''.join(df[df['date'].dt.month==8]['text'])
于 2021-03-30T10:12:06.990 回答