對于二維陣列,我想獲得每行中特定切片的平均值,其中切片索引在每行的最后兩列中定義。
例子:
sample = np.array([
[ 0, 1, 2, 3, 4, 2, 5],
[ 5, 6, 7, 8, 9, 0, 3],
[10, 11, 12, 13, 14, 1, 4],
[15, 16, 17, 18, 19, 3, 5],
[20, 21, 22, 23, 24, 2, 4]
])
所以對于第 1 行,我想得到sample[0][2:5].mean(),第 2 行我想得到sample[0][0:3].mean(),第 3 行sample[0][1:4].mean(),等等。
我想出了一種使用方法apply_along_axis
def average_slice(x):
return x[x[-2]:x[-1]].mean()
np.apply_along_axis(average_slice, 1, sample)```
array([ 3. , 6. , 12. , 18.5, 22.5])
但是,“apply_along_axis”似乎很慢。
numpy np.apply_along_axis 函式加速?
從源代碼來看,似乎有對串列的轉換和直接回圈,盡管我對這段代碼沒有完全理解
https://github.com/numpy/numpy/blob/v1.22.0/numpy/lib/shape_base.py#L267-L414
我想知道是否有比我想出的計算效率更高的解決方案。
uj5u.com熱心網友回復:
有點 hacky,但一種使用numpy.cumsum速度快 200 倍的方法:
def faster(arr):
ind = arr[:, -2:]
padded = np.pad(arr.cumsum(axis=1), ((0, 0), (1, 0)))
res = np.diff(np.take_along_axis(padded, ind, axis=1))/np.diff(ind)
return res.ravel()
faster(sample)
輸出:
array([ 3. , 6. , 12. , 18.5, 22.5])
基準:
large = sample[np.random.randint(0, 5, 10000)]
%timeit np.apply_along_axis(average_slice, 1, large)
# 47 ms ± 166 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit faster(large)
# 305 μs ± 2.36 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
驗證:
np.array_equal(faster(large), np.apply_along_axis(average_slice, 1, large))
# True
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/436812.html
上一篇:如何在JavaScript中為陣列的每個元素添加id?
下一篇:遍歷遞回陣列并更新
