панды поворачиваются и группируются

#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)