42

私が持っているとしましょう

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

値が変化する各インデックスを効率的に見つける方法はありますか? たとえば、次のような結果が必要です。

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

これがいくつかのnumpyルーチンでは不可能な場合、Pythonでそれを行うための高速な方法は何ですか? 私はnumpyの初心者なので、いくつかの優れたnumpyチュートリアルを参照することも役に立ちます。

4

4 に答える 4

75

各要素を隣接する要素と比較することで、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])

ここから、最初の要素を先頭に追加し、1 つ追加して、質問にあるのと同じインデックス スキームを取得できます。

于 2013-10-01T21:03:09.633 に答える
5

ほぼ10年後ですが、今日これに出会いました。

@kithの回答は良いですが、私たちが望むほどきれいではないかもしれません(回答で明示されていない手順も考慮してください)。

完全な形でのその答えは、

v = np.array([1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 5, 5])
np.concatenate((np.array([0]),np.where(v[:-1] != v[1:])[0]+1),axis=0)

私がもっと好きな代替案は、

np.where(np.diff(v,prepend=np.nan))[0]

これも返します

array([ 0,  5,  8,  9, 10, 11, 12, 13, 14, 15, 16], dtype=int64)

おっしゃる通り@kithさんと考え方は同じですが、

  • v[:-1] != v[1:]forを置き換えるとnp.diff()np.where配列がブール値にキャストされます。これはあまり変化しませんが、よりきれいに見えます。
  • 1 を追加して 0 を先頭に追加する余分な手順を削除しました。これは、実行np.nan前に先頭に追加することによって行われnp.diff()ます。diff 出力の最初の要素は にnp.nanなり、python np.nan では常に が評価されTrueます。
于 2021-01-10T19:09:53.757 に答える