24

サイズ N*M の行列があり、各行の平均値を見つけたいと考えています。値は 1 から 5 で、値を持たないエントリは 0 に設定されます。ただし、次の方法を使用して平均を見つけたい場合、次の値を持つエントリもカウントするため、間違った平均が得られます。 0.

matrix_row_mean= matrix.mean(axis=1)

非ゼロ値のみの平均を取得するにはどうすればよいですか?

4

2 に答える 2

30

各行のゼロ以外の数を取得し、それを使用して各行の合計を平均化します。したがって、実装は次のようになります -

np.true_divide(matrix.sum(1),(matrix!=0).sum(1))

古いバージョンの NumPy を使用している場合は、次のnp.true_divideように count の float 変換を使用して を置き換えることができます -

matrix.sum(1)/(matrix!=0).sum(1).astype(float)

サンプルラン -

In [160]: matrix
Out[160]: 
array([[0, 0, 1, 0, 2],
       [1, 0, 0, 2, 0],
       [0, 1, 1, 0, 0],
       [0, 2, 2, 2, 2]])

In [161]: np.true_divide(matrix.sum(1),(matrix!=0).sum(1))
Out[161]: array([ 1.5,  1.5,  1. ,  2. ])

問題を解決する別の方法は、ゼロを に置き換えてNaNsから を使用することnp.nanmeanです。これにより、それらは無視NaNsされ、実際には元のzerosが無視されます。

np.nanmean(np.where(matrix!=0,matrix,np.nan),1)

パフォーマンスの観点から、最初のアプローチをお勧めします。

于 2016-07-23T13:57:10.683 に答える
11

ここでは、マスクされた配列を使用するより一般的なソリューションについて詳しく説明します。詳細を説明するために、1 のみで下三角行列を作成してみましょう。

matrix = np.tril(np.ones((5, 5)), 0)

上記の用語が明確でない場合、このマトリックスは次のようになります。

  [[ 1.,  0.,  0.,  0.,  0.],
   [ 1.,  1.,  0.,  0.,  0.],
   [ 1.,  1.,  1.,  0.,  0.],
   [ 1.,  1.,  1.,  1.,  0.],
   [ 1.,  1.,  1.,  1.,  1.]]

ここで、関数が各行に対して平均 1 を返すようにします。または、言い換えると、軸 1 の平均は 5 つの 1 のベクトルに等しいということです。これを実現するために、値がゼロのエントリが無効と見なされるマスクされたマトリックスを作成しました。これは次の方法で実現できますnp.ma.masked_equal

masked = np.ma.masked_equal(matrix, 0)

最後に、マスクされた要素 (0) を体系的に無視する numpy 操作をこの配列で実行します。これを念頭に置いて、次の方法で目的の結果を取得します。

masked.mean(axis=1)

これにより、エントリが 1 のみのベクトルが生成されます。


より詳細には、の出力は次のnp.ma.masked_equal(matrix, 0)ようになります。

masked_array(data =
 [[1.0 -- -- -- --]
 [1.0 1.0 -- -- --]
 [1.0 1.0 1.0 -- --]
 [1.0 1.0 1.0 1.0 --]
 [1.0 1.0 1.0 1.0 1.0]],
             mask =
 [[False  True  True  True  True]
 [False False  True  True  True]
 [False False False  True  True]
 [False False False False  True]
 [False False False False False]],
       fill_value = 0.0)

これは、上の eh 値--が無効であると見なされることを示します。これは、マスクされた配列の mask 属性にも True として表示されます。これは、IT が無効な要素であるため、無視する必要があることを示します。

最後に、この配列に対する平均演算の出力は次のようになります。

masked_array(data = [1.0 1.0 1.0 1.0 1.0],
             mask = [False False False False False],
       fill_value = 1e+20)
于 2018-03-26T23:08:22.847 に答える