Polars使用with_columns三元表达式处理日期条件计算时长时遇‘Expr真值不明确’错误的解决咨询
Polars使用with_columns三元表达式处理日期条件计算时长时遇‘Expr真值不明确’错误的解决咨询
嗨,我完全懂你碰到的这个问题!在Polars里可不能直接用Python原生的if-else来处理列表达式哦,因为Polars的Expr是延迟计算的对象,没法直接判断它的布尔真值,这就是你收到TypeError: the truth value of an Expr is ambiguous错误的原因。
要实现你想要的逻辑,得用Polars专门提供的列级条件表达式工具——pl.when().then().otherwise(),它能逐行处理每一条数据的判断和计算,完全符合你“保留原数据、只新增列”的需求。具体写法如下:
import polars as pl from datetime import datetime df = pl.DataFrame({ 'name': 'foo', 'start': datetime.fromisoformat('2025-01-01 08:00:00'), 'end': datetime.fromisoformat('2025-01-01 18:00:00'), # ends after business hours 'business_end': datetime.fromisoformat('2025-01-01 17:00:00') }) # 正确的条件计算写法 result_df = df.with_columns( duration=pl.when(pl.col("end") <= pl.col("business_end")) .then(pl.col("end") - pl.col("start")) .otherwise(pl.col("business_end") - pl.col("start")) ) print(result_df)
运行这段代码后,你会得到正确的duration列,这里计算出来的是9小时(从08:00到17:00),完全符合你截断非工作时长的需求。
另外还有个更简洁的写法可以达到同样效果:既然我们只需要取end和business_end中更早的那个时间点来计算时长,直接用pl.min()函数取两者的最小值再减去start就行,代码更短也更高效:
result_df = df.with_columns( duration=pl.min(pl.col("end"), pl.col("business_end")) - pl.col("start") )
你之前提到的用filter()拆分数据再合并的方法虽然可行,但确实没必要——上面这两种方法都能在原DataFrame基础上直接新增列,不需要拆分、修改再合并的繁琐步骤,性能也更优。
备注:内容来源于stack exchange,提问作者Bryan Andregg
相关产品推荐
相关产品推荐

