6.4 数据重塑 (stack 和 unstack) Pandas 数据重塑:Stack 和 Unstack 在数据分析中,经常需要改变数据的结构,使其更适合特定的分析或可视化任务。Pandas 提供了 和 这两个强大的函数,用于在 DataFrame 和 Series 对象上进行数据重塑,将数据从“宽”格式转换为“长”格式,反之亦然。 概述 Stack (堆叠):将 DataFrame 的列“堆叠”到行,将最外层的列索引转换为最内层的行索引,从而将数据从宽格式转换为长格式。 Unstack (拆堆):是 Stack 的逆操作,将最内层的行索引“拆堆”到列,将数据从长格式转换为宽格式。 Stack 的使用 函数的基本语法如下: :指定要堆叠的列索引的级别。默认为 -1,表示最外层的列索引。
在数据分析中,经常需要改变数据的结构,使其更适合特定的分析或可视化任务。Pandas 提供了 stack 和 unstack 这两个强大的函数,用于在 DataFrame 和 Series 对象上进行数据重塑,将数据从“宽”格式转换为“长”格式,反之亦然。
Stack (堆叠):将 DataFrame 的列“堆叠”到行,将最外层的列索引转换为最内层的行索引,从而将数据从宽格式转换为长格式。
Unstack (拆堆):是 Stack 的逆操作,将最内层的行索引“拆堆”到列,将数据从长格式转换为宽格式。
stack() 函数的基本语法如下:
DataFrame.stack(level=-1, dropna=True)
level:指定要堆叠的列索引的级别。默认为 -1,表示最外层的列索引。
dropna:一个布尔值,指定是否删除堆叠后包含 NaN 值的行。默认为 True。
示例 1:基本 Stack 操作
import pandas as pd data = {'产品': ['A', 'A', 'B', 'B'], '年份': [2022, 2023, 2022, 2023], '销量': [100, 120, 150, 180], '价格': [10, 12, 15, 18]} df = pd.DataFrame(data) df = df.set_index(['产品', '年份']) # 设置多层索引 print("原始 DataFrame:\n", df) stacked_df = df.stack() print("\n堆叠后的 Series:\n", stacked_df)
输出:
原始 DataFrame: 销量 价格 产品 年份 A 2022 100 10 2023 120 12 B 2022 150 15 2023 180 18 堆叠后的 Series: 产品 年份 A 2022 销量 100 价格 10 2023 销量 120 价格 12 B 2022 销量 150 价格 15 2023 销量 180 价格 18 dtype: int64
在这个例子中,stack() 函数将 DataFrame 的列 '销量' 和 '价格' 堆叠到行,创建了一个 Series 对象,其中最内层的行索引是原始 DataFrame 的列名。
示例 2:指定 Level
import pandas as pd data = {'产品': ['A', 'A', 'B', 'B'], '年份': [2022, 2023, 2022, 2023], '销量': [100, 120, 150, 180], '价格': [10, 12, 15, 18]} df = pd.DataFrame(data) # 创建多层列索引 df = df.set_index(['产品','年份']) df.columns = pd.MultiIndex.from_tuples([('销售数据', '销量'), ('销售数据', '价格')]) print("原始 DataFrame:\n", df) stacked_df = df.stack(level=0) # 堆叠第一层列索引 print("\n堆叠后的 DataFrame:\n", stacked_df)
输出:
原始 DataFrame: 销售数据 销量 价格 产品 年份 A 2022 100 10 2023 120 12 B 2022 150 15 2023 180 18 堆叠后的 DataFrame: 销量 价格 产品 年份 销售数据 A 2022 销售数据 100 10 2023 销售数据 120 12 B 2022 销售数据 150 15 2023 销售数据 180 18
在这个例子中,我们创建了一个具有多层列索引的 DataFrame,然后使用 stack(level=0) 堆叠了第一层列索引。
unstack() 函数的基本语法如下:
Series.unstack(level=-1, fill_value=None) DataFrame.unstack(level=-1, fill_value=None)
level:指定要拆堆的行索引的级别。默认为 -1,表示最内层的行索引。
fill_value:用于填充拆堆后产生的缺失值。默认为 None。
示例 1:基本 Unstack 操作
import pandas as pd data = {'产品': ['A', 'A', 'B', 'B'], '年份': [2022, 2023, 2022, 2023], '销量': [100, 120, 150, 180], '价格': [10, 12, 15, 18]} df = pd.DataFrame(data) df = df.set_index(['产品', '年份']) # 设置多层索引 stacked_df = df.stack() print("原始 Series:\n", stacked_df) unstacked_df = stacked_df.unstack() print("\n拆堆后的 DataFrame:\n", unstacked_df)
输出:
原始 Series: 产品 年份 A 2022 销量 100 价格 10 2023 销量 120 价格 12 B 2022 销量 150 价格 15 2023 销量 180 价格 18 dtype: int64 拆堆后的 DataFrame: 销量 价格 产品 年份 A 2022 100 10 2023 120 12 B 2022 150 15 2023 180 18
在这个例子中,unstack() 函数将 Series 对象的最内层行索引('销量' 和 '价格')拆堆到列,恢复了原始 DataFrame 的结构。
示例 2:指定 Level 和 Fill Value
import pandas as pd import numpy as np data = {'产品': ['A', 'A', 'B', 'B'], '年份': [2022, 2023, 2022, 2023], '销量': [100, 120, 150, 180]} df = pd.DataFrame(data) df = df.set_index(['产品', '年份']) # 添加一个缺失值 df.loc[('A', 2022), '价格'] = np.nan df.loc[('B', 2023), '价格'] = np.nan stacked_df = df.stack() print("原始 Series:\n", stacked_df) unstacked_df = stacked_df.unstack(level=0, fill_value=0) # 拆堆第一层行索引,并填充缺失值 print("\n拆堆后的 DataFrame:\n", unstacked_df)
输出:
原始 Series: 产品 年份 A 2022 销量 100.0 2023 销量 120.0 B 2022 销量 150.0 2023 销量 180.0 2023 价格 NaN A 2022 价格 NaN dtype: float64 拆堆后的 DataFrame: 产品 A B 年份 价格 0.0 NaN 销量 100.0 150.0 年份 价格 NaN NaN 销量 120.0 180.0
在这个例子中,我们首先向 DataFrame 添加了一些缺失值,然后使用 unstack(level=0, fill_value=0) 拆堆了第一层行索引('产品'),并使用 0 填充了缺失值。
数据透视表:Stack 和 Unstack 可以用于创建和操作数据透视表,将数据按照不同的维度进行聚合和展示。
时间序列数据:Stack 和 Unstack 可以用于将时间序列数据从宽格式转换为长格式,或者将多个时间序列合并成一个 DataFrame。
多层索引数据:Stack 和 Unstack 可以用于处理具有多层索引的 DataFrame 和 Series 对象,方便地进行数据重塑和分析。
可以使用 Mermaid 图表来更直观地理解 Stack 和 Unstack 的操作。
解释:
DataFrame (宽格式): 原始的 DataFrame,可能包含多个列。
Stack: 将列“堆叠”到行,生成 Series。
Series (长格式): 长格式的 Series,列名变成了行索引的一部分。
Unstack: 将行“拆堆”到列,恢复 DataFrame。
DataFrame (宽格式): 经过 Unstack 操作后,恢复的 DataFrame。
示例:更具体的 Mermaid 图
假设我们有以下 DataFrame:
销量 价格 产品 年份 A 2022 100 10 2023 120 12 B 2022 150 15 2023 180 18
那么 Stack 和 Unstack 的过程可以这样可视化:
Stack 和 Unstack 操作可能会产生缺失值(NaN),需要根据实际情况进行处理。
在处理具有多层索引的 DataFrame 和 Series 对象时,需要仔细选择 level 参数,以确保得到正确的结果。
Stack 和 Unstack 可以结合使用,以实现更复杂的数据重塑操作。
stack 和 unstack 是 Pandas 中非常重要的数据重塑工具,可以帮助我们将数据从宽格式转换为长格式,或者从长格式转换为宽格式,从而更方便地进行数据分析和可视化。 掌握这两个函数的使用,可以极大地提高数据处理的效率和灵活性。希望本文的详细讲解和代码示例能够帮助你更好地理解和应用 Stack 和 Unstack 函数。