Pandas groupby kullanarak birkaç satırdaki dizeleri birleştirin


92

Pandas'ta groupedby'yi temel alan bir veri çerçevesindeki birkaç dizeyi birleştirmek istiyorum.

Şimdiye kadarki kodum bu:

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)

Son sonucun şöyle görünmesini istiyorum:

görüntü açıklamasını buraya girin

Groupby'yi nasıl kullanabileceğimi ve "metin" sütunundaki dizelerin bir tür birleştirmesini nasıl uygulayabileceğimi anlamıyorum. Herhangi bir yardım için minnettarız!

Yanıtlar:


159

'name'Ve 'month'sütunlarına göre gruplandırabilir , ardından transformorijinal df'ye hizalanmış verileri döndürecek joinve metin girişlerinin olduğu yerde bir lambda uygulayabilirsiniz :

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

Buraya ilgi sütunlarının bir listesini ileterek orijinal df'yi alıyorum df[['name','text','month']]ve sonradrop_duplicates

DÜZENLE aslında arayabilirim applyve sonra 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

Güncelleme

lambdaBurada gereksizdir:

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
İçinde pandas < 1.0, .drop_duplicates()beklenmedik sonuçlar verebilecek dizini yok sayar. Sen kullanarak bu sorunun üstesinden gelebilirsiniz .agg(lambda x: ','.join(x))yerine .transform().drop_duplicates().
Matthias Fripp

Düzgün ve basit. Aynı zamanda son derece esnek
Raghavan vmvs

drop_duplicates()parametreyi dahil etmezseniz drop_duplicates(inplace=True)veya kod satırını şu şekilde yeniden df = df[['name','text','month']].drop_duplicates()
yazarsanız çalışmayabilir

44

biz olabilir GroupBy , ismini 've 'ay' sütunları sonra) (Panda'nın DataFrame nesneleri fonksiyonlarını agg diyoruz.

Agg () işlevi tarafından sağlanan toplama işlevi, tek bir hesaplamada grup başına birden çok istatistiğin hesaplanmasına izin verir.

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

görüntü açıklamasını buraya girin


27

EdChum'un cevabı size çok fazla esneklik sağlar, ancak dizeleri bir liste nesnesi sütununda birleştirmek istiyorsanız, şunları da yapabilirsiniz:

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


Dostum, bana çok zaman kazandırdın. Teşekkür ederim. Bu, kayıtların / kullanıcı kimliklerinin kronolojik listelerini bildiğim 'kohortlar' halinde bir araya getirmenin en iyi yoludur. Tekrar teşekkürler.
Alex Fedotov

5

Benim için yukarıdaki çözümler yakındı ancak bazı istenmeyen / n'ler ve dtype: object ekledi, işte değiştirilmiş bir sürüm:

df.groupby(['name', 'month'])['text'].apply(lambda text: ''.join(text.to_string(index=False))).str.replace('(\\n)', '').reset_index()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.