Je veux fusionner plusieurs chaînes dans une trame de données basée sur un groupé par dans Pandas.
Voici mon code jusqu'à présent:
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)
Je veux que le résultat final ressemble à ceci:
Je ne sais pas comment utiliser groupby et appliquer une sorte de concaténation des chaînes dans la colonne "texte". Toute aide appréciée!
Vous pouvez grouper par 'name'
et 'month'
colonnes, puis appelez transform
qui renverra des données alignées sur le df d'origine et appliquera un lambda où nous join
les entrées de texte:
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
Je soumets le df d'origine en passant une liste des colonnes d'intérêt df[['name','text','month']]
ici puis appelez drop_duplicates
MODIFIER en fait, je peux simplement appeler apply
puis 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
mise à jour
le lambda
n'est pas nécessaire ici:
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
La réponse d'EdChum vous offre beaucoup de flexibilité, mais si vous souhaitez simplement concaténer des chaînes dans une colonne d'objets de liste, vous pouvez également:
output_series = df.groupby(['name','month'])['text'].apply(list)
Pour moi, les solutions ci-dessus étaient proches mais ont ajouté des/n et un dtype: object indésirables, voici donc une version modifiée:
df.groupby(['name', 'month'])['text'].apply(lambda text: ''.join(text.to_string(index=False))).str.replace('(\\n)', '').reset_index()