如何优化下面的代码以更快地运行,我的数据框的大小将近100,000个数据点

时间:2018-11-16 12:17:57

标签: python pandas numpy dataframe

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)

代码运行得很好,但是速度太慢,是否还有其他选择可以在更短的时间内实现呢?

Sample Dataframe

2 个答案:

答案 0 :(得分:3)

尝试以下操作:

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语句的求值都不为'0',则具有默认值(True),并避免了所有字符串格式;除此之外,它还避免了使用apply的{​​{1}}方法。

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

答案 1 :(得分:0)

解决方案与上面相同,只是稍有变化,

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']