Pandas中apply方法传递多自定义参数(含df对象)的实现方法
Pandas apply 传递多参数的正确实现方案
你现在的问题根源
- 首先卡你的根本不是apply的传参逻辑,是你写的自定义函数本身就有Python语法硬伤:Python 语法不允许带默认值的参数,排在没有默认值的参数前面。
你定义的def do_something(x,test="testFoo",df)只要运行到这行定义代码,就会直接报SyntaxError,根本跑不到调用apply的阶段。 - 其实pandas的apply传参逻辑很简单:遍历出来的每行/每列,会作为第一个位置参数传给你的自定义函数;你在apply括号里额外传的所有关键字参数,都会原封不动转发给自定义函数,不存在apply不认自定义参数的情况。
正确的实现步骤
先把函数改到符合Python语法规则
把无默认值的参数调整到带默认值参数的前面,保证函数本身能正常定义:- 如果你愿意调整参数顺序,直接把需要必传的df移到test前面即可:
def do_something(x, df, test="testFoo"): # 这里x对应apply遍历到的当前行,df是你额外传入的全量DataFrame pass - 如果你不想改动原来的参数顺序(想让test在df前面),给df补个默认值就行,哪怕先设成None:
def do_something(x, test="testFoo", df=None): pass
- 如果你愿意调整参数顺序,直接把需要必传的df移到test前面即可:
apply的调用写法不需要大改
等函数定义合法了,你之前尝试的df2.apply(do_something, test="testBar", df=df, axis=1)可以直接正常跑通:- apply执行遍历的时候,会自动把每一行的数据塞进
x这个形参里 - 你显式传的
test="testBar"、df=df两个关键字参数,会自动匹配函数的对应形参,不会和apply自带的axis这类参数抢位置。
- apply执行遍历的时候,会自动把每一行的数据塞进
容易踩的额外坑
- 要是想给自定义函数传位置参数,千万别直接把参数写在apply的参数列表里,必须放到
args元组里。比如同样的函数,想以位置参数的方式传df,得写成:df2.apply(do_something, axis=1, args=(df,), test="testBar")
要是直接把df当位置参数写在函数名后面,会被apply识别成自己的axis参数,直接报类型错误。 - 不用担心apply会把你传的df覆盖遍历出来的行数据:apply只会固定把遍历对象当第一个位置参数传入,不会乱改你传的关键字参数值。
内容的提问来源于stack exchange,提问作者nipy
相关产品推荐
相关产品推荐

