Python-Polars中实现嵌套列表元素乘积的表达式实现问题
Python-Polars中实现嵌套列表元素乘积的表达式实现问题
嘿,我来帮你搞定这个问题!你之前用pl.reduce没得到预期结果,是因为没找准操作的层级——你需要的是对每个内层子列表单独计算乘积,但原来的代码是直接对最外层的列表元素(也就是那些子列表本身)做操作,自然结果和原数据一样啦。
咱们来调整代码,先解决乘积的需求:
实现嵌套列表的乘积计算
你需要在list.eval里,针对每个内层子列表,用pl.reduce遍历它的元素来计算乘积,还要记得设置初始值(避免子列表只有一个元素时出问题)。代码如下:
import polars as pl df = pl.DataFrame({"values": [[[1]], [[2, 3], [5,6]]]}) # 计算每个内层子列表的乘积 result = df.with_columns( product=pl.col("values").list.eval( pl.reduce(lambda acc, x: acc * x, pl.element().list.explode(), initial_value=1) ) ) print(result)
运行后会得到你想要的结果:
shape: (2, 2) ┌──────────────────┬───────────┐ │ values ┆ product │ │ --- ┆ --- │ │ list[list[i64]] ┆ list[i64] │ ╞══════════════════╪═══════════╡ │ [[1]] ┆ [1] │ │ [[2, 3], [5, 6]] ┆ [6, 30] │ └──────────────────┴───────────┘
代码解释:
pl.col("values").list.eval(...):遍历外层列表的每一个子列表(比如第一行的[1],第二行的[2,3]和[5,6])pl.element().list.explode():把当前子列表展开成单个元素,让reduce能逐个处理initial_value=1:乘积的初始值设为1,保证子列表只有一个元素时(比如[1])也能正确计算(1*1=1)
拓展:实现嵌套列表的除法计算
除法要注意顺序(毕竟除法不满足交换律),还有初始值的选择。如果是要计算子列表第一个元素依次除以后续元素的结果,代码可以这么写:
division_result = df.with_columns( division=pl.col("values").list.eval( pl.reduce( lambda acc, x: acc / x, pl.element().list.explode().slice(1), # 从第二个元素开始取 initial_value=pl.element().list.first() # 用第一个元素作为初始值 ) ) ) print(division_result)
输出结果:
shape: (2, 2) ┌──────────────────┬─────────────┐ │ values ┆ division │ │ --- ┆ --- │ │ list[list[i64]] ┆ list[f64] │ ╞══════════════════╪═════════════╡ │ [[1]] ┆ [1.0] │ │ [[2, 3], [5, 6]] ┆ [0.6667, 0.8333] │ └──────────────────┴─────────────┘
代码解释:
pl.element().list.first():拿子列表的第一个元素当除法的起始值pl.element().list.explode().slice(1):从第二个元素开始,依次和初始值做除法,实现「第一个元素÷第二个÷第三个...」的逻辑- 注意:除法结果会变成浮点数,而且要确保子列表不为空,不然会报错哦!
核心思路就是:在list.eval的上下文里,聚焦到每个内层子列表,用pl.reduce配合list.explode遍历元素,再设置合适的初始值,就能实现和list.sum类似的自定义聚合逻辑啦。
备注:内容来源于stack exchange,提问作者yz_jc
相关产品推荐
相关产品推荐

