如何正确将apply函数的返回值赋值给DataFrame的两列?
解决DataFrame赋值函数返回值出现NaN的问题
问题原因
你的代码赋值后出现NaN,核心是函数返回的Series索引与目标列名不匹配:
- 函数
verif返回的Series键是e和c,但你要赋值的目标列是S和COMMENT - pandas无法自动匹配不对应的列名,导致赋值失败,最终填充NaN
解决方案
方案1:修改函数返回的Series索引,匹配目标列名
直接让函数返回的Series索引和要赋值的列名一致,这样apply后的结果可以直接赋值:
import pandas as pd df = pd.DataFrame({ 'nombre': [10, 25, 42, 18, 73] }) df["COMMENT"] = df["S"] = None def verif(row): if row["nombre"] % 10 == 0: comment = "Ends with 0" status = "OK" else: comment = "Do not end with 0" status = "KO" # 返回索引为目标列名的Series return pd.Series([status, comment], index=["S", "COMMENT"]) mask = df["nombre"] % 2 == 0 df.loc[mask, ["S", "COMMENT"]] = df.loc[mask].apply(verif, axis=1)
方案2:保留原函数,手动映射列名赋值
如果不想修改函数,可以先获取apply的结果,再分别将对应列的值赋值到目标列:
import pandas as pd df = pd.DataFrame({ 'nombre': [10, 25, 42, 18, 73] }) df["COMMENT"] = df["S"] = None def verif(row): if row["nombre"] % 10 == 0: c = "Ends with 0" e = "OK" else: c = "Do not end with 0" e = "KO" return pd.Series({"e": e, "c": c}) mask = df["nombre"] % 2 == 0 # 获取函数执行结果 result = df.loc[mask].apply(verif, axis=1) # 分别映射赋值 df.loc[mask, "S"] = result["e"] df.loc[mask, "COMMENT"] = result["c"]
方案3:用矢量化操作替代apply(更高效)
大数据量下apply效率较低,推荐用矢量化的方式直接处理:
import pandas as pd df = pd.DataFrame({ 'nombre': [10, 25, 42, 18, 73] }) df["COMMENT"] = df["S"] = None mask = df["nombre"] % 2 == 0 # 针对筛选后的行直接赋值 df.loc[mask, "S"] = df.loc[mask, "nombre"].apply(lambda x: "OK" if x % 10 == 0 else "KO") df.loc[mask, "COMMENT"] = df.loc[mask, "nombre"].apply(lambda x: "Ends with 0" if x % 10 == 0 else "Do not end with 0")
内容的提问来源于stack exchange,提问作者dia05
相关产品推荐
相关产品推荐

