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

如何对长度不同的多列列表进行截断式Explode操作?

Polars按列表最短长度截断式Explode的高效实现

问题描述

我有如下Polars DataFrame:

data = {
    "a": [[1], [2], [3, 4], [5, 6, 7]],
    "b": [[], [8], [9, 10], [11, 12]],
}
df = pl.DataFrame(data)

对应的DataFrame展示为:
┌───────────┬───────────┐
│ a ┆ b │
│ --- ┆ --- │
│ list[i64] ┆ list[i64] │
╞═══════════╪═══════════╡
│ [1] ┆ [] │
│ [2] ┆ [8] │
│ [3, 4] ┆ [9, 10] │
│ [5, 6, 7] ┆ [11, 12] │
└───────────┴───────────┘
每一行的两个列表长度可能不一致,我希望按两个列表的最短长度进行截断式Explode,得到如下结果:
┌─────┬─────┐
│ a ┆ b │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 2 ┆ 8 │
│ 3 ┆ 9 │
│ 4 ┆ 10 │
│ 5 ┆ 11 │
│ 6 ┆ 12 │
└─────┴─────┘
我原本考虑将较短的列表用None填充至相同长度后再drop_nulls,但想知道是否有更直接的实现方式?

更直接的实现方式

方法一:计算最短长度后截断列表

先计算每行两个列表的最短长度,对列表进行截断后再执行explode,步骤简洁高效,无需填充Null再过滤:

import polars as pl

data = {
    "a": [[1], [2], [3, 4], [5, 6, 7]],
    "b": [[], [8], [9, 10], [11, 12]],
}
df = pl.DataFrame(data)

result = df.with_columns(
    # 计算每行两个列表的最短长度
    min_len=pl.min([pl.col("a").list.lengths(), pl.col("b").list.lengths()]),
    # 截断列表到最短长度
    a=pl.col("a").list.slice(0, pl.col("min_len")),
    b=pl.col("b").list.slice(0, pl.col("min_len")),
).drop("min_len")  # 移除临时计算列
# 执行explode并过滤空行
result = result.explode(["a", "b"]).drop_nulls()

print(result)

方法二:利用arr.zip_with自动配对

借助Polars的arr.zip_with函数,直接按两个列表的最短长度生成配对元组,再展开拆包,写法更简洁:

import polars as pl

data = {
    "a": [[1], [2], [3, 4], [5, 6, 7]],
    "b": [[], [8], [9, 10], [11, 12]],
}
df = pl.DataFrame(data)

result = df.with_columns(
    paired=pl.col("a").arr.zip_with(pl.col("b"), lambda x, y: (x, y))
).explode("paired").unnest("paired").drop_nulls()

print(result)

两种方法都能得到你想要的目标结果,且避免了填充Null的额外步骤,执行效率更高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:18:20