numpy.array(列表)很慢

时间:2017-06-10 01:37:00

标签: arrays performance list numpy

所以我有一个包含5,000,000个整数的列表。我希望将列表覆盖到一个numpy数组。我尝试了以下代码:

numpy.array( list )

但它很慢。

我对此操作进行了100次基准测试,并在列表上循环了100次。没有太大的区别。

任何好主意如何让它更快?

3 个答案:

答案 0 :(得分:1)

我认为这很快,我检查过时间:

import numpy as np
import time
start_time = time.time()

number = 1
elements = 10000000

your_list = [number] * elements

ret = np.zeros(shape=(len(your_list)))
np.copyto(ret, your_list)

print("--- %s seconds ---" % (time.time() - start_time))
--- 0.7615997791290283 seconds ---

答案 1 :(得分:1)

如果你有,你可以创建一个更快的功能。但只是一个警告:如果列表中存在无效元素(非整数或大整数),它将崩溃。

我在这里使用IPython魔术(%load_ext cython%%cython),重点是展示函数的样子 - 不是为了展示你如何编译Cython代码(它并不难和Cythons“如何编译“文档非常好”。

%load_ext cython

%%cython

cimport cython
import numpy as np

@cython.boundscheck(False)
cpdef to_array(list inp):
    cdef long[:] arr = np.zeros(len(inp), dtype=long)
    cdef Py_ssize_t idx
    for idx in range(len(inp)):
        arr[idx] = inp[idx]
    return np.asarray(arr)

时间安排:

import numpy as np

def other(your_list):  # the approach from @Damian Lattenero in the other answer
    ret = np.zeros(shape=(len(your_list)), dtype=int)
    np.copyto(ret, your_list)
    return ret

inp = list(range(1000000))
%timeit np.array(inp)
# 315 ms ± 5.42 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.array(inp, dtype=int)
# 311 ms ± 2.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit other(inp)
# 316 ms ± 3.97 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit to_array(inp)
# 23.4 ms ± 1.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

所以速度提高了10倍以上。

答案 2 :(得分:1)

列出小整数列表;使用numpy拐杖:

In [619]: arr = np.random.randint(0,256, 5000000)
In [620]: alist = arr.tolist()
In [621]: timeit alist = arr.tolist()     # just for reference
10 loops, best of 3: 108 ms per loop

和普通列表迭代的时间(不做任何事情)

In [622]: timeit [i for i in alist]
10 loops, best of 3: 193 ms per loop

创建一个指定dtype的数组

In [623]: arr8 = np.array(alist, 'uint8')
In [624]: timeit arr8 = np.array(alist, 'uint8')
1 loop, best of 3: 508 ms per loop

我们可以使用fromiter获得2倍的提升;显然,检查的次数减少了。即使列表是数字和字符串的混合,np.array也会起作用。它还处理列表等列表。

In [625]: timeit arr81 = np.fromiter(alist, 'uint8')
1 loop, best of 3: 249 ms per loop

当我们在整个事情中进行数学运算时,使用数组的优势变得明显:

In [628]: timeit arr8.sum()
100 loops, best of 3: 6.93 ms per loop
In [629]: timeit sum(alist)
10 loops, best of 3: 74.4 ms per loop
In [630]: timeit 2*arr8
100 loops, best of 3: 6.89 ms per loop
In [631]: timeit [2*i for i in alist]
1 loop, best of 3: 465 ms per loop

众所周知,使用数组比使用列表更快,但是有一个重要的启动'高架。