我需要一些帮助来思考这个问题:
我有一个包含61K服务记录的数据集。每项服务在特定日期续订,每项服务也有成本,该成本金额以10种不同货币中的一种计费。
我需要对每个服务记录做的是将每个服务成本转换为服务续订日期的CAD货币。
当我在一个有6个服务的小样本数据集中这样做时,它需要3秒,但这意味着如果我在一个61k的记录数据集上这样做,它可能需要超过8小时,这太长了(我认为我可以在excel或google sheets中更快地做到这一点,我不想这样做)
有没有更好的方法或方法来做这个与pandas/python在谷歌协作,所以它不需要那么长时间?
提前谢谢你
# setup
import pandas as pd
!pip install forex-python
from forex_python.converter import CurrencyRates
#sample dataset/df
dummy_data = {
'siteid': ['11', '12', '13', '41', '42','51'],
'userid': [0,0,0,0,0,0],
'domain': ['A', 'B', 'C', 'E', 'F', 'G'],
'currency':['MXN', 'CAD', 'USD', 'USD', 'AUD', 'HKD'],
'servicecost': [2.5, 3.3, 1.3, 2.5, 2.5, 2.3],
'date': ['2022-02-04', '2022-03-05', '2022-01-03', '2021-04-06', '2022-12-05', '2022-11-01']
}
df = pd.DataFrame(dummy_data, columns = ['siteid', 'userid', 'domain','currency','servicecost','date'])
#ensure date is in the proper datatype
df['date'] = pd.to_datetime(df['date'],errors='coerce')
#go through df, get the data to do the conversion and populate a new series
def convertServiceCostToCAD(currency,servicecost,date):
return CurrencyRates().convert(currency, 'CAD', servicecost, date)
df['excrate']=list(map(convertServiceCostToCAD, df['currency'], df['servicecost'], df['date']))
如果我理解正确的话,这个包的作用是提供两种货币之间的每日固定汇率(因此一个方向与另一个方向相反)。
使事情变得如此缓慢的原因很明显是对包方法的调用。对我来说,每次呼叫大约需要4秒。
你总是想知道x货币对加元的汇率。
包有一个方法.get_rates()
,它似乎提供了与.convert()
方法相同的信息,但只针对一种货币和所有其他货币。
那么你可以做的是:
- 收集DataFrame中所有唯一的日期
- 为每个日期调用
.get_rates()
并保存结果 - 使用结果加上您的金额来计算所需的列
。如下:
import pandas as pd
from forex_python.converter import CurrencyRates
from tqdm import tqdm # use 'pip install tqdm' before
df = pd.DataFrame({
'siteid': ['11', '12', '13', '41', '42', '51'],
'userid': [0, 0, 0, 0, 0, 0],
'domain': ['A', 'B', 'C', 'E', 'F', 'G'],
'currency': ['MXN', 'CAD', 'USD', 'USD', 'AUD', 'HKD'],
'servicecost': [2.5, 3.3, 1.3, 2.5, 2.5, 2.3],
'date': ['2022-02-04', '2022-03-05', '2022-01-03', '2021-04-06', '2022-12-05', '2022-11-01']
})
# get rates for all unique dates, added tqdm progress bar to see progress
rates_dict = {date: CurrencyRates().get_rates('CAD', date_obj=pd.to_datetime(date, errors='coerce'))
for date in tqdm(df['date'].unique())}
# now use these rates to set cost to 1/(CAD to currency_x rate), except when currency is CAD and when servicecost is 0, in those cases just use servicecost
df['excrate'] = df.apply(lambda row: 1.0/rates_dict[row['date']][row['currency']]*row['servicecost'] if row['currency']!='CAD' and row['servicecost'] != 0 else row['servicecost'], axis=1)
print(df)
> siteid userid domain currency servicecost date excrate
0 11 0 A MXN 2.5 2022-02-04 0.154553
1 12 0 B CAD 3.3 2022-03-05 3.300000
2 13 0 C USD 1.3 2022-01-03 1.670334
3 41 0 E USD 2.5 2021-04-06 3.140874
4 42 0 F AUD 2.5 2022-12-05 2.219252
5 51 0 G HKD 2.3 2022-11-01 0.380628
这会大大加快速度,这取决于数据中有多少个不同的日期。但是,由于您说原始DataFrame有60k行,我假设有大量的日期发生多次。这段代码应该差不多~ 4秒*数量的独特DataFrame运行日期。