Pandas基于key列最小值选取对应value列值且不新增辅助列的实现方法
问题描述
我有如下结构的Pandas DataFrame,列以x_1、x_2的配对形式存在:
import pandas as pd df = pd.DataFrame( { 'A_1': [20, 30, 500], 'A_2': [40, 60, 1000], 'B_1': [35, 12, 600], 'B_2': [70, 24, 1200], } ) print(df)
输出:
A_1 A_2 B_1 B_2 0 20 40 35 70 1 30 60 12 24 2 500 1000 600 1200
列的配对关系存储在如下字典中:
comp_cols = { 'A_1': 'A_2', 'B_1': 'B_2', }
我的需求是:对每一行,先在字典key对应的列[A_1, B_1]中定位最小值对应的列,再提取该key列配对的value列的对应行值。我目前的实现需要新增额外的辅助列:
df['min_1_col'] = df[comp_cols.keys()].idxmin(axis=1) df['min_2_val'] = df.apply(lambda x: x[comp_cols[x['min_1_col']]], axis=1) print(df)
输出:
A_1 A_2 B_1 B_2 min_1_col min_2_val 0 20 40 35 70 A_1 40 1 30 60 12 24 B_1 24 2 500 1000 600 1200 A_1 1000
有没有更优雅的实现方式,可以不新增辅助列就完成上述需求?
解决方案
这里提供两种无辅助列的实现方式:
方案1:高性能向量化实现(推荐,兼容全版本Pandas)
基于Numpy的索引操作实现,性能远高于apply方案,适合各类数据量场景:
import numpy as np # 提取配对的key列和对应value列 key_cols = list(comp_cols.keys()) val_cols = [comp_cols[k] for k in key_cols] # 一步计算得到目标列,无任何中间辅助列 df['min_2_val'] = df[val_cols].to_numpy()[np.arange(len(df)), df[key_cols].to_numpy().argmin(axis=1)]
方案2:简洁易读实现
适合中小数据量,代码逻辑更直观:
df['min_2_val'] = df.lookup(df.index, df[comp_cols.keys()].idxmin(axis=1).map(comp_cols))
注:lookup方法在Pandas 1.2.0及以上版本被标记为弃用,生产环境优先使用第一种numpy向量化方案,兼容性和性能更优。
两种方案输出结果与你原有实现完全一致,且不需要新增任何中间辅助列。
内容的提问来源于stack exchange,提问作者CarloP
相关产品推荐
相关产品推荐

