Find index where elements change value numpy

2019-01-17 11:22发布

Suppose I have

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

Is there an efficient numpy way to find each index where the value changes? For instance, I would want some result like,

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

If this is not possible with some numpy routine, what is a fast way to do it in python? It would also be useful to me to be referred to some good numpy tutorials since I am a numpy beginner.

3条回答
Viruses.
2楼-- · 2019-01-17 11:52

You can get this functionality in numpy by comparing each element with it's neighbor;

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)

to get the indices you use the "where" function

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

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

From here you can prepend the first element and add a one to get to the same indexing scheme you have in your question.

查看更多
走好不送
3楼-- · 2019-01-17 11:53

Maybe It's because Python 3.5 but the above codes did not work for me.

Looks like v[:-1] != v[1:] does not return an iterable but a single bool.

I came up with following list comprehension using zip and enumerate

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

Someone looking for solution in py3.5 might find this useful!

查看更多
做自己的国王
4楼-- · 2019-01-17 11:58

Similar to @kith answer, but requires less massaging of the result:

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

No need to prepend 0 or add 1. Example:

>>> 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])

EDIT: as @Praveen mentioned, this fails when the last and the first elements are equal.

查看更多
登录 后发表回答