如何高效实现Pandas中按元组第二个元素取单元格列表最大值?
高效获取Pandas列中基于元组第二个元素的最大元组方案
原始DataFrame
import pandas as pd df = pd.DataFrame( { 'c1': ['a','b','c'], 'c2': [[1,2],[4,5,6],[7,8,9,0]], 'c3': [[(10,1),(20,2)],[(40, 4),(50,5),(60,6)],[(70,7),(80,8),(90,9),(0,0)]] } )
输出结果:
c1 c2 c3 0 a [1, 2] [(10, 1), (20, 2)] 1 b [4, 5, 6] [(40, 4), (50, 5), (60, 6)] 2 c [7, 8, 9, 0] [(70, 7), (80, 8), (90, 9), (0, 0)]
需求
基于c3列每个单元格内元组的第二个元素,找出该单元格中的最大元组,最终得到如下结果:
c1 c2 c3 maxi 0 a [1, 2] [(10, 1), (20, 2)] (20,2) 1 b [4, 5, 6] [(40, 4), (50, 5), (60, 6)] (60,6) 2 c [7, 8, 9, 0] [(70, 7), (80, 8), (90, 9), (0, 0)] (90,9)
数据量约4万行,需要保证处理性能。
现有方案及问题
当前使用的方案:
df['maxi'] = df['c3'].apply(max, key= lambda v: v[1])
apply方法在处理大量数据时存在额外的函数调用开销,性能表现不佳。
高效替代方案
方案1:列表推导式
列表推导式是Python原生循环实现,相比apply省去了Pandas的函数调度开销,性能提升明显:
df['maxi'] = [max(lst, key=lambda x: x[1]) for lst in df['c3']]
方案2:结合numpy.vectorize(可选)
如果偏好向量化风格的代码,可以使用numpy.vectorize封装逻辑,本质仍是循环,性能和列表推导式接近:
import numpy as np get_max_tuple = np.vectorize(lambda lst: max(lst, key=lambda x: x[1])) df['maxi'] = get_max_tuple(df['c3'])
性能说明
对于4万行数据,列表推导式的处理速度通常是apply的2-3倍以上,能有效降低处理时间。
内容的提问来源于stack exchange,提问作者Selva
相关产品推荐
相关产品推荐

