Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向量化/优化此python代码的最佳方法是什么?_Python_Optimization_Vectorization - Fatal编程技术网

向量化/优化此python代码的最佳方法是什么?

向量化/优化此python代码的最佳方法是什么?,python,optimization,vectorization,Python,Optimization,Vectorization,我通过一次迭代和计算每个列来计算48个派生的pandas列,但需要加快过程。要使其更快、更有效,最好的方法是什么。每列计算收盘价占该期间(T、T-1、T-2等)高价和低价的百分比 我目前使用的代码是: #get last x closes as percentage of period high and low for i in range(1, 49, 1): df.loc[:,'Close_T_period_'+str(i)] = ((df['BidClose'].shift(i).

我通过一次迭代和计算每个列来计算48个派生的pandas列,但需要加快过程。要使其更快、更有效,最好的方法是什么。每列计算收盘价占该期间(T、T-1、T-2等)高价和低价的百分比

我目前使用的代码是:

#get last x closes as percentage of period high and low
for i in range(1, 49, 1):
    df.loc[:,'Close_T_period_'+str(i)] = ((df['BidClose'].shift(i).values 
    - df['BidLow'].shift(i).values)/          
    (df['BidHigh'].shift(i).values - df['BidLow'].shift(i).values))
输入数据帧示例:

                     BidOpen  BidHigh   BidLow  BidClose  AskOpen  AskHigh   AskLow  AskClose   Volume
Date                                                                                                  
2019-09-27 09:00:00  1.22841  1.22919  1.22768   1.22893  1.22850  1.22927  1.22777   1.22900  12075.0
2019-09-27 10:00:00  1.22893  1.23101  1.22861   1.23058  1.22900  1.23110  1.22870   1.23068  16291.0
2019-09-27 11:00:00  1.23058  1.23109  1.22971   1.23076  1.23068  1.23119  1.22979   1.23087  10979.0
2019-09-27 12:00:00  1.23076  1.23308  1.23052   1.23232  1.23087  1.23314  1.23062   1.23241  16528.0
2019-09-27 13:00:00  1.23232  1.23247  1.23163   1.23217  1.23241  1.23256  1.23172   1.23228  14106.0
                     BidOpen  BidHigh   BidLow  BidClose  ...  Close_T_period_45  Close_T_period_46  Close_T_period_47  Close_T_period_48
Date                                                      ...                                                                            
2019-09-27 09:00:00  1.22841  1.22919  1.22768   1.22893  ...           0.682635           0.070796           0.128940           0.794521
2019-09-27 10:00:00  1.22893  1.23101  1.22861   1.23058  ...           0.506024           0.682635           0.070796           0.128940
2019-09-27 11:00:00  1.23058  1.23109  1.22971   1.23076  ...           0.774920           0.506024           0.682635           0.070796
2019-09-27 12:00:00  1.23076  1.23308  1.23052   1.23232  ...           0.212500           0.774920           0.506024           0.682635
2019-09-27 13:00:00  1.23232  1.23247  1.23163   1.23217  ...           0.378882           0.212500           0.774920           0.506024
输出数据帧示例:

                     BidOpen  BidHigh   BidLow  BidClose  AskOpen  AskHigh   AskLow  AskClose   Volume
Date                                                                                                  
2019-09-27 09:00:00  1.22841  1.22919  1.22768   1.22893  1.22850  1.22927  1.22777   1.22900  12075.0
2019-09-27 10:00:00  1.22893  1.23101  1.22861   1.23058  1.22900  1.23110  1.22870   1.23068  16291.0
2019-09-27 11:00:00  1.23058  1.23109  1.22971   1.23076  1.23068  1.23119  1.22979   1.23087  10979.0
2019-09-27 12:00:00  1.23076  1.23308  1.23052   1.23232  1.23087  1.23314  1.23062   1.23241  16528.0
2019-09-27 13:00:00  1.23232  1.23247  1.23163   1.23217  1.23241  1.23256  1.23172   1.23228  14106.0
                     BidOpen  BidHigh   BidLow  BidClose  ...  Close_T_period_45  Close_T_period_46  Close_T_period_47  Close_T_period_48
Date                                                      ...                                                                            
2019-09-27 09:00:00  1.22841  1.22919  1.22768   1.22893  ...           0.682635           0.070796           0.128940           0.794521
2019-09-27 10:00:00  1.22893  1.23101  1.22861   1.23058  ...           0.506024           0.682635           0.070796           0.128940
2019-09-27 11:00:00  1.23058  1.23109  1.22971   1.23076  ...           0.774920           0.506024           0.682635           0.070796
2019-09-27 12:00:00  1.23076  1.23308  1.23052   1.23232  ...           0.212500           0.774920           0.506024           0.682635
2019-09-27 13:00:00  1.23232  1.23247  1.23163   1.23217  ...           0.378882           0.212500           0.774920           0.506024
简短回答(更快的实施) 以下代码速度快6倍:

import numpy as np

def my_shift(x, i):
    first = np.array([np.nan]*i)
    return np.append(first, x[:-i])

result = ((df2['BidClose'].values - df2['BidLow'].values)/(df2['BidHigh'].values - df2['BidLow'].values))
for i in range(1, 49, 1):
    df2.loc[:,'Close_T_period_'+str(i)] = my_shift(result, i)
长答覆(解释) 代码中的两个主要瓶颈问题是:

  • 在每次迭代中,重新计算相同的值 不同之处在于,每一次的变化都是不同的
  • 出于您的目的,班次操作非常缓慢
  • 因此,我的代码只是管理这两个问题。基本上,我只计算一次结果,我只使用循环进行移位(问题#1得到了改进),我实现了自己的移位函数,在原始数组
    I
    NaN值之前追加,并剪切最后一个
    I

    执行时间 对于5000行的数据帧,时间基准给出:

    42 ms ± 1.79 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    通过我的解决方案,我得到:

    7.62 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    更新 我尝试使用apply实现一个解决方案:

    result = ((df2['BidClose'].values - df2['BidLow'].values)/(df2['BidHigh'].values - df2['BidLow'].values))
    df3 = df.reindex(df2.columns.tolist() +[f'Close_T_period_{i}' for i in range(1, 2000)], axis=1)
    df3.iloc[:, 9:] = df3.iloc[:, 9:].apply(lambda row: my_shift(result, int(row.name.split('_')[-1])))
    

    在我的测试中,此解决方案似乎比第一个稍慢。

    欢迎使用此解决方案!考虑更新您的问题,更好地解释您的问题,您的代码应该做什么,并添加一些输入/输出示例。谢谢法比奥。我可以提供熊猫输入和输出的示例,但如何在此处共享/粘贴?您可以打印数据集的标题或大量行,例如使用:
    print(df.head())
    。将结果以代码的形式粘贴到这里。根据建议添加了输入和输出尾部示例。感谢您的支持。这是可以完全矢量化的东西吗?删除“for”迭代还是不可能或不合适?我不知道矢量化的方法,问题是在每个循环上创建一个新列。好的。我一直在尝试将其矢量化,但不太清楚如何实现。听到这是因为这是不可能的,我有点安慰。无论如何,6倍的速度对我来说是好的。再次感谢您的帮助Fabio:-)还有一件事Fabio-您认为您的解决方案可以通过尝试使用“应用”而不是“for”循环来进一步改进吗?Fabiol-现在我能够+1您的有用答案。再次感谢