どうすれば派手な配列から特定の要素を削除できますか?私が持っていると言います
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
次に、から削除3,4,7
しa
ます。私が知っているのは、値のインデックス(index=[2,3,6]
)だけです。
どうすれば派手な配列から特定の要素を削除できますか?私が持っていると言います
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
次に、から削除3,4,7
しa
ます。私が知っているのは、値のインデックス(index=[2,3,6]
)だけです。
回答:
numpy.delete()を使用- 軸に沿ったサブ配列が削除された新しい配列を返します
numpy.delete(a, index)
特定の質問について:
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
index = [2, 3, 6]
new_a = np.delete(a, index)
print(new_a) #Prints `[1, 2, 5, 6, 8, 9]`
配列スカラーは不変で、Pythonの文字列に似ているnumpy.delete()
ため、新しい配列を返すことに注意してください。そのため、変更が行われるたびに、新しいオブジェクトが作成されます。つまり、ドキュメントを引用するには:delete()
「objで指定された要素が削除されたarr のコピー。削除はインプレースでは発生しないことに注意してください ...」
私が投稿したコードに出力がある場合、それはコードを実行した結果です。
それを手助けするための派手な組み込み関数があります。
import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = np.array([3,4,7])
>>> c = np.setdiff1d(a,b)
>>> c
array([1, 2, 5, 6, 8, 9])
np.setdiff1d(np.array(['one','two']),np.array(['two', 'three']))
Numpy配列は不変です。つまり、技術的には項目を削除できません。ただし、次のように、不要な値なしで新しい配列を作成できます。
b = np.delete(a, [2,3,6])
a[0]=1
変更a
します。ただし、サイズを変更することはできません。
派手な人間ではないので、私は次のことを試してみました:
>>> import numpy as np
>>> import itertools
>>>
>>> a = np.array([1,2,3,4,5,6,7,8,9])
>>> index=[2,3,6]
>>> a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))
>>> a
array([1, 2, 5, 6, 8, 9])
私のテストによると、これはを上回っていnumpy.delete()
ます。初期配列のサイズが小さいためか、なぜそうなるのかわかりません。
python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))"
100000 loops, best of 3: 12.9 usec per loop
python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "np.delete(a, index)"
10000 loops, best of 3: 108 usec per loop
これはかなり大きな違いです(私が期待していたのとは逆の方向です)。なぜこれが当てはまるのか、だれでも知っていますか?
さらに奇妙なことにnumpy.delete()
、リストを渡すと、リストをループして単一のインデックスを与えるよりもパフォーマンスが低下します。
python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "for i in index:" " np.delete(a, i)"
10000 loops, best of 3: 33.8 usec per loop
編集:配列のサイズに関係しているようです。大規模な配列でnumpy.delete()
は、大幅に高速です。
python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))"
10 loops, best of 3: 200 msec per loop
python -m timeit -s "import numpy as np" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "np.delete(a, index)"
1000 loops, best of 3: 1.68 msec per loop
明らかに、これはかなり重要ではありません。常に明確にするために行き、ホイールを再発明しないようにする必要がありますが、私は少し興味深いことに気づいたので、ここには残しておきたいと思いました。
a = delte_stuff(a)
ますあなたの最初の反復でa
すべての反復と小さいです。inbuild関数を使用する場合、値をaに格納しないで、aを元のサイズに保ちます。その上、関数を大幅に高速化できます。index
つまり、アイテムの削除の有無にかかわらず、セットoufを作成し、それに対してチェックします。両方を修正すると、1万アイテムが得られます。関数ではループあたり6.22ミリ秒、では4.48ミリ秒ですnumpy.delete
。これは、おおよその予想値です。
np.array(list(range(x)))
使用する代わりにnp.arange(x)
、インデックスを作成するためにを使用できますnp.s_[::2]
。
np.delete
削除する要素のインデックスがわかっている場合は、使用するのが最も速い方法です。ただし、完全を期すために、を使用して作成されたブールマスクを使用して配列要素を「削除」する別の方法を追加しますnp.isin
。このメソッドを使用すると、要素を直接またはインデックスで指定して、要素を削除できます。
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
インデックスで削除:
indices_to_remove = [2, 3, 6]
a = a[~np.isin(np.arange(a.size), indices_to_remove)]
要素ごとに削除(a
前の行で書き直されたので、オリジナルを再作成することを忘れないでください):
elements_to_remove = a[indices_to_remove] # [3, 4, 7]
a = a[~np.isin(a, elements_to_remove)]
特定のインデックスを削除します(マトリックスから16と21を削除しました)
import numpy as np
mat = np.arange(12,26)
a = [4,9]
del_map = np.delete(mat, a)
del_map.reshape(3,4)
出力:
array([[12, 13, 14, 15],
[17, 18, 19, 20],
[22, 23, 24, 25]])