如何在Polars DataFrame中为列表值计算Z-score
解决Polars DataFrame中列表列的Z-score计算并保留None值
要实现对列表列中每个数值计算Z-score且保留None值,你可以利用Polars的数组操作函数,以下是两种可行方案:
方案一:使用arr.eval(推荐,性能更优)
Polars的arr.eval是原生数组操作API,能在查询引擎层面高效处理列表元素,避免Python循环的性能损耗:
import polars as pl data = { "transcript_id": ["ENST00000711184.1"], "OE": [[3.933402, 1.057907, None, 3.116513]], "mean_OE": [11.882091], "std_OE": [3.889974], } df_human = pl.DataFrame(data) # 计算Z-score并保留None值 df_result = df_human.with_columns( pl.col("OE").arr.eval( pl.when(pl.element().is_not_null()) .then((pl.element() - pl.col("mean_OE")) / pl.col("std_OE")) .otherwise(pl.element()) ).alias("OE_zscore") ) # 查看结果 print(df_result)
代码说明
arr.eval:遍历OE列的每个列表,对列表内的每个元素执行后续表达式pl.element():指代当前处理的列表元素when/then/otherwise:判断元素是否为非空值,非空则计算Z-score(公式:(x - mean)/std),空值则直接保留
方案二:使用map_elements(直观易读)
如果数据量不大,也可以用map_elements结合Python列表推导式实现,逻辑更直观:
df_result = df_human.with_columns( pl.col("OE").map_elements( lambda lst: [(x - mean) / std if x is not None else None for x, mean, std in zip(lst, pl.col("mean_OE"), pl.col("std_OE"))], return_dtype=pl.List(pl.Float64) ).alias("OE_zscore") )
代码说明
map_elements:对OE列的每个列表执行lambda函数- 列表推导式:逐个检查列表元素,非空值计算Z-score,空值保留None
return_dtype:显式指定返回类型为浮点型列表,避免Polars自动推断错误
结果验证
处理后的OE_zscore列结果为:[[-2.04339, -2.7826, None, -2.2534]]
(数值为近似值,精确计算以实际运行结果为准)
内容的提问来源于stack exchange,提问作者Yannick Fitch
相关产品推荐
相关产品推荐

