Функция Pandas df.stack()
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 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']
...
Пояснение к коду:
- Исходные данные представлены в широком формате, где Q1, Q2, Q3 — три столбца с квартальными данными.
stack()Три столбца Q1, Q2, Q3 «укладываются» в строки.- Результат имеет тип Series с двумя уровнями индекса: внешний уровень — это исходный индекс строк, а внутренний уровень — исходные имена столбцов (кварталы).
- После укладки данные становятся «длинным форматом», где каждая строка содержит только одно квартальное значение.
Пример 2: Укладка многоуровневых индексов столбцов
Если DataFrame имеет многоуровневый индекс столбцов, можно указать, какой уровень укладывать.
Пример
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 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()Это обратные операции; их совместное использование позволяет гибко изменять форму данных.
Пример
# 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: общие функции