Объедините строки из нескольких строк с помощью Pandas groupby

92

Я хочу объединить несколько строк в фрейм данных на основе 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)

Я хочу, чтобы конечный результат выглядел так:

введите описание изображения здесь

Я не понимаю, как я могу использовать groupby и применить какую-то конкатенацию строк в столбце «текст». Любая помощь приветствуется!

Mattiasostmar
источник

Ответы:

159

Вы можете GroupBy 'name'и 'month'столбцы, а затем вызвать , transformкоторый будет возвращать данные , выровненные к исходному ФРУ и применить лямбда , где мы 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, передавая здесь список интересующих столбцов, 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
EdChum
источник
1
В pandas < 1.0, .drop_duplicates()игнорирует индекс, который может дать неожиданные результаты. Вы можете избежать этого, используя .agg(lambda x: ','.join(x))вместо .transform().drop_duplicates().
Маттиас Фрипп
Аккуратно и незамысловато. В высшей степени изменчивый
Raghavan vmvs
drop_duplicates()может не работать, если вы не drop_duplicates(inplace=True)df = df[['name','text','month']].drop_duplicates()
включите
44

мы можем сгруппировать по столбцам «имя» и «месяц», а затем вызвать функции agg () объектов DataFrame Panda.

Функциональность агрегирования, предоставляемая функцией agg (), позволяет рассчитывать несколько статистических данных для каждой группы за один расчет.

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

введите описание изображения здесь

Рам Праджапати
источник
27

Ответ EdChum предоставляет вам большую гибкость, но если вы просто хотите объединить строки в столбец объектов списка, вы также можете:

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

Рутгер Хофсте
источник
Чувак, ты только что сэкономил мне много времени. Спасибо. Это лучший способ собрать хронологические списки регистраций / идентификаторов пользователей в известные мне «когорты». Спасибо еще раз.
Алексей Федотов
5

Для меня вышеупомянутые решения были близки, но добавили некоторые нежелательные объекты / n и dtype:, поэтому вот модифицированная версия:

df.groupby(['name', 'month'])['text'].apply(lambda text: ''.join(text.to_string(index=False))).str.replace('(\\n)', '').reset_index()
Ник Скоццаро
источник