我有許多矩陣要添加。假設矩陣是[M1,M2 ...,M_n]。然後,一個簡單的辦法就是numpy矩陣加法的有效方法
X = np.zeros()
for M in matrices:
X += M
在操作上,X + = M,並Python中創建一個新的內存X每次+ =執行?如果是這樣的話,那似乎是低效的。在沒有爲X創建新內存的情況下進行就地操作有什麼方法嗎?
我有許多矩陣要添加。假設矩陣是[M1,M2 ...,M_n]。然後,一個簡單的辦法就是numpy矩陣加法的有效方法
X = np.zeros()
for M in matrices:
X += M
在操作上,X + = M,並Python中創建一個新的內存X每次+ =執行?如果是這樣的話,那似乎是低效的。在沒有爲X創建新內存的情況下進行就地操作有什麼方法嗎?
這工作,但不是我的機器上更快:
numpy.sum(matrices, axis=0)
除非你得到的MemoryError,試圖第二次猜測內存使用numpy的是不值得的。將其留給知道編譯代碼的開發人員。
但是我們可以執行一些時間測試 - 這纔是真正重要的,不是嗎?
我會測試添加一個好的大小數組100次。
In [479]: M=np.ones((1000,1000))
您與+ =
In [480]: %%timeit
...: X=np.zeros_like(M)
...: for _ in range(100): X+=M
...:
1 loop, best of 3: 627 ms per loop
或者使尺寸的陣列(100,1000,1000),並應用np.sum
跨過第一軸線迭代方法。
In [481]: timeit np.sum(np.array([M for _ in range(100)]),axis=0)
1 loop, best of 3: 1.54 s per loop
並使用np.add
ufunc。通過reduce
,我們可以將它依次應用於列表中的所有值。
In [482]: timeit np.add.reduce([M for _ in range(100)])
1 loop, best of 3: 1.53 s per loop
的np.sum
情況下給我的MemoryError如果我使用range(1000)
。我沒有足夠的內存來存放(1000,1000,1000)數組。 add.reduce
相同,從列表中構建一個數組。
+=
什麼+=
在掩護下通常是隱藏的,並且我們通常不關心。但對於下蓋峯看ufunc.at
:https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html#numpy.ufunc.at
上執行操作到位操作無緩衝「A」由「指數」指定的元素。對於另外的ufunc,這個方法等同於[indices] + = b,除了對索引多於一次的元素累計結果。
因此X+=M
會將總和寫入緩衝區,然後將該緩衝區複製到X
。有一個臨時緩衝區,但最終的內存使用情況不會改變。 但是,該緩衝區的創建和複製是在快速C代碼中完成的。
np.add.at
被添加來處理緩衝動作產生一些問題(重複索引)的情況。
因此,它避免了臨時緩衝區 - 但速度相當快。這可能是增加的索引功能會降低速度。 (可能有更公平的add.at
測試;但在這種情況下肯定無濟於事。)
In [491]: %%timeit
...: X=np.zeros_like(M)
...: for _ in range(100): np.add.at(X,(slice(None),slice(None)),M)
1 loop, best of 3: 19.8 s per loop
你究竟做了什麼:'[M1,M2 ...,M_n]'?它是一個數組列表嗎?添加一個樣本? – Divakar
@Divakar我認爲這是一個矩陣列表。 – TuanDT
@Divakar,M是np.ndarray。 – DSKim