我必须存储 numpy
矩阵的列表。我试过两种方法:
1.创建 list
并附加到其中:
ls_ws=[]
for ind in range(iterations):
...
ls_ws.append(ls_w) # ls_w is a matrix of size 6,1
问题:开始时速度很快,最后速度很慢。
2.创建一个零矩阵并对其进行修改:
for ind in range(iterations):
...
ls_ws=np.matrix(np.zeros((6,iterations)))
问题:我不太确定,但无论每次迭代如何,这似乎都是相同的速度。
我得到的奇怪的事情,如果我将迭代设置为较小的数字,它很快。但是如果我将它设置为1500这样的大数,那么每次迭代(即使是第一次迭代)都非常慢。
第二种方法应该很快,但如果我将迭代设置为大数,则速度非常慢。为什么?如何解决?
答案 0 :(得分:5)
我认为你在这里有一个很好的解决方案,但你对列与行的处理可能会影响性能:
ls_ws=np.matrix(np.zeros((6,iterations)))
for ind in range(iterations):
...
ls_ws[:,ind]=ls_w
您应该在第一个维度而不是最后一个维度内进行迭代。您可以交换尺寸,或者只是这样做:
ls_ws=np.matrix(np.zeros((6,iterations), order='F'))
当数组很大时,这可能会有所帮助,因为您将访问6个元素的连续块,而不是每次迭代中的分散位。
答案 1 :(得分:1)
使用附带的准系统版本附加:
def foo1(N):
alist = []
for _ in range(N):
alist.append([1,2,3,4,5,6])
return np.array(alist)
时间与N
平滑In [4]: timeit foo1(100)
10000 loops, best of 3: 123 µs per loop
In [5]: timeit foo1(1000)
1000 loops, best of 3: 1.23 ms per loop
In [6]: timeit foo1(10000)
100 loops, best of 3: 12.3 ms per loop
In [7]: timeit foo1(100000)
10 loops, best of 3: 129 ms per loop
In [8]: timeit foo1(1000000)
1 loop, best of 3: 1.29 s per loop
In [9]: timeit foo1(10000000)
1 loop, best of 3: 12.9 s per loop
列表追加可能会因大型列表而变慢。列表使用缓冲区来保存指针,以及一些增长空间。当它超过那个空间时,它必须得到更多。如果它不能“就地”扩展,它将不得不要求新空间并复制所有指针。对于接近填充内存的非常大的列表,这可能会减慢速度。我可能会看到提示,在时间从123移动到129
def foo2(N):
out = np.zeros((N,6),int)
for i in range(N):
out[i,:] = [1,2,3,4,5,6]
return out
时间也与N一致,并且是列表情况的两倍:
In [15]: timeit foo2(100)
1000 loops, best of 3: 242 µs per loop
In [16]: timeit foo2(1000)
100 loops, best of 3: 2.52 ms per loop
In [17]: timeit foo2(10000)
10 loops, best of 3: 24.6 ms per loop
In [18]: timeit foo2(100000)
1 loop, best of 3: 249 ms per loop
In [19]: timeit foo2(1000000)
1 loop, best of 3: 2.52 s per loop
In [20]: timeit foo2(10000000)
1 loop, best of 3: 25.2 s per loop
迭代最后一个维度没有时间差异
def foo3(N):
out = np.zeros((6,N),int)
for i in range(N):
out[:,i] = [1,2,3,4,5,6]
return out
迭代1000次,而一次只分配/创建6个元素是不好的numpy
练习。如果你必须迭代它最好循环几次,每次都做大型操作。例如6个循环,1000个项目阵列。
如果我将迭代移动到编译代码,时间会快得多
def foo4(N):
out = np.zeros((N,6),int)
out[...] = [1,2,3,4,5,6]
return out
In [28]: timeit foo4(1000)
.... cached.
10000 loops, best of 3: 20.4 µs per loop
In [29]: timeit foo4(100000)
1000 loops, best of 3: 1.45 ms per loop
您谈到保存矩阵甚至分配np.matrix
。那么让我们看看它有什么影响:
def foo1m(N):
alist = []
for _ in range(N):
alist.append(np.matrix([1,2,3,4,5,6]).T)
return np.concatenate(alist, axis=1)
def foo2m(N):
out = np.matrix(np.zeros((6,N),int))
for i in range(N):
out[:,i] = np.matrix([1,2,3,4,5,6]).T
return out
In [62]: timeit foo1(1000)
1000 loops, best of 3: 1.32 ms per loop
In [63]: timeit foo1m(1000)
100 loops, best of 3: 18 ms per loop
In [64]: timeit foo2(1000)
100 loops, best of 3: 2.75 ms per loop
In [65]: timeit foo2m(1000)
10 loops, best of 3: 28.2 ms per loop
这使得每次/迭代次数延长了10倍。 matrix
是ndarray
的子类,需要更多处理(将其强制为2d等)。