Pandas多层索引场景下使用.apply计算fw1、fw2的实现及优化问题
错误原因
你写的apply方法存在两个核心问题:
- 逐行遍历时拿到的
row是单条数据的Series对象,它的index属性对应的是多层列索引,你需要的行索引值实际存在row.name属性里 - 多层列索引顺序写反了:pivot时
values参数对应的是第一层列名,columns参数对应的是第二层列名,所以正确的列访问格式是(price字段, C/P),不是反过来
修复后的apply实现
fwd_fast = ( df.reset_index() .pivot(index='index', columns='type', values=['price1', 'price2']) .dropna() ) # 修复后的apply写法 res = fwd_fast.apply( lambda row: pd.Series( [ row.name + row[('price1', 'C')]/2 - row[('price2', 'P')]/2, row.name + row[('price2', 'C')]/2 - row[('price1', 'P')]/2 ], index=['fw1', 'fw2'] ), axis=1, result_type='expand' ) max_fw = res['fw1'].max() min_fw = res['fw2'].min()
更高效的向量化实现(推荐)
apply本质还是Python层面的逐行遍历,对于大数据量场景,直接用pandas向量化运算性能会高10~100倍,所有计算都在C扩展中执行,可以把秒级运行耗时降到毫秒级:
fwd_fast = ( df.reset_index() .pivot(index='index', columns='type', values=['price1', 'price2']) .dropna() ) # 全量向量化计算,无任何遍历逻辑 fwd_fast['fw1'] = fwd_fast.index + fwd_fast[('price1','C')]/2 - fwd_fast[('price2','P')]/2 fwd_fast['fw2'] = fwd_fast.index + fwd_fast[('price2','C')]/2 - fwd_fast[('price1','P')]/2 max_fw = fwd_fast['fw1'].max() min_fw = fwd_fast['fw2'].min()
内容的提问来源于stack exchange,提问作者Mac Fly
相关产品推荐
相关产品推荐

