Python pandas 三元素元组索引DataFrame左连接匹配方案
元组索引匹配DataFrame行号实现方案
问题说明
存在两个pandas DataFrame:
points:行索引为3个数值组成的元组,元组内每个元素对应Dates表的行序号Dates:存储日期及对应点位数据的维度表
需求为实现类VLOOKUP的左连接效果,根据points索引中的行号匹配Dates的日期值,为points新增3个日期列。
常规merge方法无法直接使用,因为匹配规则存储在行索引的元组中,而非独立列,以下无效代码无法运行:
result = pd.merge(points, Dates, on="idx")
初始测试数据代码如下:
idx = [(0,1,2),(0,5,7)] data = {'pointx': [11, 35], 'pricey': [1119, 943.7],} points = pd.DataFrame(data, index = idx) print(points) initial_data = {'points': [4, 11, 16, 23, 31, 35, 39, 46], 'Date': ['16/12/2021', '28/12/2021', '4/1/2022', '13/1/2022', '26/1/2022', '1/2/2022', '7/2/2022', '16/2/2022'], 'High': [994.97998, 1119, 1208, 1115.599976, 987.690002, 943.700012, 947.77002, 926.429993],} Dates = pd.DataFrame(initial_data) print(Dates)
实现代码
由于匹配依据是Dates的行位置序号,不需要走关联键匹配的merge逻辑,直接按位置取值性能最高。
版本1:numpy高性能实现(推荐,数据量大时速度快)
import pandas as pd import numpy as np # 将元组索引转为二维位置数组 pos_arr = np.array(points.index.tolist()) # 按位置批量取出对应日期,再重塑为和索引维度一致的形状 matched_dates = Dates['Date'].iloc[pos_arr.flatten()].values.reshape(pos_arr.shape) # 赋值为3个新日期列 points[['date_col1', 'date_col2', 'date_col3']] = matched_dates
版本2:纯pandas无依赖实现(无需numpy,小数据量使用方便)
points[['date_col1', 'date_col2', 'date_col3']] = [ [Dates['Date'].iloc[pos] for pos in idx_item] for idx_item in points.index ]
注意:以上代码默认索引元组中的所有数值都是Dates表的有效行号,如果存在超出Dates表长度的无效行号,需要提前加异常判断逻辑
运行结果
执行代码后points输出如下,完全符合预期:
pointx pricey date_col1 date_col2 date_col3 (0, 1, 2) 11 1119.0 16/12/2021 28/12/2021 4/1/2022 (0, 5, 7) 35 943.7 16/12/2021 1/2/2022 16/2/2022
内容的提问来源于stack exchange,提问作者Artrade
相关产品推荐
相关产品推荐

