Как сгруппировать по значению фрейма данных?

#python #pandas #pivot-table #pandas-groupby

#python #pandas #группировать по #сводная таблица

Вопрос:

У меня есть эти 2 df, которые в основном одинаковы, но в df1 значения представляют собой сумму платежа соответствующего клиента, а другое — статус клиентов за этот период (столбцы 1,2,3,4 являются периодами):

df1:

 customer|1|2|3|4
x       |2|5|5|5
y       | |5|5|5
z       |5|5|5|
  

df2:

 customer|1|2|3|4
x       |N|E|E|E
y       | |N|E|E
z       |N|E|C|-
  

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

 Status  1 |2 |3 |4
N        7|5 |  |
E         |10|10|10
C         |  |5 |
  

Раньше я группировал количество статусов с помощью

 df2.apply(pd.value_counts).fillna(0)
  

но теперь, вместо count значений, я хочу SUM значение соответствующего фрейма данных DF1

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

1. Можете ли вы изменить генерацию данных, чтобы я мог убедиться, что понимаю фрейм данных? Я не уверен, почему у вас отсутствуют значения и ‘-‘ в ваших данных. Предполагается, что это NaNs? Представляет ли следующее: df1 = pandas.DataFrame({1:[2,0,5], 2:[5,5,5], 3:[5,5,5], 4:[5,5,0]}, index=['x', 'y', 'z']) фрейм данных, над которым вы работаете?

2. Я вижу сводные таблицы. Есть ли способ поделиться исходной таблицей, которую вы использовали?

3. пустые пробелы и ‘-‘ равны NaN . на самом деле это не представляет. это всего лишь пример

4. один из примеров этих 2 фреймов данных i.imgur.com/R1L9L0A.png

5. У вас есть ваши данные в jupyter notebook . Пожалуйста, сделайте print(df1.head(10)) amp; print(df2.head(10)) и скопируйте, вставьте выходные данные этого в свой вопрос. Этот вывод можно скопировать для нас, и мы можем использовать его, чтобы ответить на ваш вопрос. Спасибо

Ответ №1:

Как это часто бывает, это кажется сложным, потому что ваши фреймы данных имеют странную форму. Если вы сначала melt их, это становится простым: просто merge их, groupby интересующие вас величины и суммируйте их (и pivot еще раз, если вы хотите отобразить это в этом формате):

 df1m = df1.melt(id_vars='customer', var_name='period', value_name='amount')
df2m = df2.melt(id_vars='customer', var_name='period', value_name='status')
dfm = df1m.merge(df2m)
res = dfm.groupby(['status', 'period'])['amount'].sum().reset_index()
res.pivot_table(index='status', columns='period')

#period      1     2     3     4
#status                         
#C         NaN   NaN   5.0   NaN
#E         NaN  10.0  10.0  10.0
#N         7.0   5.0   NaN   NaN
  

Чтобы показать, что делает melt: он отключает фрейм данных, поэтому у вас есть одна строка для каждого наблюдения (клиент, период), которая имеет сумму / статус

 df1m
#    customer period  amount
#0   x             1     2.0
#1   y             1     NaN
#2   z             1     5.0
#3   x             2     5.0
#4   y             2     5.0
#5   z             2     5.0
#6   x             3     5.0
#7   y             3     5.0
#8   z             3     5.0
#9   x             4     5.0
#10  y             4     5.0
11  z             4     NaN
  

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

1. Я знаю, это странно, но он идеально подходил для той цели, которую я использовал — группировать по количеству, и теперь я пытаюсь использовать это повторно, и я также и все еще думаю, что это лучше, чем исходная база данных

2. Конечно, это хорошо для визуализации. Однако при манипулировании часто возникает необходимость использовать аккуратные данные: vita.had.co.nz/papers/tidy-data.pdf . В любом случае, надеюсь, это помогло

3. но удивительно, я не знал, что метод melt очень впечатляет!