基于日期批量转换DataFrame中多币种至GBP的技术问题
| 金额 | 币种 | 日期 |
|---|---|---|
| 45,63 | GBP | 23.02.2020 |
| 38,42 | EUR | 15.06.2019 |
| 8500 | SEK | 20.03.2021 |
我需要将上述不同日期的各币种金额转换为GBP,尝试以下代码时出现报错:
from forex_python.converter import CurrencyRates c = CurrencyRates() df['Amount'] = df.apply( lambda x: c.convert( x.Currency, 'GBP', x.Amount, x.Date), axis = 1)
报错信息:'Currency Rates source not ready'
我也曾尝试通过API实现,但该API有1000条数据限制,而我的数据集包含95000条记录,请问是否有可行的按日期批量转换方法?
可行的批量转换方案
1. 批量获取历史汇率并本地缓存
不要单条调用API,先对数据按日期+币种去重,只获取唯一组合的汇率,再映射回原数据集:
- 提取数据中所有
(日期, 币种)的唯一组合,数量会远小于95000条(大量重复的日期/币种会被合并) - 下载权威免费的历史汇率数据集(比如欧洲央行ECB的历史汇率,无调用限制),保存为本地文件
- 将本地汇率数据与原数据集按
日期+币种合并,计算转换后的GBP金额
示例代码:
import pandas as pd # 读取原数据集 df = pd.read_csv('your_data.csv') # 读取本地历史汇率数据(示例:包含日期、EUR/GBP、各币种对EUR的汇率) exchange_rates = pd.read_csv('ecb_exchange_rates.csv', parse_dates=['Date']) # 统一日期格式(原数据为dd.mm.yyyy,转换为datetime类型) df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%Y') exchange_rates['Date'] = pd.to_datetime(exchange_rates['Date']) # 合并汇率数据:先转EUR,再转GBP df = df.merge(exchange_rates[['Date', 'EUR/GBP']], on='Date', how='left') df = df.merge(exchange_rates[['Date', 'Currency', 'Rate_to_EUR']], on=['Date', 'Currency'], how='left') # 计算转换后的GBP金额 df['Amount_GBP'] = df.apply( lambda x: x['Amount'] * x['Rate_to_EUR'] * x['EUR/GBP'] if x['Currency'] != 'GBP' else x['Amount'], axis=1 )
2. 修复forex_python的调用问题
'Currency Rates source not ready'多因网络问题、日期格式错误或数据源临时故障,可调整调用方式:
- 确保日期参数为
datetime类型,而非字符串 - 增加重试机制,避免单次请求失败中断任务
- 先对数据去重,减少API调用次数
示例代码:
from forex_python.converter import CurrencyRates import pandas as pd from tenacity import retry, stop_after_attempt, wait_exponential c = CurrencyRates() @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)) def convert_currency(row): if row['Currency'] == 'GBP': return row['Amount'] # 转换日期为datetime对象 date_obj = pd.to_datetime(row['Date'], format='%d.%m.%Y') return c.convert(row['Currency'], 'GBP', row['Amount'], date_obj) # 对数据去重,仅处理唯一的转换请求 unique_rows = df[['Currency', 'Amount', 'Date']].drop_duplicates() unique_rows['Amount_GBP'] = unique_rows.apply(convert_currency, axis=1) # 映射回原数据集 df = df.merge(unique_rows[['Currency', 'Amount', 'Date', 'Amount_GBP']], on=['Currency', 'Amount', 'Date'], how='left')
3. 搭建本地汇率数据库
如果长期处理大量汇率转换需求,可搭建本地数据库,定期从ECB、IMF等权威数据源同步历史汇率,后续直接从本地查询,完全规避API限制。
内容的提问来源于stack exchange,提问作者Orhan Dağ
相关产品推荐
相关产品推荐

