首页 > 解决方案 > 如何优化下面的代码以更快地运行,我的数据框大小几乎是 100,000 个数据点

问题描述

def encoder(expiry_dt,expiry1,expiry2,expiry3):
    if expiry_dt == expiry1:
        return 1
    if expiry_dt == expiry2:
        return 2
    if expiry_dt == expiry3:
        return 3



FINAL['Expiry_encodings'] = FINAL.apply(lambda row: '{0}_{1}_{2}_{3}_{4}'.format(row['SYMBOL'],row['INSTRUMENT'],row['STRIKE_PR'],row['OPTION_TYP'], encoder(row['EXPIRY_DT'],
                                                                                                                                             row['Expiry1'],
                                                                                                                                             row['Expiry2'],
                                                                                                                                             row['Expiry3'])), axis =1)

代码运行得很好,但是太慢了,有没有其他方法可以在更短的时间内实现这一目标?

示例数据框

标签: pythonpandasnumpydataframe

解决方案


尝试以下方法:

FINAL['expiry_number'] = '0'
for c in '321':
    FINAL.loc[FINAL['EXPIRY_DT'] == FINAL['Expiry'+c], 'expiry_number'] = c

FINAL['Expiry_encodings'] = FINAL['SYMBOL'].astype(str) + '_' + \
    FINAL['INSTRUMENT'].astype(str) + '_' + FINAL['STRIKE_PR'].astype(str) + \
    '_' + FINAL['OPTION_TYP'].astype(str) + '_' + FINAL['expiry_number']

这避免了三个语句,如果没有一个 if 语句评估为,if则具有默认值 ( ) ,并避免所有字符串格式;除此之外,它还避免了带有 a 的方法。'0'Trueapplylambda

注意'321'顺序:这反映了原始代码部分中 if 链的评估顺序:'Expiry3'具有最低优先级,在我在这里给出的代码中,它首先被 #2 覆盖,然后被 #1 覆盖。考虑到最高优先级,原始的 if 链将在 #1 处快捷方式。例如,如果'Expiry1''Expiry3'具有相同的值(等于'EXPIRY_DT'),则分配的值是1,而不是3


推荐阅读