如何跨两个DataFrame按行取多列最大值并赋值至目标列
嗨,我来帮你解决这个问题!首先得明确你的核心需求:每行都要取dfOne.colA、dfOne.colB和dfTwo.colH这三个值的最大值,然后赋值给dfOne.colMax对吧?你之前踩的坑其实是用了Python内置的max()函数——这个函数是用来比较整个对象的,不是逐元素(逐行)比较的,所以才会出问题。下面给你几个靠谱的解决方案,顺便解答你备注里的疑问。
方法一:用Pandas的combine方法(直接引用单个列)
这个方法完全符合你想要的「不用dfOne[['colA', 'colB']],而是直接用dfOne.colA/dfOne.colB」的需求,逻辑也很直观:
# 先逐行取dfOne.colA和dfOne.colB的最大值 ab_max = dfOne['colA'].combine(dfOne['colB'], max) # 再逐行和dfTwo.colH取最大值,赋值给colMax dfOne['colMax'] = ab_max.combine(dfTwo['colH'], max)
combine方法就是专门用来对两个Series做逐元素操作的,这里传入max函数就会逐行比较两个值取最大。
方法二:用Numpy的maximum(最简洁高效)
Numpy的np.maximum支持元素级的比较,而且可以嵌套使用来处理多个值:
import numpy as np # 嵌套调用np.maximum,逐行取三个列的最大值 dfOne['colMax'] = np.maximum(np.maximum(dfOne['colA'], dfOne['colB']), dfTwo['colH'])
这个写法非常简洁,而且运算效率很高,适合处理大数据量的情况。
方法三:临时合并列后取最大值(适合多列场景)
如果以后需要处理更多列,也可以先把dfTwo.colH临时合并到dfOne,然后直接取多列的逐行最大值:
# 合并dfTwo.colH到dfOne,然后取三列的逐行最大值 dfOne['colMax'] = dfOne[['colA', 'colB']].join(dfTwo['colH']).max(axis=1) # 如果不想保留临时添加的colH,可以删掉 # dfOne.drop('colH', axis=1, inplace=True)
为什么你之前的写法不对?
你用max(dfTwo.colH, dfOne[['colA', 'colB']].min(axis=1))的时候,Python内置的max()是把整个Series当作一个整体来比较的,返回的是整个Series的全局最大值,而不是每行对应位置的最大值。必须用支持元素级操作的方法(比如上面的combine或np.maximum)才能实现逐行处理的需求。
关于你备注里的疑问
当然有不用dfOne[['colA', 'colB']]的写法!上面的方法一和方法二都是直接引用单个列(dfOne['colA']/dfOne.colA)来操作的,不需要把它们放进一个临时DataFrame里。
备注:内容来源于stack exchange,提问作者SoftwareTester

