如何对pandas DataFrame逐行应用返回多行DF的函数并合并结果
问题说明
我的问题与Stack Overflow上一则关于「apply返回DataFrame后和原DataFrame合并」的问题相关,现有代码如下:
import pandas as pd col = ['State','Annual Salary'] dat = [['New York', 132826], ['New Hampshire',128704], ['California',127388], ['Vermont',121599], ['Idaho',120011]] df = pd.DataFrame(dat, columns=col) def get_taxes_from_api(state, annual_salary): return pd.DataFrame({'State': [state, state], 'annual.fica.amount': [int(annual_salary * 0.067), int(annual_salary * 1.067)], 'annual.federal.amount': [int(annual_salary * 0.3), int(annual_salary * 1.3)], 'annual.state.amount': [int(annual_salary * 0.048), int(annual_salary * 1.048)]})
需求是将get_taxes_from_api应用到原df的每一行,再把所有函数返回的DataFrame合并为一个统一的DataFrame。
和已有问题的场景差异:我的自定义函数返回的是多行DataFrame,而非单行DataFrame,原有适配单行返回的方案无法直接使用。
解决方案
针对逐行调用返回多行DataFrame的场景,直接用列表收集所有返回结果后一次性合并即可,两种常用写法如下:
- 方法1:iterrows遍历 + concat(推荐,性能更好)
逐行遍历原DataFrame传入参数,把每个子DataFrame存入列表,最后调用pd.concat一次性合并、重置索引即可:result = pd.concat( [get_taxes_from_api(row['State'], row['Annual Salary']) for _, row in df.iterrows()], ignore_index=True ) - 方法2:apply写法
如果更习惯用apply的链式写法,可以把apply返回的所有子DataFrame转成列表再合并:result = pd.concat( df.apply(lambda x: get_taxes_from_api(x['State'], x['Annual Salary']), axis=1).to_list(), ignore_index=True )
两种写法得到的结果完全一致,每个州对应2行税务计算结果,前2行输出样例如下:
State annual.fica.amount annual.federal.amount annual.state.amount 0 New York 8899 39847 6375 1 New York 141725 172673 139201
如果后续要给接口调用加超时、异常重试、并发逻辑,第一种遍历写法的可扩展性更高。
内容的提问来源于stack exchange,提问作者GoldenYoyo
相关产品推荐
相关产品推荐

