我有一个包含5,000,000个整数的列表。我想把这个列表转换成numpy数组。我尝试了以下代码:
numpy.array( list )
但是它非常慢。
我对此操作进行了100次基准测试,并循环遍历列表100次。没有太大的区别。
有什么好的想法可以让它更快吗?
我有一个包含5,000,000个整数的列表。我想把这个列表转换成numpy数组。我尝试了以下代码:
numpy.array( list )
但是它非常慢。
我对此操作进行了100次基准测试,并循环遍历列表100次。没有太大的区别。
有什么好的想法可以让它更快吗?
%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倍以上。
cdef np.uint8_t[:] arr = np.zeros(len(inp), dtype=np.uint8)
(需要同时导入cimport numpy as np
和import numpy as np
)。该操作基本上是带宽受限的,因此选择可能速度更快的最小dtype可能会加速此过程。我正在使用Windows,所以long是int32
,在Mac上可能是int64
,这可能解释了为什么你的速度似乎慢了一倍。你的“数字”长度是两倍。 - MSeifert我认为这很快,我已经检查了时间:
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 ---
np.array(your_list)
快吗?我进行了一些计时,但并没有更快。请注意,np.zeros
会提供一个浮点数数组,但是问题要求一个整数数组。 - MSeifert创建一个小整数的大列表,使用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
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
list
是一个整数列表,但是在注释中又说它是一组图像数据的平坦数组
和uint8
。Python中的整数不是uint8
。如果它不是ndarray
,那么它是一个字节串吗? - hpaulj