9

while ループ内にある配列から要素を削除するために numpy.delete を使用しています。この while ループは、配列が空でない場合にのみ有効です。このコードは問題なく動作しますが、配列に 1e6 を超える要素がある場合、速度が大幅に低下します。次に例を示します。

while(array.shape[0] > 0):
     ix = where((array >= x) & (array <= y))[0]
     array = delete(array,ix,None)

このコードを効率的にしようとしましたが、while ループを高速化する良い方法が見つかりません。ここでのボトルネックは、ある種のコピーを必要とする削除だと思います。コピーを避けるためにマスクされた配列を使用しようとしましたが、Pythonが苦手で、マスクされた配列は検索が簡単ではありません。上記のループで 7e6 要素を 24 時間もかからずに処理できるように、削除または置換を使用する適切で迅速な方法はありますか?

ありがとう

4

3 に答える 3

9

したがって、次の方法でコードのパフォーマンスを大幅に向上させることができます。

  • ループを排除します。と

  • 削除操作(元の配列のコピーが発生する)を回避する

NumPy 1.7では、元のマスクよりもはるかに使いやすい新しいマスクが導入されました。NumPyコア配列オブジェクトの一部であるため、パフォーマンスも大幅に向上します。これを使用することで、コストのかかる削除操作を回避できるため、これは便利な場合があると思います。

つまり、不要な配列要素を削除するのではなく、マスクするだけです。これは他の回答で提案されていますが、私は新しいマスクを使用することを提案しています

NAを使用するには、NAをインポートするだけです

>>> from numpy import NA as NA

次に、特定の配列に対して、masknaフラグをTrueに設定します

>>> A.flags.maskna = True

または、ほとんどの配列コンストラクター(1.7以降)にはパラメーターmasknaがあり、これをTrueに設定できます。

>>> A[3,3] = NA

array([[7, 5, 4, 8, 4],
       [2, 4, 3, 7, 3],
       [3, 1, 3, 2, 1],
       [8, 2, 0, NA, 7],
       [0, 7, 2, 5, 5],
       [5, 4, 2, 7, 4],
       [1, 2, 9, 2, 3],
       [7, 5, 1, 2, 9]])

>>> A.sum(axis=0)
array([33, 30, 24, NA, 36])

多くの場合、これはあなたが望むものではありません-つまり、NAが0であるかのように扱われるその列の合計が必要です:

その動作を取得するには、skipmaパラメーターにTrueを渡します(ほとんどのNumPy配列コンストラクターにはNumPy 1.7でこのパラメーターがあります)。

>>> A.sum(axis=0, skipna=True)
array([33, 30, 24, 33, 36])

つまり、コードを高速化するには、ループを削除して新しいマスクを使用します。

>>> A[(A<=3)&(A<=6)] = NA

>>> A
array([[8, 8, 4, NA, NA],
       [7, 9, NA, NA, 8],
       [NA, 6, 9, 5, NA],
       [9, 4, 6, 6, 5],
       [NA, 6, 8, NA, NA],
       [8, 5, 7, 7, NA],
       [NA, 4, 5, 9, 9],
       [NA, 8, NA, 5, 9]])

NAプレースホルダーは、このコンテキストでは0のように動作します。これは、あなたが望むものであると私は信じています。

>>> A.sum(axis=0, skipna=True)
array([32, 50, 39, 32, 31])
于 2012-05-14T20:25:38.060 に答える
3

私が間違っている場合は修正してください。ただし、次のことができると思います。

mask=np.where((array >= x) & (array <= y),True,False)
array=array[mask]

ループ全体を放棄しますか?

また、私のインタープリターでarray >= x & array <= yは、例外が発生します。あなたはおそらく次のことを意味していました: (array >= x) & (array <= y)

于 2012-05-14T19:43:55.040 に答える
1

numpy.delete のドキュメントによると、関数は指定された要素が削除された入力配列のコピーを返します。したがって、コピーする配列が大きいほど、関数は遅くなります。

http://docs.scipy.org/doc/numpy/reference/generated/numpy.delete.html

配列のチャンクを頻繁に削除する必要があるのはなぜですか? list配列が非常に動的な場合は、 a を使用して配列の一部を格納し、一度に小さいビットのみを削除する方がよい場合があります。

于 2012-05-14T19:41:48.080 に答える