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

含lambda的Python数据处理代码运行极慢 如何有效优化提速

性能瓶颈根因
  • 99%的耗时来自网络IO:你调用的forex_python.converter.CurrencyRates.convert()每次执行都会发起HTTP请求拉取对应日期的汇率,70行数据对应70次网络请求,单次请求延迟300~500ms的话总耗时自然到30秒级。你之前试的numba只优化CPU计算逻辑,完全碰不到IO环节;multiprocessing没提速基本是因为没做会话复用、被目标接口限流,或者进程启动开销盖过了并行收益,根本没摸到瓶颈。
  • 剩下1%的耗时来自pandas的低效用法:按国家拆分df再合并做了大量无意义内存拷贝,apply(axis=1)逐行遍历的效率比pandas原生向量化操作低1~2个数量级。
  • cpi.inflate逐行重复查表:相同年月的通胀系数是固定值,逐行调用会重复查静态表做重复计算。
优化方案(按收益从高到低排序)
  • 第一优先级:干掉逐行网络请求,把IO量降4个数量级
    你现在的逻辑是每算一行发一次请求,7万行就是7万次请求,按单次300ms算要跑近6个小时,完全不可行。
    正确做法是:
    • 先扫描全量数据,提取所有出现过的日期、需要转换的源货币(你的场景只有EUR、GBP两种)
    • 一次性拉取这些日期对应对USD的汇率,存成(源货币, 日期) -> 汇率的映射表,或者直接下载欧央行/美联储公开的历史汇率全量CSV到本地,后续直接读本地文件,连网络请求都不用发。
      这一步做完,网络请求从7万次降到最多几千次(按你数据覆盖的时间跨度算,跨10年也就3000多个日期),如果用本地静态汇率文件,IO开销直接降到毫秒级。
  • 第二优先级:替换逐行apply为向量化操作,去掉无意义的df拆分
    不要拆成DE/GB/US三个子df再拼接,直接用pandas原生的map、merge接口做批量处理:
    • 建国家到货币的映射字典,直接用Series.map()给全量df打源货币标签
    • 把存好的汇率表转成和原df同结构的表,用pd.merge()按源货币、日期做左连接,一次性把所有行的汇率匹配上,直接做乘法算USD金额,完全不用逐行apply
    • 美国行的源货币是USD,汇率固定为1,不用走转换逻辑
  • 第三优先级:给cpi通胀计算加缓存,避免重复计算
    cpi的通胀数据是本地静态存储的,同一个日期对应的通胀系数完全固定。先把所有出现过的日期去重,提前算好每个日期对应的通胀系数存成映射表,再用Series.map()批量匹配,不要逐行调用cpi.inflate。
优化后参考代码框架
import cpi
import pandas as pd

# 第一次运行时批量拉取所需汇率,存为本地csv,格式为[source_currency, date, rate_to_usd]
# USD对应的rate_to_usd固定填1即可,后续运行直接读本地文件,无需网络请求
rate_df = pd.read_csv("historical_usd_exchange_rates.csv", parse_dates=['date'])
rate_df['date'] = rate_df['date'].dt.date

# 读数据时只加载需要的列,减少内存占用和IO耗时
transaction_df = pd.read_csv(
    "tickets.csv",
    usecols=['customer_country_code', 'processed_at', 'amount']
)
transaction_df['date'] = pd.to_datetime(transaction_df['processed_at']).dt.date

# 批量映射国家对应货币,无需拆分df
country_currency_map = {'DE': 'EUR', 'GB': 'GBP', 'US': 'USD'}
transaction_df['source_currency'] = transaction_df['customer_country_code'].map(country_currency_map)

# 批量匹配汇率,计算美元金额
transaction_df = transaction_df.merge(rate_df, on=['source_currency', 'date'], how='left')
transaction_df['amount_usd'] = transaction_df['amount'] * transaction_df['rate_to_usd']

# 批量匹配通胀系数,计算实际美元价值
unique_dates = transaction_df['date'].unique()
inflation_map = {d: cpi.inflate(1, d) for d in unique_dates}
transaction_df['inflation_factor'] = transaction_df['date'].map(inflation_map)
transaction_df['Real_USD'] = transaction_df['amount_usd'] * transaction_df['inflation_factor']
额外说明
  • 这套优化跑7万行数据总耗时基本在1秒以内,不需要用numba或者multiprocessing,这两个工具都是解决CPU密集型瓶颈的,你的场景瓶颈在IO和pandas用法不对,用这两个工具纯属方向错了。
  • 日期转换直接用pandas的.dt接口,不要套apply,原生向量化实现比逐行apply快几十倍。
  • 如果需要定期更新汇率,写个单独的脚本每周/每月拉一次增量汇率更新到本地汇率文件就行,不要在主处理逻辑里发请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:45:32