首页 > 解决方案 > python for循环计算太低效/太长

问题描述

我正在 python 上运行一个回测程序。然而,即使数学/逻辑很简单,python 似乎也需要很长时间来计算 FOR 循环。

对于每一行/行,平均需要 1 秒;当我有成千上万的数据行时,所花费的时间是不切实际的。

我使用 panda 数据框作为基础,并通过 for-loop 生成前向计算。有没有更有效的方法,或者我能做些什么来减少计算时间?

def signal_TA1(data, periods):
    columns = ['x1', 'x2', 'x3', .......]
    pd_Append = pd.DataFrame((np.zeros((len(data.index),len(columns)))), columns = columns) #create and initialize as zeros needed columns
    data = data.join(pd_Append)
    data['Size'] = data.bidQ + data.askQ
    data['prx'] = (data.bid * data.askQ + data.ask * data.bidQ)/data.Size

    for i in range(1, len(data.index), 1):
        data.emaX.iloc[i] = data.lambda_.iloc[i] * data.Size.iloc[i] + (1 - data.lambda_.iloc[i]) * data.emaX.iloc[i-1]
        xxxxxx
        xxxxx
        xxxxx
    return data

标签: python-3.xpandasfor-loopcalculation

解决方案


似乎(好吧,它似乎是相对知名的)numpy 比 pandas 更有效地处理循环计算(因为它每次都必须重新构建整个数组)。

基本上,我在函数中创建了一个 numpy 数组 [x,y]。然后,我通过一个 for 循环计算并逐行填充 numpy 数组。最后,我只是将完成的 numpy 数组转换为 pandas 数据框(以便于显示和绘图)。对于大约 2,500 行数据和计算,时间差永远不会超过 1 秒。

def signal_M2(data, weight, pandas = True):
    bid = np.array(data.bid)
    ask = np.array(data.ask)
    askQ = np.array(data.askQ)
    bidQ = np.array(data.bidQ)
    size = bidQ + askQ
    VWAP = (bid * askQ + ask * bidQ)/(bidQ + askQ)

    columns = [x1, x2, x3, x4, x5, .....]
    datB = np.zeros((len(data.index), len(columns)))
    datA = pd.DataFrame(index=[0], columns = columns)

    lambda_ = 0.5
    weight = 0.3
    x1 = VWAP[0]
    x2 = VWAP[0]
    x3 = VWAP[0]
    x4 = VWAP[0]
    x5 = size[0]
    ....
    ....
    datB[0] = (bid[0], ask[0], bidQ[0], askQ[0], size[0], ..........)

    for row in range(1, len(data.index), 1):
        x1 = lambda_ * size[row] + (1 - lambda_) * emaInertia
        x2 = weight * VWAP[row] + (1 - weight) * emaPrx
        x3 = weight * VWAP[row] + (1 -weight) * emaPrxSlow
        x4 = weight * VWAP[row] + (1 -weight) * emaPrxFast
        x5 = weight * VWAP[row] + (1 -weight) * emaPrxLead

        if pandas == True:
            datB[row] = (bid[row], ask[row], bidQ[row], ...........)
        else:
            print(................)

    if pandas == True:
        datB = pd.DataFrame(datB, columns = columns)
        return datB 
    else : 
        print('no pandas dataframe was asked to be be stored')

推荐阅读