![](/img/trans.png)
[英]Improve the efficiency of this search to check if any two numbers in this list sum to another?
[英]Is there any option to improve the time efficiency of the this data normalization any further?
我有一個名為 tArray 的矩陣,其形狀為 (11, 512) 並且想要對其中的值進行歸一化。 我看到 np.max() 花費了很多時間,但我沒有找到任何進一步改進它的選項。 下面這行代碼的時間效率可以提高嗎?:
tArray = np.array([[val/tArray[i][sqLen-1] for val in tArray[i]] if i not in [1,2] else [val/np.max(tArray[i][:sqLen-1]) for val in tArray[i]] for i in range(len(tArray))])
重現:
tArray = np.random.randint(1, 100, size=(11, 512))
tArray = np.array([[val/tArray[i][512-1] for val in tArray[i]] if i not in [1,2] else [val/np.max(tArray[i][:512-1]) for val in tArray[i]] for i in range(len(tArray))])```
這是〜180X加速改進方法:
請注意,對於輸入數組的形狀[512-1]
與[-1]
(最后一列)相同, [:512-1]
與[:-1]
相同。
循環的主要條件if i not in [1,2] else
表明聚合/計算隱含在 3 個切片中: [0]
(第一行)、 [1:3]
(第 1 行和第 2 行)和剩余行[3:]
。
因此,不是遍歷每一行並重新計算每一列,我們可以以矢量化方式一次對 3 個連續切片應用所需的操作,並最終將結果與np.vstack
例程連接起來:
np.vstack((tArray[0]/tArray[0,-1], tArray[1:3]/tArray[1:3,:-1].max(1)[:,None], tArray[3:]/tArray[3:,-1][:,None]))
讓我們看看測量:
tArray = np.random.randint(1, 100, size=(11, 512)) # input array
In [165]: %timeit tArray1 = np.array([[val/tArray[i][512-1] for val in tArray[i]] if i not in [1,2] else [val/np.max
...: (tArray[i][:512-1]) for val in tArray[i]] for i in range(len(tArray))])
4.54 ms ± 23.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [171]: %timeit new_arr = np.vstack((tArray[0]/tArray[0,-1], tArray[1:3]/tArray[1:3,:-1].max(1)[:,None], tArray[3:]/tAr
...: ray[3:,-1][:,None]))
25.5 µs ± 264 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
當然, tArray1
和new_arr
的內容是一樣的:
In [173]: tArray1
Out[173]:
array([[ 8.11111111, 2.33333333, 9.33333333, ..., 0.44444444,
5.22222222, 1. ],
[ 0.76767677, 0.77777778, 0.72727273, ..., 0.58585859,
0.29292929, 0.09090909],
[ 0.36363636, 0.85858586, 0.35353535, ..., 0.06060606,
0.48484848, 0.55555556],
...,
[ 1.875 , 2.04166667, 0.29166667, ..., 0.20833333,
0.58333333, 1. ],
[ 0.28735632, 0.11494253, 0.37931034, ..., 0.50574713,
0.74712644, 1. ],
[ 5.625 , 10.5 , 0.5 , ..., 2.125 ,
0.75 , 1. ]])
In [174]: new_arr
Out[174]:
array([[ 8.11111111, 2.33333333, 9.33333333, ..., 0.44444444,
5.22222222, 1. ],
[ 0.76767677, 0.77777778, 0.72727273, ..., 0.58585859,
0.29292929, 0.09090909],
[ 0.36363636, 0.85858586, 0.35353535, ..., 0.06060606,
0.48484848, 0.55555556],
...,
[ 1.875 , 2.04166667, 0.29166667, ..., 0.20833333,
0.58333333, 1. ],
[ 0.28735632, 0.11494253, 0.37931034, ..., 0.50574713,
0.74712644, 1. ],
[ 5.625 , 10.5 , 0.5 , ..., 2.125 ,
0.75 , 1. ]])
創建一個分母數組,用最大值替換所選行中的分母。 然后將整個矩陣除以這個分母數組(您需要轉置矩陣來執行此操作,然后再將其轉回)。
t = np.random.randint(1, 100, size=(11, 512))
ignore = [1, 2]
denoms = t[..., -1].copy()
denoms[ignore] = t[ignore, :-1].max(axis=1)
result = (t.T / denoms).T
這似乎比vstack
解決方案稍微快一些,並且還允許您更清楚地選擇哪些行到 select。
這對於 350 倍的加速(浮點數 560 倍)怎么樣?
def f(a):
d = a[:, -1].copy()
d[1:3] = a[1:3, :-1].max(1)
return a / d[:, None]
在float
arrays 上,它比@Roman 的答案快兩倍。 我認為它也更容易閱讀。
a = np.random.uniform(1, 100, size=(11, 512))
%timeit np.vstack((a[0]/a[0,-1], a[1:3,:]/a[1:3,:-1].max(), a[3:,:]/a[3:,-1][:,None]))
24.4 µs ± 102 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit f(a)
11.8 µs ± 22.9 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
在int
arrays 上,差別不大(快 60%)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.