Polars中用更简洁方式将空列表替换为null的方法
问题:Polars中将空列表替换为Null的简洁实现
我正在从换行分隔的JSON(ndjson)文件提取数据并执行一系列转换,其中一项转换会生成值列表,我希望空列表[]替换为null而非保留空列表。具体场景:每个JSON对象包含telecom嵌套JSON对象数组,需要在expr_extract_phone()中实现:从telecom数组里提取system为"phone"的对象的value字段,收集为唯一值列表;若列表为空则设为null。
当前实现代码逻辑繁琐,尤其是用map_batches处理空列表的部分,想寻找更简洁的Polars表达式写法:
def expr_extract_phone() -> pl.Expr: return pl.col('telecom').list.eval( pl.element().filter(pl.element().struct['system'] == 'phone').struct['value'] ).list.unique().alias('phone_numbers').map_batches(lambda col: pl.LazyFrame(col).select( pl.when(pl.col('phone_numbers').list.len() > 0)\ .then(pl.col('phone_numbers')) ).collect().get_column('phone_numbers'), return_dtype=pl.List(pl.String), is_elementwise=True )
简洁实现方案
可以直接利用Polars原生的when/then/otherwise表达式结合list.len()判断,无需复杂的map_batches嵌套,代码大幅简化:
def expr_extract_phone() -> pl.Expr: return ( pl.col("telecom") .list.eval(pl.element().filter(pl.element().struct["system"] == "phone").struct["value"]) .list.unique() .alias("phone_numbers") .when(pl.col("phone_numbers").list.len() > 0) .otherwise(None) )
关键逻辑说明:
- 保留原有的
list.eval过滤逻辑:从telecom数组中筛选出system为"phone"的对象,提取对应的value字段 list.unique()对提取到的手机号去重,得到唯一值列表- 使用
.when(列表长度>0).otherwise(None)直接替换空列表:当列表非空时保留原列表,否则返回None(即Polars中的null值)
这种写法完全基于Polars原生表达式API,逻辑清晰且性能更优,避免了不必要的LazyFrame嵌套操作。
内容的提问来源于stack exchange,提问作者teejay
相关产品推荐
相关产品推荐

