以下函式將 numpy 函式應用于兩個 numpy 陣列。
import numpy as np
def my_func(a: np.ndarray, b: np.ndarray) -> float:
return np.nanmin(a, axis=0) np.nanmin(b, axis=0)
>>> my_func(np.array([1., 2., np.nan]), np.array([1., np.nan]))
2.0
但是,將相同的函式應用于不同形狀的 np.array 的 np.array 的最佳方法是什么?
a = np.array([np.array([1., 2]), np.array([1, 2., 3, np.nan])], dtype=object) # First array shape (2,), second (3,)
b = np.array([np.array([1]), np.array([1.5, 2.5, np.nan])], dtype=object)
np.vectorize 確實有效
>>> np.vectorize(my_func)(a, b)
array([2. , 2.5])
但正如vectorize 檔案所指定的:
提供 vectorize 函式主要是為了方便,而不是為了性能。實作本質上是一個 for 回圈。
有沒有更聰明的解決方案?我可以使用np.pad來獲得相同的形狀,但它似乎不是最佳的,因為它需要填充到內部陣列的最大長度(這里是 4 fora和 3 for b)。
我查看了numba和有關性能的堆疊交換,但我不確定這種情況下的最佳實踐。
謝謝 !
uj5u.com熱心網友回復:
您的函式和陣列:
In [222]: def my_func(a: np.ndarray, b: np.ndarray) -> float:
...: return np.nanmin(a, axis=0) np.nanmin(b, axis=0)
...:
In [223]: a = np.array([np.array([1., 2]), np.array([1, 2., 3, np.nan])], dtype=object
...: ) # First array shape (2,), second (3,)
...: b = np.array([np.array([1]), np.array([1.5, 2.5, np.nan])], dtype=object)
In [224]: a
Out[224]: array([array([1., 2.]), array([ 1., 2., 3., nan])], dtype=object)
In [225]: b
Out[225]: array([array([1]), array([1.5, 2.5, nan])], dtype=object)
vectorize與簡單的串列理解進行比較:
In [226]: np.vectorize(my_func)(a, b)
Out[226]: array([2. , 2.5])
In [227]: [my_func(i,j) for i,j in zip(a,b)]
Out[227]: [2.0, 2.5]
和他們的時間:
In [228]: timeit np.vectorize(my_func)(a, b)
157 μs ± 117 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [229]: timeit [my_func(i,j) for i,j in zip(a,b)]
85.9 μs ± 148 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [230]: timeit np.array([my_func(i,j) for i,j in zip(a,b)])
89.7 μs ± 1.03 μs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
如果您要使用物件陣列,frompyfunc則比vectorize:
In [231]: np.frompyfunc(my_func,2,1)(a, b)
Out[231]: array([2.0, 2.5], dtype=object)
In [232]: timeit np.frompyfunc(my_func,2,1)(a, b)
83.2 μs ± 50.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
我有點驚訝它甚至比串列理解更好。
frompyfunc(和vectorize) 當輸入需要相互“廣播”時更有用:
In [233]: np.frompyfunc(my_func,2,1)(a[:,None], b)
Out[233]:
array([[2.0, 2.5],
[2.0, 2.5]], dtype=object)
我不是numba專家,但我懷疑它不處理物件 dtype 陣列,或者它并沒有提高速度。請記住,物件資料型別意味著元素是物件參考,就像在串列中一樣。
通過使用otypes函式創建并將其從計時回圈中取出,我獲得了更好的時間:
In [235]: %%timeit f=np.vectorize(my_func, otypes=[float])
...: f(a, b)
...:
...:
95.5 μs ± 316 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [236]: %%timeit f=np.frompyfunc(my_func,2,1)
...: f(a, b)
...:
...:
81.1 μs ± 103 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
如果您不了解otypes,則說明您還沒有np.vectorize足夠好地閱讀檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/324131.html
上一篇:在單個陣列中生成元素的所有組合(用于N個元素的組合)
下一篇:動態陣列-記憶體管理問題
