Polars数据框重塑:将列表列展开为多列的技巧

DDD
发布: 2025-10-24 14:51:07
原创
457人浏览过

Polars数据框重塑:将列表列展开为多列的技巧

本文详细介绍了在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 等独立的列。

逐步实现数据框重塑

要实现上述转换,我们需要执行以下三个关键步骤:

1. 使用 unpivot 将列名转换为值

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 列(包含原始的列表数据)。

序列猴子开放平台
序列猴子开放平台

具有长序列、多模态、单模型、大数据等特点的超大规模语言模型

序列猴子开放平台 0
查看详情 序列猴子开放平台

2. 使用 list.to_struct 将列表转换为结构体

接下来,我们需要将 value 列中的每个列表转换为一个结构体(Struct)。结构体是一种复合数据类型,可以包含多个命名字段。这为我们将列表中的元素映射到独立的列提供了中间步骤。

pl.col("value").list.to_struct(fields=lambda x : f"Value{x}") 这行代码做了几件事:

  • pl.col("value"): 选中 value 列。
  • .list.to_struct(): 对列表列应用 to_struct 方法。
  • fields=lambda x : f"Value{x}": 这是关键部分。它定义了结构体中每个字段的名称。lambda x : f"Value{x}" 是一个匿名函数,它会为列表中的每个元素生成一个字段名,例如 Value0, Value1, Value2。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],其中包含了三个字段。

3. 使用 unnest 展开结构体列

最后一步是使用 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)
登录后复制

注意事项与总结

  • 链式操作的优势: Polars 的表达式系统允许我们将多个操作链式调用,这不仅使代码更简洁,而且由于Polars的优化执行,通常效率更高。
  • fields 参数的灵活性: list.to_struct 中的 fields 参数非常灵活,可以是一个字符串列表,也可以是一个生成字段名的函数(如本例所示)。根据具体需求选择合适的方式。
  • 数据类型一致性: 确保列表中的所有子元素具有相同的数据类型,否则 to_struct 可能会遇到类型推断问题。
  • 适用于多种场景: 这种组合操作不仅适用于将列表展开为列,还可以作为更复杂数据重塑和特征工程的基础。例如,如果列表长度不固定,to_struct 可能会用 null 填充较短的列表以匹配最长列表的结构。

通过掌握 unpivot、list.to_struct 和 unnest 这三个强大的Polars操作,您将能够高效地处理和重塑包含列表数据的复杂数据框,为后续的数据分析和建模工作奠定坚实基础。

以上就是Polars数据框重塑:将列表列展开为多列的技巧的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号