Pandas - самый популярный инструмент для анализа и обработки данных в Python. Используя модуль Pandas, мы можем легко создавать сложные конвейеры анализа данных. Один из частых случаев использования, с которым мы сталкиваемся, - это преобразование широких данных (также известных как данные без накопления) в длинные данные (также известные как данные с накоплением или модель «сущность-атрибут-значение») или наоборот. Широкоформатный формат содержит данные во многих столбцах, где атрибуты, связанные с наблюдением, хранятся в отдельном столбце. В длинном формате имена атрибутов хранятся в столбце, а соответствующие значения - в другом столбце, что упрощает использование данных в стандартных библиотеках для прогнозирования и в других приложениях машинного обучения.

Фрейм данных в широком формате содержит много столбцов. Например, многие специалисты по планированию цепочки поставок используют месяцы в качестве столбцов в электронной таблице Excel. Для данных за 5 лет это означает 60 столбцов. По прошествии нескольких месяцев это может стать трудным. С другой стороны, в длинном формате мы сможем легко выполнять сложные методы временных рядов, используя различные методы машинного обучения. Таким образом, нам придется превратить все столбцы месяцев в одну. Здесь в игру вступает pandas.melt (). Функция melt () изменяет форму или преобразует существующий фрейм данных из широкого формата в длинный формат.

Wide Format:
Person   Age   Weight   Height  
 -------- ----- -------- -------- 
  Bob       32      168      180  
  Alice     24      150      175  
  Steve     64      144      165
Long Format:
Person   Variable   Value  
 -------- ---------- ------- 
  Bob      Age           32  
  Bob      Weight       168  
  Bob      Height       180  
  Alice    Age           24  
  Alice    Weight       150  
  Alice    Height       175  
  Steve    Age           64  
  Steve    Weight       144  
  Steve    Height       165

В этой статье с простым вариантом использования я поделюсь несколькими примерами функции Pandas melt ().

Во-первых, давайте создадим широкий DataFrame. В качестве примера я буду использовать разные покупки товаров в час в магазине.

# Creating sample data
import pandas as pd
# creating a dataframe
df = pd.DataFrame(
    {
        'Item': ['Cereals', 'Dairy', 'Frozen', 'Meat'],
        'Price': [100, 50, 200, 250],
        'Hour_1': [5, 5, 3, 8],
        'Hour_2': [8, 8, 2, 1],
        'Hour_3': [7, 7, 8, 2]
    }
)

print(df)
  Item      Price   Hour_1   Hour_2   Hour_3  
 --------- ------- -------- -------- -------- 
  Cereals     100        5        8        7  
  Dairy        50        5        8        7  
  Frozen      200        3        2        8  
  Meat        250        8        1        2

В настоящее время эти данные представлены в удобочитаемой форме, поскольку для каждого элемента есть строка для каждого часа, но они не подходят для анализа. Итак, нам нужно немного изменить форму.

Растопить

Функция melt () используется для отмены поворота данного DataFrame из широкого формата в длинный, при необходимости оставляя переменные идентификатора установленными.

Синтаксис:

pd.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name=’value’, col_level=None)

Параметры

id_vars: столбцы для использования в качестве переменных идентификатора.

value_vars Столбцы, которые нужно откорректировать. Если не указано, используются все столбцы, которые не установлены как id_vars.

var_name - имя для столбца "переменная". Если нет, используется «переменная».

value_name - имя для столбца «значение».

col_level - если столбцы являются MultiIndex, используйте этот уровень для плавления.

ignore_index - Если True, исходный индекс игнорируется. Если False, исходный индекс сохраняется. Это будет полезно в тех случаях, когда указатель содержит полезную информацию.

Пример

Давайте изменим форму фрейма данных, чтобы в нем был столбец, содержащий часы, и другой столбец, содержащий значения продаж.

melt_df = pd.melt(
    df, 
    id_vars=['Item'], 
    value_vars=('Hour_1','Hour_2','Hour_3'), 
    var_name='Hour', 
    value_name='Sales', 
    col_level=None
)
melt_df
  Item      Hour    Sales  
 --------- -------- ------- 
  Cereals   Hour_1       5  
  Dairy     Hour_1       5  
  Frozen    Hour_1       3  
  Meat      Hour_1       8  
  Cereals   Hour_2       8  
  Dairy     Hour_2       8  
  Frozen    Hour_2       2  
  Meat      Hour_2       1  
  Cereals   Hour_3       7  
  Dairy     Hour_3       7  
  Frozen    Hour_3       8  
  Meat      Hour_3       2

Теперь мы можем вычислить некоторые полезные числа.

Группировка по позициям и продажам для получения общих продаж:

melt_df.groupby('Item')['Sales'].sum()
Item     Sales  
 --------- ------- 
  Cereals      20  
  Dairy        20  
  Frozen       13  
  Meat         11
melt_df.groupby('Hour')['Sales'].sum()
Hour    Sales  
 -------- ------- 
  Hour_1      21  
  Hour_2      19  
  Hour_3      24

В приведенном выше примере мы не включили цену. Если мы хотим вычислить выручку вместо количества продаж, нам нужно будет включить цену также в длинный формат. Это приведено ниже:

melt_df = pd.melt(
    df, 
    id_vars=['Item','Price'], 
    value_vars=('Hour_1','Hour_2','Hour_3'), 
    var_name='Hour', 
    value_name='Sales', 
    col_level=None
)
melt_df
  Item     Price    Hour    Sales   Revenue  
 --------- ------- -------- ------- --------- 
  Cereals     100   Hour_1       5       500  
  Dairy        50   Hour_1       5       250  
  Frozen      200   Hour_1       3       600  
  Meat        250   Hour_1       8      2000  
  Cereals     100   Hour_2       8       800  
  Dairy        50   Hour_2       8       400  
  Frozen      200   Hour_2       2       400  
  Meat        250   Hour_2       1       250  
  Cereals     100   Hour_3       7       700  
  Dairy        50   Hour_3       7       350  
  Frozen      200   Hour_3       8      1600  
  Meat        250   Hour_3       2       500

Расчет дохода:

df['Revenue'] = df['Price'] * df['Sales']
df
  Item     Price    Hour    Sales   Revenue  
 --------- ------- -------- ------- --------- 
  Cereals     100   Hour_1       5       500  
  Dairy        50   Hour_1       5       250  
  Frozen      200   Hour_1       3       600  
  Meat        250   Hour_1       8      2000  
  Cereals     100   Hour_2       8       800  
  Dairy        50   Hour_2       8       400  
  Frozen      200   Hour_2       2       400  
  Meat        250   Hour_2       1       250  
  Cereals     100   Hour_3       7       700  
  Dairy        50   Hour_3       7       350  
  Frozen      200   Hour_3       8      1600  
  Meat        250   Hour_3       2       500

Группировка по часам, позиции для получения общей выручки:

df.groupby('Hour')['Revenue'].sum()
  Hour     Revenue  
 --------- --------- 
  Hour_1       3350  
  Hour_2       1850  
  Hour_3       3150
df.groupby('Item')['Revenue'].sum()
  Item     Revenue  
 --------- --------- 
  Cereals      2000  
  Dairy        1000  
  Frozen       2600  
  Meat         2750

Расплавление DataFrame с помощью функции pivot ()

Функцию pivot () можно использовать для преобразования объекта DataFrame из длинного в широкий формат, чтобы получить исходный фрейм данных. Значение index функции pivot () должно быть таким же, как значение id_vars. Значение столбца следует передавать как имя столбца переменной.

melt_df
  Item     Price    Hour    Sales   Revenue  
 --------- ------- -------- ------- --------- 
  Cereals     100   Hour_1       5       500  
  Dairy        50   Hour_1       5       250  
  Frozen      200   Hour_1       3       600  
  Meat        250   Hour_1       8      2000  
  Cereals     100   Hour_2       8       800  
  Dairy        50   Hour_2       8       400  
  Frozen      200   Hour_2       2       400  
  Meat        250   Hour_2       1       250  
  Cereals     100   Hour_3       7       700  
  Dairy        50   Hour_3       7       350  
  Frozen      200   Hour_3       8      1600  
  Meat        250   Hour_3       2       500
df_unmelted = melt_df.pivot_table(
    index['Item','Price'],columns='Hour',values='Sales'
)
df_unmelted
  Item     Price   Hour_1   Hour_2   Hour_3  
 --------- ------- -------- -------- -------- 
  Cereals     100        5        8        7  
  Dairy        50        5        8        7  
  Frozen      200        3        2        8  
  Meat        250        8        1        2

Дивья Хосе (Divya Jose) - специалист по анализу данных в компании Predmatic с опытом работы в области стохастических процессов, моделирования методом Монте-Карло, планирования поставок и прогнозирования на основе данных. Predmatic AI - это компания, занимающаяся наукой о данных и разработкой решений на основе искусственного интеллекта, которая предоставляет высокоэффективные и масштабируемые бизнес-решения.