You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何快速从另一个时序DataFrame映射时序DataFrame的值

问题描述

我有两个时序DataFrame:

from pandas import Timestamp
import pandas as pd

df1 = pd.DataFrame(index=[Timestamp('2023-12-22 00:01:00'), Timestamp('2023-12-22 00:02:00')], 
                   columns=['Peter', 'Adam'], 
                   data=[['A', 'C'], ['C', 'D']])

df2 = pd.DataFrame(index=[Timestamp('2023-12-22 00:01:00'), Timestamp('2023-12-22 00:01:00'),
                          Timestamp('2023-12-22 00:01:00'), Timestamp('2023-12-22 00:01:00'),
                          Timestamp('2023-12-22 00:02:00'), Timestamp('2023-12-22 00:02:00'),
                          Timestamp('2023-12-22 00:02:00'), Timestamp('2023-12-22 00:02:00')], 
                   columns=['Level', 'Score'], 
                   data=[['A', 1], ['B', 2], ['C', 3], ['D', 4], ['A', 5], ['B', 6], ['C', 7], ['D', 8]])

df1内容:

Peter Adam
2023-12-22 00:01:00     A    C
2023-12-22 00:02:00     C    D

df2内容:

Level  Score
2023-12-22 00:01:00     A      1
2023-12-22 00:01:00     B      2
2023-12-22 00:01:00     C      3
2023-12-22 00:01:00     D      4
2023-12-22 00:02:00     A      5
2023-12-22 00:02:00     B      6
2023-12-22 00:02:00     C      7
2023-12-22 00:02:00     D      8

我希望得到如下结果:

Peter Adam
2023-12-22 00:01:00     1    3
2023-12-22 00:02:00     7    8

虽然可以通过循环、按列遍历df1并使用apply等方法实现,但我认为存在更高效的转换方式,请问有什么解决方案?


解决方案

方法1:构建多级索引映射批量替换

先将df2转换为以时间索引+Level为键的映射关系,再直接匹配df1的元素:

# 构建(时间, Level)到Score的映射
score_map = df2.set_index([df2.index, 'Level'])['Score']

# 按行索引+元素值匹配映射
result = df1.apply(lambda col: col.combine(col.index, lambda x, idx: score_map.loc[(idx, x)]))

方法2:转宽表后对齐匹配

把df2从长表转为宽表,让Level作为列,直接和df1的结构对齐取值:

# 将df2转为宽表,时间为行索引,Level为列
df2_wide = df2.pivot(index=df2.index, columns='Level', values='Score')

# 按df1的列和索引提取对应值
result = pd.DataFrame({col: df2_wide.loc[df1.index, df1[col]].values for col in df1.columns}, 
                      index=df1.index)

方法3:向量化lookup(性能最优)

利用pandas的lookup方法实现一次性批量提取,是效率最高的方案:

# 先将df2转为宽表
df2_wide = df2.pivot(index=df2.index, columns='Level', values='Score')

# 批量提取对应时间+Level的Score值
result_values = df2_wide.lookup(df1.index, df1.values.ravel()).reshape(df1.shape)
result = pd.DataFrame(result_values, index=df1.index, columns=df1.columns)

以上三种方法均比循环或逐元素apply高效,其中方法3的向量化操作适合处理大规模数据集。

内容的提问来源于stack exchange,提问作者Jackson Tale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 06:40:29