HOWTO · Pandas
将 Lambda 函数应用于 Pandas DataFrame
本指南说明如何使用 DataFrame.assign() 和 DataFrame.apply() 方法将 Lambda 函数应用于 pandas DataFrame。
本页内容
当任务适合用简短的单表达式函数完成时,可以在 pandas 中使用 Python lambda:用 DataFrame.assign() 创建列,用 DataFrame.apply() 按行或按列计算,用 Series.map() 转换值,并用布尔掩码筛选行。具体操作及其轴决定了 lambda 接收什么输入、返回什么结果。
lambda 函数在 pandas 中的作用
Python lambda 表达式会创建一个只包含单个表达式的小型匿名函数,例如 lambda value: value * 2。它描述要执行的计算;接收该函数的 pandas 操作决定函数处理的是整列、某一行,还是 Series 中的单个值。如果逻辑需要多条语句、需要重复使用,或用一个有意义的名称表达会更清晰,请改用命名的 def 函数。
使用 DataFrame.assign() 创建衍生列
DataFrame.assign() 会返回包含所需新增列或替换列的 DataFrame,原始 DataFrame 保持不变。可调用赋值接收 DataFrame,因此一个表达式可以使用一个或多个已有列。例如,df.assign(percentage=lambda data: data["marks"] / 1000 * 100) 根据分数计算百分比,而 df.assign(total=lambda data: data["math"] + data["science"]) 则将两列相加。新列会与 DataFrame 的索引对齐。
使用 DataFrame.apply() 按行或按列应用函数
DataFrame.apply() 默认逐列传入数据:axis=0 表示对各列应用函数,axis=1 表示对每一行应用函数。若要逐行计算,例如将某行的 base 与 bonus 相加,可以写成 df.apply(lambda row: row["base"] + row["bonus"], axis=1)。返回对象的类型取决于函数的返回值;每行返回一个标量时,结果是 Series。若只需对某列做简单算术运算,优先使用 pandas 向量化操作;与逐行调用 Python 相比,这种写法通常更清晰、速度也更快。
在 Series 中映射或筛选值
Python 内置的 map(function, values) 会转换每个输入值并返回迭代器;用 list(...) 转换后即可将结果完整取出。Series.map(function) 是 pandas 中对应的操作,会返回与原索引对齐的 Series。例如,df["age"].map(lambda age: age + 1) 会生成每个年龄加一后的值;在将结果赋值之前,不会更改 DataFrame。
Python 内置的 filter(predicate, values) 会保留谓词结果为真的输入值,并返回迭代器。筛选 pandas DataFrame 时,使用布尔掩码更直接,还能保留符合条件的行及其其他列:df[df["age"] < 25]。也可以筛选 Series:df["age"][df["age"] < 25]。两者结果不同:对 Series 使用 filter 会得到符合条件的值,而使用 DataFrame 布尔掩码则会选出完整的行。
使用 lambda 实现条件逻辑
条件表达式可以放在 lambda 的单个表达式中:lambda income: "Stable" if income >= 5000 else "Unstable"。将它应用于 Series 后,每个收入值都会对应一个标签;阈值包含边界,因此收入为 5000 时结果是 Stable,低于 5000 时结果是 Unstable。若要将结果用于整个 DataFrame,可以把它赋给一列,例如 df["category"] = df["income"].apply(lambda income: "Stable" if income >= 5000 else "Unstable")。
选择合适的方法并检查结果
用 assign() 添加列;当函数需要逐行或逐列处理数据时用 apply();用 Series.map() 转换每个值;用布尔掩码选出符合条件的行。赋值之前,请检查轴、传给 lambda 的输入,以及结果是 Series 还是 DataFrame。下面的完整示例使用相互关联的数据演示这些模式:
本节中的代码以及显示的标签或输出仍为英文。
import pandas as pd
df = pd.DataFrame({"name": ["Ari", "Bea", "Cal"], "math": [80, 92, 75], "science": [85, 88, 90], "income": [4000, 6000, 5000]})
result = df.assign(
total=lambda data: data["math"] + data["science"],
next_income=lambda data: data["income"].map(lambda value: value + 1000),
category=lambda data: data["income"].apply(lambda value: "Stable" if value >= 5000 else "Unstable"),
)
selected = result[result["total"] >= 170]
print(selected[["name", "total", "next_income", "category"]].to_string(index=False))