#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 очень впечатляет!