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

Polars中如何对列表类型列计算点积?无需展开列表

在Polars中对列表列计算点积(不使用explode)

问题背景

有包含等长列表列的Polars DataFrame,需在不使用explode(避免内存占用过高)的前提下计算两列的点积,原执行代码触发报错:

df = pl.DataFrame({
    "b": [[1,2,3], [2,3],[4],[1,2,3],[]],
    "c": [[1,1,1], [2,2],[4],[1,5,6],[]]
})
df.with_columns(pl.col('b').list.eval(pl.element().dot(pl.col('b'))).alias('b.c'))

报错信息:

ComputeError: named columns are not allowed in `list.eval`; consider using `element` or `col("")`

解决方案

方法1:Polars原生向量化操作(推荐)

通过list.zip将两列对应元素配对,对每对元素相乘后求和得到点积。完全基于Polars原生函数,性能最优,无需Python lambda:

import polars as pl

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

result = df.with_columns(
    dot=(
        pl.col("b").list.zip(pl.col("c"))
        .list.eval(pl.element().first() * pl.element().second())
        .list.sum()
        .fill_null(0)  # 空列表求和返回null,此处转为0
    )
)

print(result)

方法2:使用struct.map_elements

若逻辑更复杂,可将两列打包成struct,通过map_elements遍历每行计算点积,代码更直观:

result = df.with_columns(
    dot=pl.struct(["b", "c"]).map_elements(
        lambda s: sum(x*y for x, y in zip(s["b"], s["c"])),
        return_dtype=pl.Int64
    )
)

原代码报错原因

list.eval的作用域局限于当前列表列内部,仅能用pl.element()指代当前列表的元素,无法直接引用DataFrame的其他命名列(如代码中的pl.col('b')),因此触发报错。


最终输出

shape: (5, 3)
┌───────────┬───────────┬─────┐
│ b         ┆ c         ┆ dot │
│ ---       ┆ ---       ┆ --- │
│ list[i64] ┆ list[i64] ┆ i64 │
╞═══════════╪═══════════╪═════╡
│ [1, 2, 3] ┆ [1, 1, 1] ┆ 6   │
│ [2, 3]    ┆ [2, 2]    ┆ 10  │
│ [4]       ┆ [4]       ┆ 16  │
│ [1, 2, 3] ┆ [1, 5, 6] ┆ 29  │
│ []        ┆ []        ┆ 0   │
└───────────┴───────────┴─────┘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:54:04