如何在Polars DataFrame中将单元格X替换为1并保留其他列?
Polars替换DataFrame中"X"为1、空值为0的正确姿势
需求说明
刚接触Polars,想把DataFrame里所有单元格的"X"换成1,空值(None)换成0,同时保留那些不需要修改的列。举个例子:
原DataFrame
import polars as pl df = pl.DataFrame({"A": ["X", None], "B": [None, "X"]})
原数据展示:
shape: (2, 2) ┌──────┬──────┐ │ A ┆ B │ │ --- ┆ --- │ │ str ┆ str │ ╞══════╪══════╡ │ X ┆ null │ │ null ┆ X │ └──────┴──────┘
想要的结果
shape: (2, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 0 │ │ 0 ┆ 1 │ └─────┴─────┘
我现在写的代码
# 替换规则 mapper = { "X": 1, None: 0, } # 列名列表 columns = pdf.columns # 循环替换 for x in columns: pdf = pdf.select(pl.all().replace(mapper))
代码里的问题
你这段代码有两个没必要的问题:
- 循环遍历列名,但每次都用
pl.all()对所有列做替换,等于重复操作了N次(N是列数),完全多余 - 直接用
replace替换后,列的类型还是字符串,不会自动转成整数,而且用None当字典键在Polars里有时候会有隐式的类型问题
几种正确的写法
写法1:批量替换+类型转换(最简洁)
直接对所有字符串列做替换,转成整数,其他列原样保留:
import polars as pl df = pl.DataFrame({"A": ["X", None], "B": [None, "X"], "C": ["测试", "保留"]}) # 加个要保留的列示例 mapper = {"X": 1, None: 0} # 只处理字符串列,替换后转整数,其他列不动 result_df = df.with_columns( pl.col(pl.Utf8).replace(mapper).cast(pl.Int64) ) print(result_df)
输出结果:
shape: (2, 3) ┌─────┬─────┬──────┐ │ A ┆ B ┆ C │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪══════╡ │ 1 ┆ 0 ┆ 测试 │ │ 0 ┆ 1 ┆ 保留 │ └─────┴─────┴──────┘
写法2:条件表达式(逻辑更清晰)
如果觉得字典替换不够直观,用when/then写条件逻辑更清楚:
result_df = df.with_columns( pl.col(pl.Utf8) .when(pl.col() == "X", 1) # 遇到X就换成1 .when(pl.col().is_null(), 0) # 遇到空值换成0 .otherwise(pl.col()) # 其他内容保留(如果是字符串的话,要是想转数值可以改这里) .cast(pl.Int64) )
写法3:只处理指定列
要是不想改所有字符串列,只想改特定的几列,直接指定列名就行:
target_cols = ["A", "B"] result_df = df.with_columns( pl.col(target_cols).replace(mapper).cast(pl.Int64) )
重点提醒
- Polars是列式计算框架,尽量别用循环,向量化操作性能高得多
- 替换完一定要用
cast(pl.Int64)把列转成整数类型,不然列还是字符串格式 - 用
with_columns而不是select,这样能保留所有原有列,只修改需要的列
内容的提问来源于stack exchange,提问作者Manuel
相关产品推荐
相关产品推荐

