numpy配列の行を削除する


88

私はこのように見えるかもしれない配列を持っています:

ANOVAInputMatrixValuesArray = [[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 
0.53172222], [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]]

行の1つが最後にゼロ値を持っていることに注意してください。すべてのセルにゼロ以外の値を含む行を保持しながら、ゼロを含む行を削除したいと思います。

ただし、配列には、データが入力されるたびに異なる行数があり、ゼロは毎回異なる行に配置されます。

次のコード行を使用して、各行のゼロ以外の要素の数を取得します。

NumNonzeroElementsInRows    = (ANOVAInputMatrixValuesArray != 0).sum(1)

上記の配列の場合、次のものNumNonzeroElementsInRowsが含まれます。[5 4]

5つは、行0のすべての可能な値がゼロ以外であることを示し、4つは、行1の可能な値の1つがゼロであることを示します。

したがって、次のコード行を使用して、ゼロ値を含む行を見つけて削除しようとしています。

for q in range(len(NumNonzeroElementsInRows)):
    if NumNonzeroElementsInRows[q] < NumNonzeroElementsInRows.max():
        p.delete(ANOVAInputMatrixValuesArray, q, axis=0)

しかし、何らかの理由で、このコードは何も実行していないようですが、多くの印刷コマンドを実行すると、コードに至るまですべての変数が正しく入力されているように見えます。

単純に「ゼロ値を含む行を削除する」簡単な方法が必要です。

誰かがこれを達成するために書くべきコードを教えてもらえますか?

回答:


162

配列から行と列を削除する最も簡単な方法はnumpy.deleteメソッドです。

次の配列があるとしますx

x = array([[1,2,3],
        [4,5,6],
        [7,8,9]])

最初の行を削除するには、次のようにします。

x = numpy.delete(x, (0), axis=0)

3番目の列を削除するには、次のようにします。

x = numpy.delete(x,(2), axis=1)

したがって、0を含む行のインデックスを見つけて、それらをリストまたはタプルに入れ、これを関数の2番目の引数として渡すことができます。


ありがとう!私も同じ問題を抱えていましたが、単に電話をかけるだけでnumpy.delete(x, index)はうまくいかなかった理由がわかりませんでした。
アンチモン

6
numpy delete()のドキュメントには、新しい配列が返されるため、「ブールマスクを使用することが望ましい場合が多い」と記載されていることに注意してください。例はそのリンクの下にあります
arturomp 2016年

1
@arturompですが、マスクは非破壊的です。delete()の呼び出しは時間/メモリを消費しますか?
ネイサン

13

これがワンライナーです(はい、それはuser333700のものに似ていますが、もう少し簡単です):

>>> import numpy as np
>>> arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222], 
                [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
>>> print arr[arr.all(1)]
array([[ 0.96488889,  0.73641667,  0.67521429,  0.592875  ,  0.53172222]])

ちなみに、この方法は、大きな行列のマスク配列法よりもはるかに高速です。2048 x 5マトリックスの場合、この方法は約1000倍高速です。

ちなみに、user333700の方法(彼のコメントから)は私のテストでは少し速かったのですが、それは私の頭を悩ませます。


3
「any」は短絡する可能性があり、最初の真のケースが検出されるとすぐに停止する可能性がありますが、「all」はすべての条件をチェックする必要があります。したがって、(numpyの "〜")は、一般的にすべてよりも高速である必要があります。
Josef

4
@ user333700、両方とも短絡する可能性がありますが、異なるものになります。any検出された最初の真のケースで真に短絡します。all最初に検出された誤ったケースでfalseに短絡します。この場合、短絡は引き分けになるはずですが、余分なことをしないと、私の意見では遅くなるはずです。
ジャスティンピール

5

これは元のアプローチに似ており、unutbuの回答よりも少ないスペースを使用しますが、遅くなると思います。

>>> import numpy as np
>>> p = np.array([[1.5, 0], [1.4,1.5], [1.6, 0], [1.7, 1.8]])
>>> p
array([[ 1.5,  0. ],
       [ 1.4,  1.5],
       [ 1.6,  0. ],
       [ 1.7,  1.8]])
>>> nz = (p == 0).sum(1)
>>> q = p[nz == 0, :]
>>> q
array([[ 1.4,  1.5],
       [ 1.7,  1.8]])

ちなみに、あなたの行p.delete()は私には機能しませんndarray-sには.delete属性がありません。


8
もう少し単純:p [〜(p == 0).any(1)]または行に対してより明示的:p [〜(p == 0).any(1)、:]
Josef

2

numpyは、まったく同じことを行うための単純な関数を提供します。マスクされた配列 'a'があるとすると、numpy.ma.compress_rows(a)を呼び出すと、マスクされた値を含む行が削除されます。私はこれがこの方法ではるかに速いと思います...


1
import numpy as np 
arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222],[ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
print(arr[np.where(arr != 0.)])

-1

この質問に答えるには遅すぎるかもしれませんが、コミュニティの利益のために私の意見を共有したいと思いました。この例では、行列を「ANOVA」と呼びます。この行列から、5番目の列にのみ0が含まれる行を削除しようとしていると仮定します。

indx = []
for i in range(len(ANOVA)):
    if int(ANOVA[i,4]) == int(0):
        indx.append(i)

ANOVA = [x for x in ANOVA if not x in indx]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.