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

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

Я пытался транспонировать и использовать функции поворота, но это не сработало. Я также пробовал сводную_таблицу, но это тоже не сработало.

Ожидаемый результат:

Пожалуйста, предоставьте свои данные в виде текста, а не фото. в качестве альтернативы вы можете поделиться ссылкой на загружаемый файл csv.

sammywemmy 03.02.2023 00:22
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
67
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам нужно смешать melt, чтобы сгладить ваш фрейм данных, а затем pivot_table изменить его форму в соответствии с ожидаемым результатом:

>>> (df.melt(var_name=['Variable', 'Date'], value_name='Value', ignore_index=False)
       .pivot_table(index=df.index.names+['Date'], columns='Variable', values='Value')
       .reset_index().rename_axis(columns=None))

  Brand Family Brand Channel Product        Date  Dollars  Quantity
0            A     A     Reg      A1  2022-01-12        4         1
1            A     A     Reg      A1  2022-01-13        5         2
2            A     A     Reg      A1  2022-01-14        6         3
3            A     A     Reg      A2  2022-01-12       14        11
4            A     A     Reg      A2  2022-01-13       15        12
5            A     A     Reg      A2  2022-01-14       16        13

Вход:

>>> df

                                     Quantity                          Dollars                      
                                   2022-01-12 2022-01-13 2022-01-14 2022-01-12 2022-01-13 2022-01-14
Brand Family Brand Channel Product                                                                  
A            A     Reg     A1               1          2          3          4          5          6
                           A2              11         12         13         14         15         16

Вы также можете использовать:

df1 = pd.read_csv('path/file.csv', header=[0, 1], index_col=[0,1,2,3])

df1.stack().reset_index()

  Brand Family Brand Channel Product        Date  Quantity  Dollars
0            A     A     Reg      A1  2022-01-12         1        4
1            A     A     Reg      A1  2022-01-13         2        5
2            A     A     Reg      A1  2022-01-14         3        6
3            A     A     Reg      A2  2022-01-12        11       14
4            A     A     Reg      A2  2022-01-13        12       15
5            A     A     Reg      A2  2022-01-14        13       16

где df1 ваши данные

Ответ принят как подходящий

Я просто предположил, что ваш CSV-файл похож на тот, который встроен в мой код.

Решение

Сначала прочитайте файл и игнорируйте заголовки.

import io
import pandas as pd
import numpy as np

csv_file = io.StringIO('''\
,,,,Quantity,Quantity,Quantity,Dollars,Dollars,Dollars
Brand Family,Brand,Channel,Product,2022-01-12,2022-01-13,2022-01-14,2022-01-12,2022-01-13,2022-01-14
Brand A,Brand A,Reg,A1,18,47,41,216,164,492
Brand A,Brand A,Reg,A2,9,23,20,108,276,240
Brand A,Brand A,Reg,A3,28,80,82,392,1120,1148
Brand A,Brand A,Reg,A4,,,,,,
Brand A,Brand A,Reg,A5,7,15,13,98,210,182\
''')

df = pd.read_csv(csv_file, header=None).replace(np.nan, 0)
print(df)
              0        1        2        3           4           5           6           7           8           9
0             0        0        0        0    Quantity    Quantity    Quantity     Dollars     Dollars     Dollars
1  Brand Family    Brand  Channel  Product  2022-01-12  2022-01-13  2022-01-14  2022-01-12  2022-01-13  2022-01-14
2       Brand A  Brand A      Reg       A1          18          47          41         216         164         492
3       Brand A  Brand A      Reg       A2           9          23          20         108         276         240
4       Brand A  Brand A      Reg       A3          28          80          82         392        1120        1148
5       Brand A  Brand A      Reg       A4           0           0           0           0           0           0
6       Brand A  Brand A      Reg       A5           7          15          13          98         210         182

И давайте разделим его на две части, левая часть

left = df.iloc[2:, :4].set_axis(df.iloc[1, :4], axis='columns')
print(left)
1 Brand Family    Brand Channel Product
2      Brand A  Brand A     Reg      A1
3      Brand A  Brand A     Reg      A2
4      Brand A  Brand A     Reg      A3
5      Brand A  Brand A     Reg      A4
6      Brand A  Brand A     Reg      A5

и правая часть.

right = df.iloc[:, 4:].T
print(right)
          0           1    2    3     4  5    6
4  Quantity  2022-01-12   18    9    28  0    7
5  Quantity  2022-01-13   47   23    80  0   15
6  Quantity  2022-01-14   41   20    82  0   13
7   Dollars  2022-01-12  216  108   392  0   98
8   Dollars  2022-01-13  164  276  1120  0  210
9   Dollars  2022-01-14  492  240  1148  0  182

Теперь поверните правую часть

pivoted = right.pivot(index=0, columns=[1]).T.reset_index(level=1, names=[0, 'Date'])
print(pivoted)

и обратите внимание, что индекс соответствует левой части.

0        Date Dollars Quantity
2  2022-01-12     216       18
2  2022-01-13     164       47
2  2022-01-14     492       41
3  2022-01-12     108        9
3  2022-01-13     276       23
3  2022-01-14     240       20
4  2022-01-12     392       28
4  2022-01-13    1120       80
4  2022-01-14    1148       82
5  2022-01-12       0        0
5  2022-01-13       0        0
5  2022-01-14       0        0
6  2022-01-12      98        7
6  2022-01-13     210       15
6  2022-01-14     182       13

Наконец, соедините их общим индексом.

df = left.join(pivoted).reset_index(drop=True)
print(df)
   Brand Family    Brand Channel Product        Date Dollars Quantity
0       Brand A  Brand A     Reg      A1  2022-01-12     216       18
1       Brand A  Brand A     Reg      A1  2022-01-13     164       47
2       Brand A  Brand A     Reg      A1  2022-01-14     492       41
3       Brand A  Brand A     Reg      A2  2022-01-12     108        9
4       Brand A  Brand A     Reg      A2  2022-01-13     276       23
5       Brand A  Brand A     Reg      A2  2022-01-14     240       20
6       Brand A  Brand A     Reg      A3  2022-01-12     392       28
7       Brand A  Brand A     Reg      A3  2022-01-13    1120       80
8       Brand A  Brand A     Reg      A3  2022-01-14    1148       82
9       Brand A  Brand A     Reg      A4  2022-01-12       0        0
10      Brand A  Brand A     Reg      A4  2022-01-13       0        0
11      Brand A  Brand A     Reg      A4  2022-01-14       0        0
12      Brand A  Brand A     Reg      A5  2022-01-12      98        7
13      Brand A  Brand A     Reg      A5  2022-01-13     210       15
14      Brand A  Brand A     Reg      A5  2022-01-14     182       13

Это сработало и было очень легко следовать, спасибо! Одно изменение, которое мне пришлось внести, заключалось в том, чтобы удалить «names=[0, 'Date']» из reset_index, чтобы оно заработало.

rupi 03.02.2023 18:07

Другие вопросы по теме