Группируйтесь и присоединяйтесь в фрейме данных pandas для строкового столбца с символом новой строки

#python #pandas #dataframe #pandas-groupby

Вопрос:

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

Я могу сделать это с помощью кода df_new= df.groupby(['Category'], as_index=False).agg(' '.join) . Пожалуйста, смотрите измененный фрейм данных в качестве вывода этого кода.

Я пробовал использовать различные комбинации "n".join , но это не сработало должным образом.

Оригинал:

     df.head()
    Name    Last    Loc     Category        
    [1]Tabby    buy     NJ      A
    [2]Tabby    buy     JP      B
    [3]Tabby    buy     JP      A
    [4]Tabby    sell    NJ      B
 

Модифицированный:

     df.head()
    Name                Last        Loc     Category        
    [1]Tabby [3]Tabby   buy buy     NJ      A
    [2]Tabby [4]Tabby   buy sell    JP      B
 

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

Ожидаемый:

     df.head()
    Name        Last        Loc     Category        
    [1]Tabby    buy buy     NJ      A
    [3]Tabby
    [2]Tabby    buy sell    JP      B
    [4]Tabby
 

Есть ли способ это сделать?

Ответ №1:

Вы не можете выполнить то, что хотите, без новых индексированных строк (поэтому «n » не работает в фрейме данных).

Более простое решение:

 df = df.sort_values('Category')
df['Last'] = df.groupby('Category')['Last'].transform(' '.join)
df.loc[df.duplicated('Category'), df.columns != 'Name'] = ''
 
 >>> df
       Name      Last Loc Category
0  [1]Tabby   buy buy  NJ        A
2  [3]Tabby
1  [2]Tabby  buy sell  JP        B
3  [4]Tabby
 
 >>> print(df.to_string(index=False))

    Name     Last Loc Category
[1]Tabby  buy buy  NJ        A
[3]Tabby
[2]Tabby buy sell  JP        B
[4]Tabby
 

Старый ответ

Альтернативой может быть:

 out = df.groupby('Category', as_index=False) 
        .agg({'Name': list, 'Last': ' '.join, 'Loc': 'first'}) 
        .explode('Name')
 

На этом этапе вывод будет:

 >>> out
  Category      Name      Last Loc
0        A  [1]Tabby   buy buy  NJ
0        A  [3]Tabby   buy buy  NJ
1        B  [2]Tabby  buy sell  JP
1        B  [4]Tabby  buy sell  JP
 

Теперь вы можете использовать .loc для удаления дополнительного контента:

 out.loc[out.duplicated('Category'), out.columns != 'Name'] = ''
out = out[df.columns]
 

Конечный результат:

 >>> out
       Name      Last Loc Category
0  [1]Tabby   buy buy  NJ        A
0  [3]Tabby
1  [2]Tabby  buy sell  JP        B
1  [4]Tabby
 

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

1. Спасибо. Я действительно искал что-то, что не будет создавать новые индексированные строки, но если это невозможно сделать, то ваше решение работает так, как показано. Ценю ваш ответ.

2. Я обновил свой ответ. Не забудьте принять мой ответ, если это соответствует вашим потребностям (хотя это не то, что вы ожидали сначала) 🙂