有没有更快的方法来使列表彼此“过去”?

时间:2019-01-23 07:38:23

标签: python numpy

我的代码接受两个单独的列表A和B,并将一个“过去”移到另一个 (拍摄一辆经过停放的火车的火车),取每个班次序列的点积的平方。

我实际上并不了解Python的许多技巧,所以也许我的解决方案很笨拙。

for shift in range (1,len(B)):
   total += np.dot( A[-shift:] , B[:shift] )**2 + np.dot( A[:shift] , B[-shift:] )**2
total += (np.dot(A,B))**2

它按原样运行,但是我现在正在处理如此大量的数据,因此速度成为一个严重的问题。

1 个答案:

答案 0 :(得分:2)

在python中创建切片时(例如A[-shift:]),您正在创建数组的副本。例如,您可以通过执行以下操作查看此信息:

A=[1,2,3]
B=A[:1]
B[0]=17
A // => A is still [1,2,3] not [17,2,3]

但是您可以使用numpy数组来避免这种复制:

A=numpy.array([1,2,3])
B=A[:1]
B[0]=17
A /// => A is numpy.array([17,  2,  3])

因此,如果您使用numpy数组,则数据复制会少很多,我怀疑您的代码会更高效。但是一如既往对此进行基准测试以确认它。

请参见https://stackoverflow.com/a/5131563/922613  或https://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html以获得更多信息

我使用以下脚本对其进行了基准测试:

import numpy as np

def normal_arrays():
    A=[1,2,3,4]
    B=[1,2,3,4]
    total = 0
    for shift in range (1,len(B)):
        total += np.dot( A[-shift:] , B[:shift] )**2 + np.dot( A[:shift] , B[-shift:] )**2
        total += (np.dot(A,B))**2


def numpy_arrays():
    A=np.array([1,2,3,4])
    B=np.array([1,2,3,4])
    total = 0
    for shift in range (1,len(B)):
        total += np.dot( A[-shift:] , B[:shift] )**2 + np.dot( A[:shift] , B[-shift:] )**2
        total += (np.dot(A,B))**2


if __name__ == "__main__":
    import timeit
    print('normal arrays', timeit.timeit(normal_arrays))
    print('numpy arrays', timeit.timeit(numpy_arrays))

我的结果是将运行时间提高了约50%:

normal arrays 21.76756980700884
numpy arrays 11.998605689994292