所以我有一个包含5,000,000个整数的列表。我希望将列表覆盖到一个numpy数组。我尝试了以下代码:
numpy.array( list )
但它很慢。
我对此操作进行了100次基准测试,并在列表上循环了100次。没有太大的区别。
任何好主意如何让它更快?
答案 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)
如果你有cython,你可以创建一个更快的功能。但只是一个警告:如果列表中存在无效元素(非整数或大整数),它将崩溃。
我在这里使用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
众所周知,使用数组比使用列表更快,但是有一个重要的启动'高架。