Pandas groupbyを使用して、複数の行の文字列を連結します


99

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を使用して、「text」列の文字列を何らかの連結で適用する方法がわかりません。助けていただければ幸いです。

回答:


176

'name''month'列でグループ化してから呼び出すtransformと、元のdfに揃えられたデータが返され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

1
ではpandas < 1.0.drop_duplicates()インデックスを無視します。これにより、予期しない結果が生じる可能性があります。の.agg(lambda x: ','.join(x))代わりにを使用すると、これを回避でき.transform().drop_duplicates()ます。
マティアスフリップ

きちんとしていて複雑ではありません。非常に柔軟でもあります
Raghavanvmvs20年

drop_duplicates()パラメータを含めないdrop_duplicates(inplace=True)か、コード行を次のように書き直すと、機能 しない可能性がありますdf = df[['name','text','month']].drop_duplicates()
IAmBotmaker 2010

48

我々はできるGROUPBY、「名前」と「月」の列が続い)(パンダのデータフレームは、オブジェクトの機能をAGG呼び出します。

agg()関数によって提供される集計機能により、1回の計算でグループごとに複数の統計を計算できます。

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

ここに画像の説明を入力してください


28

EdChumによる回答は、多くの柔軟性を提供しますが、文字列をリストオブジェクトの列に連結するだけの場合は、次のこともできます。

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


男、あなたは私に多くの時間を節約してくれました。ありがとうございました。これは、登録/ユーザーIDの時系列リストを私が知っている「コホート」にまとめる最良の方法です。改めてありがとうございました。
AlexFedotov20年

6

私にとって、上記の解決策は近いものでしたが、いくつかの不要な/ nとdtype:objectが追加されたため、変更されたバージョンは次のとおりです。

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

-1

リスト内の「テキスト」を連結する場合:

df.groupby(['name', 'month'], as_index = False).agg({'text': list})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.