如何在Pandas中单次遍历高效获取DataFrame最小值及对应行列位置
解决方案
单次扫描实现(基于Numpy,性能最优)
你原来的3次min()调用确实会触发3次全量数据扫描,用Numpy的argmin配合unravel_index可以实现单次遍历拿到全部结果,代码如下:
import pandas as pd import numpy as np data = pd.DataFrame([ ['A', 'asdf', 1, 2, 3], ['B', 'zxcv', 4, 5, 6], ['C', 'qwer', 2, 5, 3], ['D', 'hjkl', 3, 9, 4], ], columns=['entity', 'code', '2007', '2008', '2009']).set_index('entity') data_num = data.drop(columns=['code']) # 核心逻辑,仅扫描1次数据 arr = data_num.to_numpy() min_flat_idx = arr.argmin() min_row_idx, min_col_idx = np.unravel_index(min_flat_idx, arr.shape) # 映射回原DataFrame的行名、列名 minval = arr[min_row_idx, min_col_idx] minval_row = data_num.index[min_row_idx] minval_col = data_num.columns[min_col_idx] print(minval, minval_row, minval_col) # 输出:1 A 2007
argmin会遍历数组1次拿到最小值的扁平化索引,unravel_index仅做坐标转换,无额外数据扫描开销,大数据集下性能比原写法高3倍以上。
纯Pandas实现(无Numpy依赖)
如果不想引入Numpy调用,也可以用stack+idxmin实现,性能介于原写法和Numpy方案之间:
minval_row, minval_col = data_num.stack().idxmin() minval = data_num.loc[minval_row, minval_col]
关于to_numpy()是否产生副本的说明
你的判断正确:当DataFrame所有列的dtype完全一致时,to_numpy()默认返回原数据的视图,不会产生副本。你可以通过修改返回的numpy数组元素,观察原DataFrame是否同步变化验证这一点。
只有当DataFrame存在混合dtype、或使用pandas扩展类型(如可空Int64、字符串Dtype)时,
to_numpy()才会触发类型转换生成副本,你当前的场景全为int类型的数值列,完全不会有复制开销。
内容的提问来源于stack exchange,提问作者shadowtalker
相关产品推荐
相关产品推荐

