Функция Pandas df.stack()

Pandas 常用函数Pandas: общие функции


df.stack()является методом-членом DataFrame, используемым дляпреобразования индексов столбцов в индексы строк. Он "укладывает" столбцы данных широкого формата в строки, создавая Series или DataFrame с иерархическим индексом.

Это важная операция для изменения формы данных, обычно используется вместе сunstack()для взаимного преобразования данных.

Определение слова: stackЭто означает «складывать, накапливать»; здесь это относится к «укладке» данных столбцов в строки, преобразуя широкую таблицу в длинную таблицу.


Базовый синтаксис и параметры

df.stack()является методом экземпляра DataFrame, вызываемым через оператор точки.

Формат синтаксиса

DataFrame.stack(level=-1, dropna=True)

Описание параметра

  • Параметр: level
    • Тип: int, str, список int или список str.
    • Описание: Указывает уровень для стекирования. Для многоуровневых индексов можно указать конкретный номер уровня (начиная с 0) или имя уровня. По умолчанию -1, что означает самый внутренний уровень.
  • Параметр: dropna
    • Тип: Boolean.
    • Описание: Удалять ли строки, все значения в которых NaN, в результате. По умолчанию True, что удаляет строки, где все значения NaN.

Описание функций

  • Возвращаемое значение: Возвращает Series или DataFrame. Если только один столбец исходного DataFrame стекируется, возвращается Series; в противном случае возвращается DataFrame.
  • Эффект: Преобразует индексы столбцов в индексы строк, создавая более длинный формат данных. Стекированные данные находятся в «длинном формате», что удобно для статистического анализа или визуализации.

Примеры

Давайте с помощью серии примеров от простого к сложному тщательно освоимdf.stack()его использование.

Пример 1: Базовое использование - Преобразование столбцов в строки

Пример

import pandas as pd
import numpy as np

# 1. Создайте данные в широком формате (один столбец на квартал)
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'Q1': [100, 150, 200],
    'Q2': [120, 160, 210],
    'Q3': [130, 170, 220]
})

print("=== Исходные данные в широком формате ===")
print(df)
print(f"Имена столбцов: {df.columns.tolist()}")

# 2. Используйте df.stack() для преобразования столбцов в строки
stacked = df.stack()
print("n=== результат df.stack() ===")
print(stacked)
print(f"nТип: {type(stacked)}")

# 3. Преобразуйте результат в DataFrame для проверки
print("n=== Преобразовано в DataFrame ===")
stacked_df = stacked.reset_index()
stacked_df.columns = ['name', 'quarter', 'sales']
print(stacked_df)

Ожидаемый вывод:

=== 原始宽格式数据 ===
      name  Q1   Q2   Q3
0    Alice  100  120  130
1      Bob  150  160  170
2  Charlie  'Q2', 'Q3'], columns=['name', 'quarter', 'sales']
...

Пояснение к коду:

  1. Исходные данные представлены в широком формате, где Q1, Q2, Q3 — три столбца с квартальными данными.
  2. stack()Три столбца Q1, Q2, Q3 «укладываются» в строки.
  3. Результат имеет тип Series с двумя уровнями индекса: внешний уровень — это исходный индекс строк, а внутренний уровень — исходные имена столбцов (кварталы).
  4. После укладки данные становятся «длинным форматом», где каждая строка содержит только одно квартальное значение.

Пример 2: Укладка многоуровневых индексов столбцов

Если DataFrame имеет многоуровневый индекс столбцов, можно указать, какой уровень укладывать.

Пример

import pandas as pd
import numpy as np

# 1. Создание данных с многоуровневым индексом столбцов
# Внешний уровень: тип продукта (Electronics, Furniture)
# Внутренний уровень: квартал (Q1, Q2)
df = pd.DataFrame(
    [[100, 110, 200, 210], [150, 160, 180, 190]],
    index=['Store_A', 'Store_B'],
    columns=pd.MultiIndex.from_tuples([
        ('Электроника', 'Q1'), ('Электроника', 'Q2'),
        ('Мебель', 'Q1'), ('Мебель', 'Q2')
    ], names=['Продукт', 'Квартал'])
)

print("=== Исходные данные (многоуровневый индекс столбцов) ===")
print(df)
print(f"Уровни индекса столбцов: {df.columns.names}")

# 2. Свернуть внутренний уровень столбцов (по умолчанию, level=-1)
print("n=== Свернуть внутренний уровень столбцов (level=-1) ===")
stacked_inner = df.stack()
print(stacked_inner)

# 3. Свернуть внешний уровень столбцов
print("n=== Свернуть внешний уровень столбцов (level=0) ===")
stacked_outer = df.stack(level=0)
print(stacked_outer)

# 4. Стековать все столбцы (создаёт более длинный формат)
print("n=== Стековать все столбцы ===")
stacked_all = df.stack(level=[0, 1])
print(stacked_all)

Ожидаемый вывод:

=== 原始数据(多层列索引)===
Product      Electronics   Furniture
Quarter              Q1   Q2      Q1   Q
...

Пояснение к коду:

  • Для DataFrame с многоуровневым индексом столбцов имена столбцов — это кортежи: (Product, Quarter).
  • level=-1Стековать самый внутренний уровень (по умолчанию), т. е. уровень Quarter, и результат сохраняет Product в качестве столбцов.
  • level=0Стековать внешний уровень, т. е. уровень Product, и результат сохраняет Quarter в качестве столбцов.
  • Эта гибкость позволяет выбирать уровень для стекования в соответствии с потребностями вашего анализа.

Пример 3: Обработка пропущенных значений

Используйтеdropnaпараметр для управления обработкой пропущенных значений.

Пример

import pandas as pd
import numpy as np

# 1. Создать данные, содержащие пропущенные значения
df = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'Math': [100, np.nan],
    'Английский': [90, 85],
    'Science': [np.nan, 95]
})

print("=== Исходные данные (содержащие пропущенные значения) ===")
print(df)

# 2. dropna=True (по умолчанию), удалить строки, состоящие только из NaN
print("n=== dropna=True (по умолчанию) ===")
stacked_drop = df.stack(dropna=True)
print(stacked_drop)

# 3. dropna=False, сохранить значения NaN
print("n=== dropna=False ===")
stacked_keep = df.stack(dropna=False)
print(stacked_keep)

# 4. Практическое применение: организовать результат после stack в длинный формат, пригодный для анализа
print("n=== Организовано в DataFrame длинного формата ===")
result = df.set_index('name').stack().reset_index()
result.columns = ['name', 'subject', 'score']
print(result)

# 5. Удаление пропущенных значений
result_clean = result.dropna()
print("n=== После удаления пропущенных значений ===")
print(result_clean)

Ожидаемый вывод:

=== 原始数据(包含缺失值)===
   name  Math  English  Science
0  Alice  100.0     90.0      NaN
1    Bob    NaN    85.0     95.0
2=== 堆叠内层列 (level=-1) ===
Store_A  Electronics  Q1    100
                  Q2    110
         Furniture   Q1    200
                  Q2    210
Store_B  Electronics  Q1    150
 ...

Пояснение к коду:

  • dropna=True(По умолчанию) удаляет строки, в которых все значения NaN.
  • В анализе данных обычно необходимо сохранять исходные данные, а затем при необходимости удалять пропущенные значения.
  • После стекирования используйтеreset_index()чтобы преобразовать иерархический индекс в обычные столбцы для удобства последующей обработки.

Пример 4: Совместное использование stack и unstack

stack()иunstack()Это обратные операции; их совместное использование позволяет гибко изменять форму данных.

Пример

import pandas as pd

# 1. Создайте исходные данные
df = pd.DataFrame({
    'product': ['A', 'B', 'C'],
    'Север': [100, 150, 200],
    'South': [180, 170, 160],
    'Восток': [190, 200, 210]
})

print("=== Исходные данные ===")
print(df)

# 2. Используйте unstack, чтобы преобразовать регионы в столбцы (сначала преобразуйте в многоуровневый индекс)
df_indexed = df.set_index('product')
print("n=== После установки индекса ===")
print(df_indexed)

# 3. Используйте stack, чтобы преобразовать столбцы в строки (stack — обратная операция к unstack)
print("n=== unstack + stack: преобразование туда и обратно ===")
# Сначала unstack
unstacked = df_indexed.unstack()
print("результат unstack:")
print(unstacked)
# Затем stack обратно
restacked = unstacked.stack()
print("nstack назад:")
print(restacked)

# 4. Полный пример: создать многоуровневый индекс и затем преобразовать
print("n=== Преобразование многоуровневого индекса ===")
# Создать DataFrame с многоуровневым индексом
multi_df = pd.DataFrame(
    [[100, 110], [150, 160]],
    index=pd.MultiIndex.from_tuples([('A', '2023'), ('B', '2023')], names=['product', 'year']),
    columns=['North', 'South']
)
print("Исходные данные многоуровневого индекса:")
print(multi_df)

# unstack year
print("nunstack year:")
print(multi_df.unstack(level='year'))

# unstack columns
print("nunstack columns (преобразовать в столбцы):")
print(multi_df.unstack(level='columns'))

Ожидаемый вывод:

=== unstack + stack 往返 ===
unstack 结果:
       product
North  A          100
       B          150
       C          200
South  A          180
       B          170
...

Пояснение к коду:

  • stack()Преобразует индексы столбцов в индексы строк, превращая широкую таблицу в длинную.
  • unstack()Преобразует индексы строк в индексы столбцов, превращая длинную таблицу в широкую.
  • Совместное использование обоих позволяет выполнять произвольное изменение формы данных.
  • Для анализа данных очень важно понимать обратную взаимосвязь между этими двумя операциями.

Совет: stack()иunstack()является ключевым инструментом для изменения формы данных.stack()складывает столбцы в строки (из широкого формата в длинный),unstack()разбивает строки на столбцы (из длинного формата в широкий).

Pandas 常用函数Pandas: общие функции

Другие расширения