#pandas #dataframe
Вопрос:
city sale_date sale1 sale2 sale3
city1 2020/07/08 100 200 300
city1 2020/07/09 200 300 400
city2 2020/07/08 111 222 333
...
Я хочу получить кадр данных ниже
2020/07/08 2020/07/09 ...
city1 sale1 100 200
sale2 200 300
sale3 300 400
city2 sale1 111 NaN
sale2 222 NaN
sale3 333 NaN
Я пытался использовать pd.pivot, но в нем просто несколько повторяющихся столбцов по датам
Если я повернусь 3 раза, а затем сложу/соединим их
sale1_df = df.pivot(index='city',columns='sale_date',values='sale1')
sale2_df = df.pivot(index='city',columns='sale_date',values='sale2')
sale3_df = df.pivot(index='city',columns='sale_date',values='sale3')
Это может сработать после сортировки. но есть ли более простой способ достичь этого?
Я не могу представить,если у вас больше продаж (например: sale4, sale5,…)
Ответ №1:
Вы можете сделать это, сначала используя df.melt()
, а затем df.pivot_table()
.
Melt()
делает что-то вроде разворота, и таким образом это перевернет вашу продажу 1, продажу 2… в строки вместо столбцов. Тогда pivot_table()
ваша «дата продажи» превратится в столбцы вместо строк.
df2 = df.melt(id_vars=['city','sale_date'])
df2
city sale_date variable value
0 city1 2020/07/08 sale1 100
1 city1 2020/07/09 sale1 200
2 city2 2020/07/08 sale1 111
3 city1 2020/07/08 sale2 200
4 city1 2020/07/09 sale2 300
5 city2 2020/07/08 sale2 222
6 city1 2020/07/08 sale3 300
7 city1 2020/07/09 sale3 400
8 city2 2020/07/08 sale3 333
Вы можете задать имена столбцов для «переменной» и «значения» в соответствии с документацией здесь — https://pandas.pydata.org/docs/reference/api/pandas.melt.html
Тогда вы можете pivot_table()
на этом
df2.pivot_table(index=['city','variable'],columns='sale_date',values='value')
sale_date 2020/07/08 2020/07/09
city variable
city1 sale1 100.0 200.0
sale2 200.0 300.0
sale3 300.0 400.0
city2 sale1 111.0 NaN
sale2 222.0 NaN
sale3 333.0 NaN
Ответ №2:
Установите индекс, стек и распакуйте по имени столбца, в котором вам нужны значения, вырожденные в столбцы
df.set_index(['city', 'sale_date']).stack().unstack('sale_date').reset_index().rename(columns={'level_1': 'sale_type'})
sale_date city sale_type 2020/07/08 2020/07/09
0 city1 sale1 100.0 200.0
1 city1 sale2 200.0 300.0
2 city1 sale3 300.0 400.0
3 city2 sale1 111.0 NaN
4 city2 sale2 222.0 NaN
5 city2 sale3 333.0 NaN
Ответ №3:
Добавление stack
в конце
out = df.pivot(index = 'city',columns='sale_date').stack(level=0)