You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars:展开列表列前匹配每行多列表的元素数量

解决Polars多列表列补全长度后explode的问题

问题原因

你原来的代码报错是因为pl.lit只能处理静态常量,无法基于动态计算的表达式(比如每行的列表长度差)生成列表。另外,原列表是i64类型,补全空字符串会导致类型不匹配,引发转换错误。

解决方案

步骤1:计算每行两个列表的最大长度

先新增一列max_len,存储每行中a和b列表的最大长度:

import polars as pl

df = pl.DataFrame({
    "a": [[1, 2], [3], [4, 5], [1]], 
    "b": [[4, 5, 7], [6], [4, 5], [3, 2]]
})

# 计算每行的最大列表长度
df = df.with_columns(max_len=pl.max_horizontal(pl.col("a").list.len(), pl.col("b").list.len()))

步骤2:补全短列表到最大长度

使用pl.list.repeat动态生成对应长度的占位元素(推荐用None匹配原i64类型的Null值,或转换类型后用空字符串):

# 补全a列:长度不足时拼接None列表
# 补全b列:同理
df = df.with_columns(
    a=pl.when(pl.col("a").list.len() < pl.col("max_len"))
        .then(pl.col("a").list.concat(pl.list.repeat(None, pl.col("max_len") - pl.col("a").list.len())))
        .otherwise(pl.col("a")),
    b=pl.when(pl.col("b").list.len() < pl.col("max_len"))
        .then(pl.col("b").list.concat(pl.list.repeat(None, pl.col("max_len") - pl.col("b").list.len())))
        .otherwise(pl.col("b"))
)

步骤3:执行explode操作

此时所有列表列长度一致,可以正常explode:

result = df.explode(["a", "b"])
print(result)

输出结果:

shape: (8, 4)
┌──────┬──────┬───────┬─────────┐
│ a    ┆ b    ┆ alens ┆ max_len │
│ ---  ┆ ---  ┆ ---   ┆ ---     │
│ i64  ┆ i64  ┆ u32   ┆ u32     │
╞══════╪══════╪═══════╪═════════╡
│ 1    ┆ 4    ┆ 2     ┆ 3       │
│ 2    ┆ 5    ┆ 2     ┆ 3       │
│ null ┆ 7    ┆ 2     ┆ 3       │
│ 3    ┆ 6    ┆ 1     ┆ 1       │
│ 4    ┆ 4    ┆ 2     ┆ 2       │
│ 5    ┆ 5    ┆ 2     ┆ 2       │
│ 1    ┆ 3    ┆ 1     ┆ 2       │
│ null ┆ 2    ┆ 1     ┆ 2       │
└──────┴──────┴───────┴─────────┘

可选:补全空字符串(需转换类型)

如果一定要用空字符串作为占位,需先将列表列转换为String类型:

df = df.with_columns(
    a=pl.col("a").cast(pl.String),
    b=pl.col("b").cast(pl.String),
    max_len=pl.max_horizontal(pl.col("a").list.len(), pl.col("b").list.len())
).with_columns(
    a=pl.when(pl.col("a").list.len() < pl.col("max_len"))
        .then(pl.col("a").list.concat(pl.list.repeat("", pl.col("max_len") - pl.col("a").list.len())))
        .otherwise(pl.col("a")),
    b=pl.when(pl.col("b").list.len() < pl.col("max_len"))
        .then(pl.col("b").list.concat(pl.list.repeat("", pl.col("max_len") - pl.col("b").list.len())))
        .otherwise(pl.col("b"))
).explode(["a", "b"])

关键说明

  • 避免用pl.lit处理动态生成的列表:pl.lit仅适用于静态常量,动态长度的列表需用Polars内置的列表生成函数(如pl.list.repeat)。
  • 保持类型一致:补全元素的类型必须和原列表类型匹配,否则会引发类型转换错误。

内容的提问来源于stack exchange,提问作者DOOM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:13:18