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

如何利用另一DataFrame中的汇率将金额转换为欧元计价?

解决方案:向量化实现货币金额转欧元计价

问题分析

你的代码最后一行报错是因为尝试用Series作为索引直接访问prices的行,pandas不支持这种操作。此外,多次重复拆分货币对会降低百万级数据的处理效率,需要优化为一次拆分+向量化计算。

修正后的代码

import pandas as pd

amounts = pd.DataFrame({
    'symbol': ['EUR/USD', 'EUR/USD', 'GBP/USD', 'GBP/USD', 'EUR/GBP', 'EUR/GBP'],
    'time': [1, 2, 1, 2, 1, 2],
    'amount': [1, 1, 2, 2, 3, 3]
})
amounts.set_index('symbol', inplace=True)

prices = pd.DataFrame({
        'symbol': ['EUR/USD', 'GBP/USD', 'EUR/GBP'],
        'price': [1.2, 1.5, 0.8]
})
prices.set_index('symbol', inplace=True)

amounts = amounts.join(prices, on='symbol')

# 一次性拆分货币对为基准货币(base)和报价货币(quote),提升大数据处理效率
amounts[['base', 'quote']] = amounts.index.str.split('/', expand=True)

# 初始化欧元计价列
amounts['eur'] = 0.0

# 场景1:基准货币是欧元(EUR/XXX),报价货币金额转欧元
mask_eur_base = amounts['base'] == 'EUR'
amounts.loc[mask_eur_base, 'eur'] = amounts.loc[mask_eur_base, 'amount'] / amounts.loc[mask_eur_base, 'price']

# 场景2:报价货币是欧元(XXX/EUR),基准货币金额转欧元
mask_eur_quote = amounts['quote'] == 'EUR'
amounts.loc[mask_eur_quote, 'eur'] = amounts.loc[mask_eur_quote, 'amount'] * amounts.loc[mask_eur_quote, 'price']

# 场景3:非欧元直接计价的货币对,用交叉汇率转欧元
mask_other = ~mask_eur_base & ~mask_eur_quote
# 获取报价货币对应的欧元汇率货币对符号
eur_quote_symbol = 'EUR/' + amounts.loc[mask_other, 'quote']
# 提取对应汇率并计算交叉转换
eur_quote_rate = prices.loc[eur_quote_symbol, 'price'].values
amounts.loc[mask_other, 'eur'] = amounts.loc[mask_other, 'amount'] * amounts.loc[mask_other, 'price'] / eur_quote_rate

# 保留两位小数匹配预期输出
amounts['eur'] = amounts['eur'].round(2)

# 输出结果
print(amounts['eur'].tolist())

关键优化点

  1. 单次拆分货币对:仅执行一次str.split操作,避免重复计算,大幅提升百万行数据的处理速度。
  2. 向量化条件赋值:用loc配合布尔掩码实现批量赋值,完全避免循环,符合大数据处理要求。
  3. 正确的交叉汇率计算:通过prices.loc精准获取交叉汇率,解决原代码的索引访问错误,确保转换逻辑符合预期。

运行后输出结果与预期完全一致:[0.83, 0.83, 2.5, 2.5, 3.75, 3.75]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:05:22