簡體   English   中英

為什么python`in`比`np.isin`要快得多

[英]Why is python `in` much faster than `np.isin`

我正在使用numpy實現一些搜索算法,其中一步是檢查天氣,向量是否在矩陣中(作為行)。 我用np.isin之前,但我突然變得好奇將蟒蛇關鍵字in工作。 因此,我對其進行了測試,發現它可以正常工作。

由於我沒有找到in任何python接口(例如__add__表示+__abs__表示abs ),因此我相信通過使用標准迭代器邏輯在python in進行硬連接,因此與numpy np.isin相比,它應該更慢np.isin 但經過一些測試,令人難以置信:

>>> a = np.int8(1)
>>> A = np.zeros(2**24, 'b')
>>> %timeit a in A
>>> %timeit np.isin(a, A)
21.7 ms ± 1.58 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
310 ms ± 20.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

這賽斯np.isin比蟒慢10+倍in為小的數據類型。 我也測試了大數據類型

>>> a = np.ones(1, 'V256')
>>> A = np.zeros(2**22, 'V256')
>>> %timeit a in A
>>> %timeit np.isin(a, A)
129 ms ± 12.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
10.5 s ± 184 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

這表示np.isin慢100倍。

我想知道這可能是什么原因。 注意,由於a=1A=[0,0,...] ,則必須在整個數組上進行匹配。 在python端沒有“提前退出”這樣的事情。

編輯哦,實際上in __contains__有python接口。 但是,為什么np.isin會比np.ndarray.__contains__慢得多?

numpy.ndarray.__contains__基本上只是(elem == arr).any() (即使那沒有意義)。 您可以看一下source ,它對於NumPy C例程而言非常簡短。

numpy.isin在其左操作數上廣播,並針對廣播情況下的效率進行了優化。 對於較小的左操作數,它將使用基於sort的方法 ,這對於標量而言是過大的。 當前,對於左操作數是標量,或者對於左手是足夠小的數組,以至於排序比單純的方法要昂貴得多,它沒有快速的路徑。

我的回答沒有問到。 可能會給你一些想法。 通常,從numpy獲得良好性能的主要想法是一次分攤許多元素上的解釋器成本。 換句話說,將循環從python代碼(慢)移到numpy / BLAS / LAPACK / etc中的C / Fortran循環。 內部(快速)。 如果成功完成該操作(稱為矢量化),則性能通常會很好。

當然,通過轉儲python解釋器並改為使用C ++,顯然可以提高性能。 這種方法是否成功取決於您對C ++和numpy進行高性能編程的能力,以及您要嘗試執行的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM