Сгруппируйте по столбцам и соедините значения строк еще двух столбцов

#python #python-3.x #pandas

Вопрос:

Я пытаюсь сгруппировать данные по всем столбцам в моем фрейме данных, за исключением 2.

В приведенном ниже примере я пытаюсь сгруппировать по col1 и col2

Для col3 , где col1 amp; col2 значения совпадают, соедините col3 значения с помощью ; . Ибо col4 сделайте то же самое, ожидайте, что вы присоединитесь к n

Надеюсь, основной пример дает лучший пример того, что я пытаюсь сделать.

Текущий Кадр Данных:

 col1  col2    col3   col4
001   time    yes    working
001   time    no     resting
002   time    no     flying
003   hours   yes    flying
002   time    no     flying
003   lights  no     flying
 

Чего я хочу:

  col1  col2   col3      col4
 001   time   yes ; no  working n resting
 002   time   no ; no   flying n walking
 003   hours  yes       flying
 003   lights  no     flying
 

Ниже, по-видимому, работает для каждого столбца ( col3 и col4 ). Но я не уверен, какой код мне нужен для того, чтобы это работало для обоих столбцов, чтобы получить желаемый результат.

 cols = ['col1', 'col2']
new_df = df.groupby(cols)['col3'].apply(lambda x: ';'.join(x)).reset_index()

cols = ['col1', 'col2']
new_df = df.groupby(cols)['col4'].apply(lambda x: 'n'.join(x)).reset_index()
 

Комментарии:

1. Вы ищете .agg вместо того, чтобы подать заявку

Ответ №1:

Используйте DataFrame.drop_duplicates (при необходимости) с GroupBy.agg :

 cols = ['col1', 'col2']
cols1 = ['col3','col4']
new_df = df.drop_duplicates(cols cols1).groupby(cols)[cols1].agg('n'.join).reset_index()
print (new_df)
  col1    col2       col3                col4
0  001    time  no n yes  working n resting
1  002    time         no              flying
2  003   hours        yes              flying
3  003  lights         no              flying
 

Или используйте set s для уникальных значений для каждого столбца отдельно:

 cols = ['col1', 'col2']
cols1 = ['col3','col4']
new_df = df.groupby(cols)[cols1].agg(lambda x: 'n'.join(set(x))).reset_index()
print (new_df)
  col1    col2       col3                col4
0  001    time  no n yes  working n resting
1  002    time         no              flying
2  003   hours        yes              flying
3  003  lights         no              flying
 

Комментарии:

1. Спасибо. Это работает. Хотя я надеялся, что будет способ использовать n в качестве разделителя для col4 вместо ; . Не могли бы вы также объяснить, почему agg это работает, а не apply нет ?

2. @AaronWright — Потому groupby.agg что работа с каждым столбцом отдельно

Ответ №2:

сводная таблица также может быть опцией

 df.pivot_table(index=["col1","col2"],values=["col3","col4"],aggfunc={"col3":lambda x:" ; ".join(x.astype(str)),
                                                                    "col4":lambda x:" n ".join(x.astype(str))}).reset_index()
 

выход:

     col1    col2    col3        col4
0   001     time    yes ; no    working n resting
1   002     time    no ; no     flying n flying
2   003     hours   yes         flying
3   003     lights  no          flying