2013-10-01 22 views
16

假設我有查找索引,其中,要素變化值numpy的

>>> v 
array([1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 5, 5]) 

有沒有發現每個索引,其中值變化的有效方式numpy的?舉例來說,我想了一些成績一樣,

>>> index_of_changed_values(v) 
[0, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16] 

如果這是不可能的一些numpy的套路,什麼是一個快速的方法來做到這一點在Python?由於我是一名初學者,因此我可以參考一些很好的numpy教程。

回答

28

您可以通過每個元素與它的鄰居比較得到numpy的這個功能;

v[:-1] != v[1:] 


array([False, False, False, False, True, False, False, True, True, 
    True, True, True, True, True, True, True, False, False], dtype=bool) 

獲得指數使用「其中」功能

np.where(v[:-1] != v[1:])[0] 

array([ 4, 7, 8, 9, 10, 11, 12, 13, 14, 15]) 

從這裏你可以預先考慮的第一要素,並添加一個讓你在你的問題具有相同的索引方案。

+0

這個完美的作品謝謝。很好的解釋。 – liang

+3

@kith如此簡單,如此完美,如此OMG! –

-1

也許這是因爲Python 3.5,但上面的代碼並沒有爲我工作。

看起來像v[:-1] != v[1:]不會返回iterable而只是一個bool

我想出了利用zipenumerate

[ i for i, (x, y) in enumerate(zip(v[:-1],v[1:])) if x!=y] 

有人尋找py3.5的解決方案可能會發現這個有用下面的列表理解!

+0

上面的代碼中使用numpy的 – ash

+0

@ash:我的意思是'v [: - 1]!= V [1:]'未返回*的'bools'陣列*(或更一般*陣列狀結構*),其反過來也不能在* python 3.5 *中使用'numpy.where'。答案針對的是那些會想到這個問題並使用python 3.5的人。 是的,我知道上面的代碼使用numpy的,這沒有。 – cipher

+1

即公元前他們必須numpy的陣列不是Python列表 – ash

-1

類似於@kith答案,但需要的結果的更小的按摩:

np.where(np.roll(v,1)!=v)[0] 

無需前面加上0或1。添加實施例 :

>>> v=np.array([1, 1, 1, 2, 2, 3, 3, 4, 4, 4]) 
>>> np.where(np.roll(v,1)!=v)[0] 
array([0, 3, 5, 7]) 

編輯:如@Praveen提到當最後一個元素和第一個元素相等時,這會失敗。

+0

這如果數組看起來就像是行不通的'[1,1,1,2,2,2,1,1,1]'。即第一個和最後一個值是相同的,所以你不會像你期望的那樣得到索引'0'... – Praveen