如何在Python中用两个DataFrame实现Excel的INDEX/MATCH功能?
问题描述
我用谷歌搜索到的方案都是merge操作,不符合我的需求。我有两个结构完全匹配(行数、列数一致)的DataFrame:
da(标签矩阵):
col0 col1 col2 col3 col4 col5 2023-08-14 06:30:01 B C D E F G 2023-08-14 06:30:01 B C D E F G 2023-08-14 06:30:02 B C D E F G 2023-08-14 06:30:03 B C D E F G 2023-08-14 06:30:04 B C D E F G 2023-08-14 06:30:05 B C D E F G 2023-08-14 06:30:06 A B C E F G 2023-08-14 06:30:07 A B C E F G
db(数值矩阵,与da位置一一对应):
col0 col1 col2 col3 col4 col5 2023-08-14 06:30:01 28 26 8 -7 -17 -14 2023-08-14 06:30:01 28 26 8 -7 -17 -14 2023-08-14 06:30:02 28 26 8 -5 -17 -14 2023-08-14 06:30:03 28 26 5 -5 -17 -14 2023-08-14 06:30:04 28 26 5 -11 -17 -14 2023-08-14 06:30:05 28 26 5 -11 -17 -10 2023-08-14 06:30:06 33 28 26 -11 -17 -10 2023-08-14 06:30:07 34 28 26 -11 -17 -10
我需要生成结果dc:以da中所有唯一标签为列,每行根据da的标签,从db对应位置取数填充,没有对应标签的列填0,最终效果如下:
A B C D E F G 2023-08-14 06:30:01 0 28 26 8 -7 -17 -14 2023-08-14 06:30:01 0 28 26 8 -7 -17 -14 2023-08-14 06:30:02 0 28 26 8 -5 -17 -14 2023-08-14 06:30:03 0 28 26 5 -5 -17 -14 2023-08-14 06:30:04 0 28 26 5 -11 -17 -14 2023-08-14 06:30:05 0 28 26 5 -11 -17 -10 2023-08-14 06:30:06 33 28 26 0 -11 -17 -10 2023-08-14 06:30:07 34 28 26 0 -11 -17 -10
我已经用以下代码生成了dc的列名,但不知道如何高效填充数据(不想逐行迭代):
from itertools import chain a = list(map(set,da.values.T)) b = list(set(chain.from_iterable(a))) dc = pd.DataFrame(columns = b)
解决方案
可以利用Pandas的堆叠(stack/unstack)操作实现无迭代的向量化处理,步骤如下:
- 先整理所有唯一标签并排序(保证列顺序和示例一致)
- 将da和db堆叠成长格式,对齐位置关系
- 重新构造索引为「时间+标签」的Series,再转成宽格式并填充0
完整代码:
import pandas as pd from itertools import chain # 1. 获取所有唯一标签并按字母排序 all_cols = sorted(set(chain.from_iterable(da.values))) # 2. 将da和db堆叠,保留原始时间索引和位置对应关系 da_stack = da.stack() db_stack = db.stack() # 3. 构造以(时间, 标签)为索引的数值Series combined_series = pd.Series( db_stack.values, index=pd.MultiIndex.from_tuples( zip(da_stack.index.get_level_values(0), da_stack.values) ) ) # 4. 转成宽格式,缺失值填充0,并按指定列顺序整理 dc = combined_series.unstack(fill_value=0).reindex(columns=all_cols)
代码说明:
stack()将DataFrame从宽格式转成长格式,自动保留原始行索引(时间)和列的位置信息- 构造MultiIndex时,把da的标签作为二级索引,和db的数值一一绑定
unstack()将长格式转回宽格式,fill_value=0自动给不存在的标签列填充0reindex(columns=all_cols)确保列顺序和预期一致
如果你的da和db没有显式的时间索引,需要先把第一列设为索引:
da = da.set_index(da.columns[0]) db = db.set_index(db.columns[0])
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

