Подтвердить что ты не робот

Найти индекс, где элементы меняют значение 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, так как я начинаю новичком.

4b9b3361

Ответ 1

Вы можете получить эту функциональность в 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)

чтобы получить индексы, в которых используется функция "where"

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

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

Здесь вы можете добавить первый элемент и добавить один, чтобы перейти к той же схеме индексирования, что и в вашем вопросе.

Ответ 2

Может быть, потому что Python 3.5, но приведенные выше коды не сработали для меня.

Похоже, v[:-1] != v[1:] не возвращает iterable, а одиночный bool.

Я придумал следующее понимание списка с помощью zip и enumerate

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

Кто-то, ищущий решение в py3.5, может найти это полезным!

Ответ 3

Аналогично @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])

EDIT: как упоминалось в @Praveen, это не удается, когда последний и первый элементы равны.