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