基于指定索引与列快速选取Pandas DataFrame元素的优化方案
Pandas 高效提取DataFrame指定位置值的方法
问题场景
给定带索引与列的Pandas DataFrame,以及一个Series:该Series的索引对应DataFrame的列名,值为对应列中的某行索引。需要提取DataFrame中这些行列交叉位置的值,组成列表或Series。
原实现(低效非向量化)
用户最初使用循环遍历的方式,速度较慢:
result = pd.Series() for c, i in sr.items(): result[c] = df.loc[i, c]
高效向量化解决方案
方法1:利用numpy索引(性能最优)
直接操作DataFrame的底层numpy数组,通过行列的位置索引提取值:
# 获取列名在DataFrame中的位置索引 col_indices = df.columns.get_indexer(sr.index) # 获取行索引在DataFrame中的位置索引 row_indices = df.index.get_indexer(sr.values) # 提取对应值并转为Series result = pd.Series(df.values[row_indices, col_indices], index=sr.index)
方法2:使用df.lookup(注意版本兼容性)
df.lookup是专门用于按行索引和列名提取值的方法,但在pandas 1.2.0及以上版本已被标记为弃用,适合旧版本使用:
result = pd.Series(df.lookup(sr.values, sr.index), index=sr.index)
方法3:长格式合并(无版本限制,兼容性好)
将DataFrame转为长格式后,与Series合并匹配:
# 将DataFrame转为长格式,保留原索引和列名 melted_df = df.reset_index().melt(id_vars='index', var_name='column', value_name='value') # 将Series转为DataFrame,统一字段名用于合并 sr_df = sr.reset_index().rename(columns={'index': 'column', 0: 'index'}) # 合并后提取目标值并重构Series result = melted_df.merge(sr_df, on=['index', 'column'])['value'].set_index(sr.index)
以上三种方法均为向量化操作,避免了循环遍历,在处理大数据集时性能远优于原循环实现,其中方法1的执行效率最高。
内容的提问来源于stack exchange,提问作者DisplayName007
相关产品推荐
相关产品推荐

