這是我當前的代碼。
當第二個“for回圈”中的元素數量很少(大約10k)并且只需要幾秒鐘時,它可以正常作業,但是當第二個“for回圈”中的元素數量很高(大約40k)時大約需要 60 秒或更長時間:為什么?
例如:有時當第二個 for 回圈有 28k 個元素時,執行它的時間比它有 7k 個元素時要少。我不明白為什么時間不是線性依賴于操作的數量。
此外,作為一般規則,代碼運行的時間越長,回圈時間就越長。
回顧一下,執行時間通常遵循以下規則:
- 當操作 < 10k 時,時間 < 5 秒
- 當 10k < operations < 40k , 10s < time < 30s (似乎是隨機的)
- 當操作 > 40k 時,時間 ~ 60 秒
.
from random import random
import numpy as np
import time
import gc
from collections import deque
import random
center_freq = 20000000
smpl_time = 0.03749995312*pow(10,-6)
mat_contents = []
for i in range(10):
mat_contents.append(np.ones((3600, random.randint(3000,30000))))
tempo = np.empty([0,0])
for i in range(3600):
tempo = np.append(tempo, center_freq*smpl_time*i)
ILO = np.cos(tempo)
check = 0
for element in mat_contents:
start_time = time.time()
Icolumn = np.empty([0,0])
Imatrix = deque([])
gc.disable()
for colonna in element.T:
Imatrix.append(np.multiply(ILO, colonna))
gc.enable()
varI = np.var(Imatrix)
tempImean = np.mean(Imatrix)
print('\nSize: ', len(element.T))
print("--- %s seconds ---" % (time.time() - start_time))
print("--- ", check, ' ---')
check = 1
uj5u.com熱心網友回復:
你的代碼殺死了我的會話,大概是因為陣列維度對于記憶體來說太大了。用較小的數字再試一次:
In [1]: from collections import deque
...: import random
...:
...: center_freq = 20000000
...: smpl_time = 0.03749995312*pow(10,-6)
...:
...: mat_contents = []
...:
...: for i in range(10):
...: mat_contents.append(np.ones((36, random.randint(30,300))))
...:
...: tempo = np.empty([0,0])
...:
...: for i in range(3600):
...: tempo = np.append(tempo, center_freq*smpl_time*i)
...:
...: ILO = np.cos(tempo)
...:
...: check = 0
In [2]:
In [2]: tempo.shape
Out[2]: (3600,)
In [3]: ILO
Out[3]:
array([ 1. , 0.73168951, 0.07073907, ..., -0.63602366,
-0.99137119, -0.81472814])
In [4]: len(mat_contents)
Out[4]: 10
快速說明 - 雖然mat_contents回圈中的串列附加相對較快,np.append但下一個回圈中的附加很糟糕。不要那樣使用它。
我不知道我現在是否有時間看下一個回圈,但是,你為什么要在deque那里使用?為什么不是清單?我沒有使用過deque很多,但我認為它與右側的串列相比沒有任何優勢append。
修正ILO縮小的形狀
In [16]: tempo = np.empty([0,0])
...: ...:
...: ...: for i in range(36):
...: ...: tempo = np.append(tempo, center_freq*smpl_time*i)
...:
In [17]: tempo.shape
Out[17]: (36,)
In [18]: ILO = np.cos(tempo)
我懷疑回圈可以用一個numpy運算式代替,但我不會深入研究。
In [19]: %%timeit
...: for element in mat_contents:
...: Icolumn = np.empty([0,0])
...: Imatrix = deque([])
...: for colonna in element.T:
...: Imatrix.append(np.multiply(ILO, colonna))
...: varI = np.var(Imatrix)
...: tempImean = np.mean(Imatrix)
...:
5.82 ms ± 6 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
使用時間Imatrix = []相同,因此使用deque不會受到傷害。
mat_contents包含具有不同形狀的陣列(第二維):
In [22]: [x.shape for x in mat_contents]
Out[22]:
[(36, 203),
(36, 82),
(36, 194),
(36, 174),
(36, 119),
(36, 190),
(36, 272),
(36, 68),
(36, 293),
(36, 248)]
現在讓我們檢查一下您擔心的慢回圈:
In [23]: ILO.shape
Out[23]: (36,)
In [24]: element=mat_contents[0]
In [25]: element.T.shape
Out[25]: (203, 36)
In [26]: Imatrix =[]
...: for colonna in element.T:
...: Imatrix.append(np.multiply(ILO, colonna))
...: arr = np.array(Imatrix)
In [27]: arr.shape
Out[27]: (203, 36)
要將 (36,) 陣列和 (203,36) 相乘,我們不需要回圈。
In [28]: np.allclose(ILO*element.T, arr)
Out[28]: True
In [29]: %%timeit
...: Imatrix =[]
...: for colonna in element.T:
...: Imatrix.append(np.multiply(ILO, colonna))
...: arr = np.array(Imatrix)
...:
...:
405 μs ± 2.72 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
整個陣列操作要快得多:
In [30]: timeit ILO*element.T
19.4 μs ± 14.3 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
在您最初的問題中,您加載了一個.mat檔案。您是否正在嘗試翻譯 MATLAB 代碼? numpy 就像舊時的 MATLAB,其中全矩陣運算要快得多。 numpy不jit編譯回圈。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/474475.html
