Polars中如何在单次.with_columns()中访问新创建的列?
问题原因
你遇到的报错是因为Polars在同一个with_columns调用中,所有表达式都是基于原始DataFrame的列计算的——也就是说,你前面写的pl.col("start").str.to_date()还没把原始的字符串列替换成日期类型,后面计算duration时用到的pl.col("end")和pl.col("start")还是原来的字符串列,自然没法做减法。
解决方案
方案1:内嵌转换逻辑到计算中
直接在计算duration时,对原始字符串列做日期转换,一次with_columns就能搞定:
import polars as pl pl.DataFrame( { "start": ["01.01.2019", "01.01.2020"], "end": ["11.01.2019", "01.05.2020"], } ).with_columns( pl.col("start").str.to_date(), pl.col("end").str.to_date(), (pl.col("end").str.to_date() - pl.col("start").str.to_date()).alias("duration"), )
缺点是start和end列的转换逻辑重复了一次,不过对于大多数场景,性能影响可以忽略。
方案2:使用pl.let复用转换结果(Polars 0.19+支持)
如果不想重复写转换逻辑,可以用pl.let定义临时变量,复用转换后的日期值,代码更高效:
import polars as pl pl.DataFrame( { "start": ["01.01.2019", "01.01.2020"], "end": ["11.01.2019", "01.05.2020"], } ).with_columns( pl.let( # 定义临时变量存储转换后的日期 start_date=pl.col("start").str.to_date(), end_date=pl.col("end").str.to_date(), # 一次性返回所有需要的列 then=[ start_date.alias("start"), end_date.alias("end"), (end_date - start_date).alias("duration"), ] ) )
这个方法只做了一次日期转换,逻辑更清晰,也满足单次调用的需求。
方案3:用select替换列并计算
如果不需要保留原始的字符串列,也可以直接用select一次性完成转换和计算:
import polars as pl pl.DataFrame( { "start": ["01.01.2019", "01.01.2020"], "end": ["11.01.2019", "01.05.2020"], } ).select( start=pl.col("start").str.to_date(), end=pl.col("end").str.to_date(), duration=pl.col("end").str.to_date() - pl.col("start").str.to_date(), )
代码紧凑,直接生成最终需要的列集合。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

