雖然@ BrenBarn的解決方案是完全有效的,非常緊湊,並在numpy的代碼通常的結構,你有兩次排序,它總是讓我吃驚因爲有點浪費。事實證明,你不必做第二種。下面的代碼並不簡單,但對於大型陣列來說會更快:
>>> my_weird_sort = np.empty_like(idx)
>>> my_weird_sort[idx] = np.arange(idx.size)
>>> my_weird_sort
array([5, 6, 3, 1, 2, 0, 4])
快多少?我做了一些計時,在我的系統上,對於小尺寸,速度稍微慢一點,對於〜100-200個物品的數組,啓動速度更快,對於1,000至1,000,000個物品的數組,速度要快1.4-1.5倍。
爲了完整起見,類似的構建體通常被用於第一個排序的陣列,獲得排序後的數組中的每一項的某個值,然後重新排列的結果返回到未排序的狀態。作爲一個例子,以找出是否一個項目是一個數組值的第一個實例,你可以這樣做:
>>> b = np.array([1, 3, 1, 2, 4, 3, 3, 2, 0])
>>> idx = np.argsort(b, kind='mergesort') # need stable sort
>>> sorted_b = b[idx]
>>> sorted_b
array([0, 1, 1, 2, 2, 3, 3, 3, 4])
>>> sorted_is_first = np.concatenate(([True], sorted_b[1:] != sorted_b[:-1]))
>>> sorted_is_first
array([ True, True, False, True, False, True, False, False, True], dtype=bool)
>>> is_first = sorted_is_first[idx.argsort()]
>>> is_first
array([ True, True, False, True, True, False, False, False, True], dtype=bool)
你也可以得到這個沒有第二個排序,由同樣做上面:
>>> is_first = np.empty_like(sorted_is_first)
>>> is_first[idx] = sorted_is_first
>>> is_first
array([ True, True, False, True, True, False, False, False, True], dtype=bool)
與此類似最近添加到np.unique
,對於被要求return_inverse
指標的情況下的變化,看到here。在那種情況下,大尺寸的速度幾乎是2倍。
相關:http://stackoverflow.com/a/25535723/166749 – 2014-09-21 15:41:24
哇!我發送該公關時大約在同一天的時間,阿里發佈了他的回覆給其他線程... – Jaime 2014-09-21 16:27:24
我知道,當我看到公關我立即檢查是否你是誰發佈的答案:) – 2014-09-21 20:22:36