where和mask:Pandas中强大的条件替换工具

where 和 mask 提供类似 if-else 的替换功能,可以方便的在 DataFrame 中处理缺失值和异常值。
数据分析
Author

Tom

Published

May 25, 2025

在数据清洗中常常碰到需要根据某些条件对已有数据进行更新的情况,比如下面的例子中,需要根据修改后的论文题目对已有的论文数据进行更新。

import pandas as pd
import numpy as np

title = pd.DataFrame(
    {
        "学号": [123, 234, 345, 456],
        "论文题目": ["A", "B", "C", "D"],
        "修改后的题目": ["E", np.nan, np.nan, "F"],
    },
)
title
学号 论文题目 修改后的题目
0 123 A E
1 234 B NaN
2 345 C NaN
3 456 D F

Pandas 提供了一个 where 方法,可以根据条件对 DataFrame 中的值进行更新。对于需要更新的行,可以使用 where 方法来指定条件,并将满足条件的行更新为新的值。对于上面的例子:

title
学号 论文题目 修改后的题目
0 123 A E
1 234 B NaN
2 345 C NaN
3 456 D F
title.loc[:, ["论文题目"]].where(
    title.loc[:, "修改后的题目"].isna(), title.loc[:, "修改后的题目"], axis=0
)
论文题目
0 E
1 B
2 C
3 F

以上示例中 title.loc[:, "修改后的题目"].isna() 返回一个布尔 Series,表示哪些行的“修改后的题目”列是缺失值,即论文题目没有修改。where 方法会保留满足条件的值,将不满足条件的值进行更新。即将论文题目修改过的(“修改后的题目”为非空的)更新为“修改后的题目”。

where 方法

where 方法的基本语法如下:

DataFrame.where(cond, other=nan, inplace=False, axis=None, level=None, errors='raise')

其中,cond 是一个布尔条件,用于指定哪些行需要更新,other 是用于替换的值,inplace 参数决定是否在原 DataFrame 上进行操作。

基本使用方法

df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})
print("原始DataFrame:")
print(df)

# 保留满足条件的值,不满足的替换为 NaN
res = df.where(df > 2)
print("\n保留大于2的值:")
print(res)
原始DataFrame:
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

保留大于2的值:
     A  B  C
0  NaN  4  7
1  NaN  5  8
2  3.0  6  9

指定替换值(other参数

# 不满足条件的替换为 -1
res = df.where(df > 2, -1)
print("原始DataFrame:")
print(df)
print("\n小于2的值替换值为-1:")
print(res)
原始DataFrame:
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

小于2的值替换值为-1:
   A  B  C
0 -1  4  7
1 -1  5  8
2  3  6  9
# 也可以使用另一个 DataFrame 作为替换值
other_df = pd.DataFrame({"A": [-1, -1, -1], "B": [-2, -2, -2], "C": [-3, -3, -3]})
res = df.where(df > 2, other_df)
print("\n使用另一个DataFrame作为替换值:")
print(res)

使用另一个DataFrame作为替换值:
   A  B  C
0 -1  4  7
1 -1  5  8
2  3  6  9

使用函数作为判断条件

# 使用lambda函数作为条件
res = df.where(lambda x: x % 2 == 0, -1)
print("\n使用函数作为条件:")
print(res)

使用函数作为条件:
   A  B  C
0 -1  4 -1
1  2 -1  8
2 -1  6 -1

按列应用不同条件

conditions
A B C
0 False False True
1 True True False
2 True True False
# 对不同的列应用不同的条件
conditions = pd.DataFrame({"A": df["A"] > 1, "B": df["B"] > 4, "C": df["C"] < 8})
res = df.where(conditions, -1)
print("原始DataFrame:")
print(df)
print("\n条件DataFrame:")
print(conditions)
print("\n按列应用不同条件:")
print(res)
原始DataFrame:
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

条件DataFrame:
       A      B      C
0  False  False   True
1   True   True  False
2   True   True  False

按列应用不同条件:
   A  B  C
0 -1 -1  7
1  2  5 -1
2  3  6 -1

mask 方法

maskwhere 参数一致,但功能相反,它用于替换满足条件的值,而保留不满足条件的值。例如:

df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})
print("原始DataFrame:")
print(df)

# 替换满足条件的值为NaN
res = df.mask(df > 2)
print("\n使用mask后的结果:")
print(res)
原始DataFrame:
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

使用mask后的结果:
     A   B   C
0  1.0 NaN NaN
1  2.0 NaN NaN
2  NaN NaN NaN

总结一下,wheremask 是 Pandas 中非常强大的条件替换工具,可以:

  • 根据条件保留或替换值
  • 使用标量、DataFrame 或 Series 作为替换值
  • 支持函数作为条件
  • 可以原地修改或返回新对象