使用Polars对DataFrame列执行多操作时的重复报错及输出需求
使用Polars对DataFrame所有列执行多统计操作的正确姿势
问题场景
想用Polars对DataFrame的所有列执行多项统计操作,比如单独统计每列非空值数量时,代码可以正常运行:
df.select(pl.col("*").is_not_null().sum())
但尝试同时统计空值和非空值时,会触发Duplicated Error:
( df .select( pl.col("*").is_not_null().sum().alias("foo"), pl.col("*").is_null().sum().alias("bar") ) )
这是因为两次pl.col("*")操作后生成的列名完全重复,Polars不允许结果中存在重复列名。
现有可行方案(但步骤繁琐)
目前我采用分开统计再合并的方式实现需求:
a = ( df .select(pl.col("*").is_null().sum()) .transpose(include_header=True) .rename({"column_0" : "null_count"}) ) b = ( df .select(pl.col("*").is_not_null().sum()) .transpose(include_header=True) .rename({"column_0" : "not_null_count"}) ) a.join(b, how="left", on="column")
最终能得到预期格式的输出:
shape: (8, 3) ┌─────────────┬────────────┬────────────────┐ │ column ┆ null_count ┆ not_null_count │ │ --- ┆ --- ┆ --- │ │ str ┆ u32 ┆ u32 │ ╞═════════════╪════════════╪════════════════╡ │ InvoiceNo ┆ 0 ┆ 541909 │ │ StockCode ┆ 0 ┆ 541909 │ │ Description ┆ 1454 ┆ 540455 │ │ Quantity ┆ 0 ┆ 541909 │ │ InvoiceDate ┆ 0 ┆ 541909 │ │ UnitPrice ┆ 0 ┆ 541909 │ │ CustomerID ┆ 135080 ┆ 406829 │ │ Country ┆ 0 ┆ 541909 │ └─────────────┴────────────┴────────────────┘
更简洁的优化方案
不需要拆分多次操作,直接通过一次链式调用就能完成:
方案一:利用suffix标记列后转置重塑
( df .select( pl.col("*").is_null().sum().suffix("_null"), pl.col("*").is_not_null().sum().suffix("_not_null") ) .melt(variable_name="column", value_name="count") .with_columns( # 提取原始列名 original_col=pl.col("column").str.replace(r"_null$|_not_null$", ""), # 标记统计类型 stat_type=pl.col("column").str.extract(r"_null$|_not_null$") ) .pivot(index="original_col", columns="stat_type", values="count") .rename({"_null": "null_count", "_not_null": "not_null_count"}) .rename({"original_col": "column"}) )
方案二:先转置再分组统计(更直观高效)
( df # 转置后把原列名作为新列,原数据作为value列 .transpose(include_header=True, header_name="column", column_names=["value"]) # 按原列名分组,统计空值和非空值数量 .group_by("column") .agg( null_count=pl.col("value").is_null().sum(), not_null_count=pl.col("value").is_not_null().sum() ) )
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

