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

如何用另一Pandas DataFrame作为查找表替换DataFrame中的值?

Pandas按匹配规则替换DataFrame值的优化方案

需求说明

需要将df中的每个数值,替换为df2中对应行、对应列名(即df中的数值)的数值,最终得到目标结果。

示例数据

代码创建数据

import numpy as np
import pandas as pd
dt_index = pd.to_datetime(['2003-05-01', '2003-05-02', '2003-05-03', '2003-05-04'])
df = pd.DataFrame({'A':[1,1,3,12], 'B':[12,1,3,3], 'C':[3,12,12,1]}, index = dt_index)
df2 = pd.DataFrame({1:[1.4,4.2,1.3,5.6], 12:[2.3,7.3,9.5,0.4], 3:[8.8,0.1,8.7,2.4], 4:[9.6,9.8,5.5,1.8]}, index = dt_index)

数据展示

df内容:

A   B   C
2003-05-01   1  12   3
2003-05-02   1   1  12
2003-05-03   3   3  12
2003-05-04  12   3   1

df2内容:

1    12   3    4 
2003-05-01  1.4  2.3  8.8  9.6
2003-05-02  4.2  7.3  0.1  9.8
2003-05-03  1.3  9.5  8.7  5.5
2003-05-04  5.6  0.4  2.4  1.8

预期输出

expect = pd.DataFrame({'A':[1.4,4.2,8.7,0.4], 'B':[2.3,4.2,8.7,2.4], 'C':[8.8,7.3,9.5,5.6]}, index = dt_index)

expect内容:

A    B    C
2003-05-01  1.4  2.3  8.8
2003-05-02  4.2  4.2  7.3
2003-05-03  8.7  8.7  9.5
2003-05-04  0.4  2.4  5.6

现有尝试代码

X = df.copy()
for i in np.unique(df):
    X.mask(df == i, df2[i], axis=0, inplace=True)

疑问

现有代码看似可行,但不确定是否存在潜在问题,且当DataFrame规模增大时扩展性如何,希望得到更优、更快的解决方案。

补充说明:df中的值与df、df2的列不保证连续。


优化解决方案

方案1:基于Numpy索引的向量化操作(推荐,高效兼容新版本)

利用Numpy的向量化索引能力,直接定位df2中对应位置的值,完全避免循环,大数据量下性能最优:

# 构建df2列名到索引的映射
col_map = {col: idx for idx, col in enumerate(df2.columns)}
# 将df的数值转换为df2对应的列索引
df_col_indices = df.applymap(lambda x: col_map[x]).to_numpy()
# 按行、列索引提取df2中的值并重构为DataFrame
result = pd.DataFrame(
    df2.to_numpy()[np.arange(len(df2))[:, None], df_col_indices],
    index=df.index,
    columns=df.columns
)

方案2:使用melt+merge+pivot(逻辑直观,适合复杂场景)

通过数据重塑的方式实现,逻辑清晰易理解,适合数据量中等或需要调试的场景:

# 将df转为长格式
df_melt = df.reset_index().melt(id_vars='index', var_name='col', value_name='key')
# 将df2转为长格式
df2_melt = df2.reset_index().melt(id_vars='index', var_name='key', value_name='value')
# 匹配合并数据
merged = df_melt.merge(df2_melt, on=['index', 'key'])
# 重塑回宽格式得到结果
result = merged.pivot(index='index', columns='col', values='value').rename_axis(None, axis=1)

方案3:DataFrame.lookup(适用于Pandas < 2.0版本)

lookup方法可直接按行和列的匹配关系提取值,代码简洁,但Pandas 2.0+已标记为弃用:

result = pd.DataFrame(
    df.lookup(df.index, df.values),
    index=df.index,
    columns=df.columns
)

现有代码的潜在问题

  • 性能瓶颈:循环遍历每个唯一值,每次mask操作都要遍历整个DataFrame,数据量较大时(如上万行/列)会显著变慢。
  • 容错性差:若df中存在df2没有的列名,代码会直接报错,需额外添加判断逻辑处理此类情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:50:24