
本文详细介绍了在polars中如何将包含列表的数据框列进行复杂重塑。通过结合`unpivot`、`list.to_struct`和`unnest`操作,可以将原始数据框的列名转换为新列的值,并将列表元素展开为多个独立的列,从而实现数据从宽格式到长格式再到特定宽格式的灵活转换,极大地简化了数据处理流程。
在数据分析和处理中,我们经常会遇到需要对数据框的结构进行复杂重塑的场景。特别是在处理包含列表(List)类型数据的列时,如何将这些列表元素有效地展开为独立的列,并同时重构数据框的整体布局,是Polars用户面临的常见挑战。本教程将详细演示如何利用Polars的强大功能,通过一系列链式操作,将一个包含列表列的数据框转换为一个更易于分析的宽格式数据框。
假设我们有一个Polars数据框,其中包含多个列,每个列的值都是一个列表。
import polars as pl
df = pl.DataFrame({
"foo": [[1, 2, 3], [7, 8, 9]],
"bar": [[4, 5, 6], [1, 0, 1]]
})
print("原始数据框:")
print(df)输出:
原始数据框: shape: (2, 2) ┌─────┬─────┐ │ foo ┆ bar │ │ --- ┆ --- │ │ list[i64] ┆ list[i64] │ ╞═════╪═════╡ │ [1, 2, 3] ┆ [4, 5, 6] │ │ [7, 8, 9] ┆ [1, 0, 1] │ └─────┴─────┘
我们的目标是将这个数据框转换为以下结构:
shape: (4, 4) ┌──────┬────────┬────────┬────────┐ │ Name ┆ Value0 ┆ Value1 ┆ Value2 │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 ┆ i64 │ ╞══════╪════════╪════════╪════════╡ │ foo ┆ 1 ┆ 2 ┆ 3 │ │ foo ┆ 7 ┆ 8 ┆ 9 │ │ bar ┆ 4 ┆ 5 ┆ 6 │ │ bar ┆ 1 ┆ 0 ┆ 1 │ └──────┴────────┴────────┴────────┘
可以看到,原始的列名(foo, bar)变成了新列 Name 的值,而每个列表中的元素则被展开成了 Value0, Value1, Value2 等独立的列。
要实现上述转换,我们需要执行以下三个关键步骤:
unpivot 操作(在其他库中也常被称为 melt)用于将数据框的“宽”格式转换为“长”格式。它会将指定列的列名转换为一个新列的值,并将这些列的对应值放入另一个新列。
在这个例子中,我们将 foo 和 bar 列进行 unpivot 操作。variable_name="Name" 参数指定了存储原始列名的新列的名称,而默认情况下,原始列的值会存储在一个名为 value 的新列中。
# 步骤 1: unpivot
df_unpivoted = df.unpivot(variable_name="Name")
print("\n步骤 1: unpivot 后的数据框:")
print(df_unpivoted)输出:
步骤 1: unpivot 后的数据框: shape: (4, 2) ┌──────┬───────────┐ │ Name ┆ value │ │ --- ┆ --- │ │ str ┆ list[i64] │ ╞══════╪═══════════╡ │ foo ┆ [1, 2, 3] │ │ foo ┆ [7, 8, 9] │ │ bar ┆ [4, 5, 6] │ │ bar ┆ [1, 0, 1] │ └──────┴───────────┘
现在,我们有了一个 Name 列(包含 foo 和 bar)和一个 value 列(包含原始的列表数据)。
接下来,我们需要将 value 列中的每个列表转换为一个结构体(Struct)。结构体是一种复合数据类型,可以包含多个命名字段。这为我们将列表中的元素映射到独立的列提供了中间步骤。
pl.col("value").list.to_struct(fields=lambda x : f"Value{x}") 这行代码做了几件事:
# 步骤 2: 将列表转换为结构体
df_struct = df_unpivoted.with_columns(
pl.col("value").list.to_struct(fields=lambda x : f"Value{x}")
)
print("\n步骤 2: 列表转换为结构体后的数据框:")
print(df_struct)输出:
步骤 2: 列表转换为结构体后的数据框:
shape: (4, 2)
┌──────┬────────────────────┐
│ Name ┆ value │
│ --- ┆ --- │
│ str ┆ struct[3] │
╞══════╪════════════════════╡
│ foo ┆ {1,2,3} │
│ foo ┆ {7,8,9} │
│ bar ┆ {4,5,6} │
│ bar ┆ {1,0,1} │
└──────┴────────────────────┘现在 value 列的数据类型变为了 struct[3],其中包含了三个字段。
最后一步是使用 unnest 操作。unnest 会将一个结构体列中的每个字段展开为数据框中的独立列。
# 步骤 3: 展开结构体列
df_final = df_struct.unnest("value")
print("\n步骤 3: 展开结构体列后的最终数据框:")
print(df_final)输出:
步骤 3: 展开结构体列后的最终数据框: shape: (4, 4) ┌──────┬────────┬────────┬────────┐ │ Name ┆ Value0 ┆ Value1 ┆ Value2 │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 ┆ i64 │ ╞══════╪════════╪════════╪════════╡ │ foo ┆ 1 ┆ 2 ┆ 3 │ │ foo ┆ 7 ┆ 8 ┆ 9 │ │ bar ┆ 4 ┆ 5 ┆ 6 │ │ bar ┆ 1 ┆ 0 ┆ 1 │ └──────┴────────┴────────┴────────┘
至此,我们成功地将原始数据框重塑为所需的格式。
将上述三个步骤链式组合起来,可以得到一个简洁高效的解决方案:
import polars as pl
df = pl.DataFrame({
"foo": [[1, 2, 3], [7, 8, 9]],
"bar": [[4, 5, 6], [1, 0, 1]]
})
output_df = (
df
.unpivot(variable_name="Name")
.with_columns(pl.col("value").list.to_struct(fields=lambda x : f"Value{x}"))
.unnest("value")
)
print("\n最终重塑后的数据框:")
print(output_df)通过掌握 unpivot、list.to_struct 和 unnest 这三个强大的Polars操作,您将能够高效地处理和重塑包含列表数据的复杂数据框,为后续的数据分析和建模工作奠定坚实基础。
以上就是Polars数据框重塑:将列表列展开为多列的技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号