Numpy数组复制比Python列表复制慢

pbpqsu0x  于 2023-03-11  发布在  Python
关注(0)|答案(1)|浏览(157)

我在这里看到过一些关于通过for循环访问numpy数组和python列表中的单个项的帖子。
我的程序有点不同。我正在做的是复制一个大约10个元素的小数组(或列表),然后使用它。我做了很多次,所以我希望它快一些。如果你感兴趣的话,应用程序是我正在搜索一棵树,每个小数组/列表都是树中的一个“状态”。
但是我发现numpy.copy()函数比Python list()函数慢。
为了证明我所说的,这里有一个计时的小程序:

import time

import numpy as np
def numPyArrays(iterations:int):

    initialArray = np.array([1,0,0,1,0,1,1,1,0,0])

    for i in range(iterations):
        nextArray = initialArray.copy()
    
    print(f"Numpy Arrays:\n{nextArray}")
    return    

def pythonLists(iterations:int):

    initialList = [1,0,0,1,0,1,1,1,0,0]

    for i in range(iterations):
        nextList = list(initialList)
    
    print(f"Python Lists:\n{nextList}")
    return

def main():

    numIterations = 10000000

    startTime = time.time()
    numPyArrays(numIterations)
    print(f"Time taken: {round(time.time() - startTime, 2)} seconds.\n")

    startTime = time.time()
    pythonLists(numIterations)
    print(f"Time taken: {round(time.time() - startTime, 2)} seconds.\n")

main()

时间:

Numpy Arrays:
[1 0 0 1 0 1 1 1 0 0]
Time taken: 4.68 seconds.

Python Lists:
[1, 0, 0, 1, 0, 1, 1, 1, 0, 0]
Time taken: 1.5 seconds.

我本以为numpy.copy函数会和

fumotvh3

fumotvh31#

你所做的操作看起来毫无意义,你只是一遍又一遍地将同一个数组或列表赋给一个新变量,如果你真的以一种有用的方式复制了那么多数据,会发生什么呢?
不如这样:

import time

import numpy as np

def numPyArrays(iterations: int):
    initialArray = np.array([1, 0, 0, 1, 0, 1, 1, 1, 0, 0])

    result = np.zeros((iterations, len(initialArray)), dtype=int)
    result[:, :] = initialArray

    print(result[0], result[1], result[-1])
    return

def pythonLists(iterations: int):
    initialList = [1, 0, 0, 1, 0, 1, 1, 1, 0, 0]

    result = [list(initialList) for i in range(iterations)]

    print(result[0], result[1], result[-1])
    return

def main():
    numIterations = 10000000

    startTime = time.time()
    numPyArrays(numIterations)
    print(f"Time taken: {round(time.time() - startTime, 2)} seconds.\n")

    startTime = time.time()
    pythonLists(numIterations)
    print(f"Time taken: {round(time.time() - startTime, 2)} seconds.\n")

main()

结果:

[1 0 0 1 0 1 1 1 0 0] [1 0 0 1 0 1 1 1 0 0] [1 0 0 1 0 1 1 1 0 0]
Time taken: 0.13 seconds.

[1, 0, 0, 1, 0, 1, 1, 1, 0, 0] [1, 0, 0, 1, 0, 1, 1, 1, 0, 0] [1, 0, 0, 1, 0, 1, 1, 1, 0, 0]
Time taken: 4.26 seconds.

你的例子显示了初始化一个全新的numpy数组比定义一个新的列表要多一些开销,但是在任何实际的场景中,你只需要做几次,而复制操作本身在numpy中要快得多,正如这个例子所显示的。
我的代码不是将同一个数组一遍又一遍地复制到一个全新的数组,而是将数组复制到数组的新行,然后对列表做同样的操作,在这里,numpy快了不止一个数量级。
(Note我的示例只打印每个结果的前2个副本,然后打印最后一个副本,但当然这是任意的--您可以编写一些代码来检查所有行实际上是否都分配了相同的值)

相关问题