如何在Pandas链式调用中无需pipe,用Lambda实现DataFrame合并?
不借助pipe方法,在Pandas链式调用中用lambda基于上一个DataFrame状态调用merge的方案
问题背景
需要在Pandas方法链式调用的前提下,不使用pipe方法,通过lambda函数基于上一个DataFrame的状态调用merge方法。
可运行但依赖pipe的代码
以下代码通过pipe实现需求,能正常运行:
import pandas as pd (pd.DataFrame( [{'YEAR':2013,'FK':1, 'v':1}, {'YEAR':2013,'FK':2, 'v':2}, {'YEAR':2014,'FK':1, 'v':3}, {'YEAR':2014,'FK':2, 'v':4} ]) .pipe(lambda w: w.merge(w.query('YEAR==2013')[['FK','v']], on='FK', how='left' )) )
错误尝试及报错信息
直接将lambda传入merge的写法无法运行:
import pandas as pd (pd.DataFrame( [{'YEAR':2013,'FK':1, 'v':1}, {'YEAR':2013,'FK':2, 'v':2}, {'YEAR':2014,'FK':1, 'v':3}, {'YEAR':2014,'FK':2, 'v':4} ]) .merge(lambda w: w.query('YEAR==2013'), on='FK', how='left' ) )
报错信息(已翻译):
TypeError: 只能合并Series或DataFrame对象,传入了一个<class 'function'>类型的对象
解决方案
merge方法的第一个参数必须是DataFrame或Series对象,不能直接传入lambda函数。要在链式调用中不依赖pipe,可以通过立即执行lambda函数的方式,用上一步的DataFrame(用_表示)作为参数传入,得到符合要求的DataFrame后再传入merge。
方案1:使用立即执行的lambda
import pandas as pd (pd.DataFrame( [{'YEAR':2013,'FK':1, 'v':1}, {'YEAR':2013,'FK':2, 'v':2}, {'YEAR':2014,'FK':1, 'v':3}, {'YEAR':2014,'FK':2, 'v':4} ]) .merge((lambda df: df.query('YEAR==2013')[['FK','v']])(_), on='FK', how='left' ) )
方案2:直接使用_简化写法
其实可以不用lambda,直接用链式调用的占位符_代表上一步的DataFrame,直接调用query处理后传入merge:
import pandas as pd (pd.DataFrame( [{'YEAR':2013,'FK':1, 'v':1}, {'YEAR':2013,'FK':2, 'v':2}, {'YEAR':2014,'FK':1, 'v':3}, {'YEAR':2014,'FK':2, 'v':4} ]) .merge(_.query('YEAR==2013')[['FK','v']], on='FK', how='left' ) )
说明
- 链式调用中的
_是Pandas提供的占位符,代表上一步操作返回的DataFrame对象 - 两种方案都避免了使用
pipe,直接基于上一步的DataFrame状态完成merge操作
内容的提问来源于stack exchange,提问作者the_RR
相关产品推荐
相关产品推荐

