2

以下の「b」配列の欠損値を「c」の対応する行平均に置き換えるにはどうすればよいですか?

a=numpy.arange(24).reshape(4,-1)
b=numpy.ma.masked_where(numpy.remainder(a,5)==0,a);b
Out[46]: 
 masked_array(data =
 [[-- 1 2 3 4 --]
 [6 7 8 9 -- 11]
 [12 13 14 -- 16 17]
 [18 19 -- 21 22 23]],
         mask =
 [[ True False False False False  True]
 [False False False False  True False]
 [False False False  True False False]
 [False False  True False False False]],
       fill_value = 999999)

c=b.mean(axis=1);c
Out[47]: 
masked_array(data = [2.5 8.2 14.4 20.6],
         mask = [False False False False],
   fill_value = 1e+20)
4

2 に答える 2

2

あなたは使用することができwhereますtake

inds = np.where(b.mask)

b[inds] = np.take(c,inds[0])

b
masked_array(data =
 [[2 1 2 3 4 2]
 [6 7 8 9 8 11]
 [12 13 14 14 16 17]
 [18 19 20 21 22 23]],
             mask =
 [[False False False False False False]
 [False False False False False False]
 [False False False False False False]
 [False False False False False False]],
       fill_value = 999999)

この特定の例では、dtypeof に問題がありaます。a = a.astype(np.float)作成前に追加すると、bうまく機能します。より高速にインデックスを作成する方法があるかもしれませんnp.where

于 2013-10-30T16:43:57.983 に答える
2

これを試して:

np.copyto(b, c[...,None], where=b.mask)

c各行に適用することを認識できるように、追加の軸を追加する必要があります。( のようなオプションがあればnp.meankeepdimsこれnp.sumは必要ありません:P

import numpy as np

a = np.arange(24).reshape(4,-1).astype(float)   # I changed your example to be a float
b = np.ma.masked_where(numpy.remainder(a,5)==0,a)
c = b.mean(1)

np.copyto(b, c[...,None], where=b.mask)

In [189]: b.data
Out[189]: 
array([[  2.5,   1. ,   2. ,   3. ,   4. ,   2.5],
       [  6. ,   7. ,   8. ,   9. ,   8.2,  11. ],
       [ 12. ,  13. ,  14. ,  14.4,  16. ,  17. ],
       [ 18. ,  19. ,  20.6,  21. ,  22. ,  23. ]])

これは、inds配列を作成するよりも高速です。

In [169]: %%timeit
   .....: inds = np.where(b.mask)
   .....: b[inds] = np.take(c, inds[0])
   .....: 
10000 loops, best of 3: 81.2 µs per loop


In [173]: %%timeit
   .....: np.copyto(b, c[...,None], where=b.mask)
   .....: 
10000 loops, best of 3: 45.1 µs per loop

もう1つの利点は、dtypeの問題について警告することです:

a = np.arange(24).reshape(4,-1)    # still an int
b = np.ma.masked_where(numpy.remainder(a,5)==0,a)
c = b.mean(1)

In [193]: np.copyto(b, c[...,None], where=b.mask)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-193-edc7f01f3f89> in <module>()
----> 1 np.copyto(b, c[...,None], where=b.mask)

TypeError: Can not cast scalar from dtype('float64') to dtype('int64') according to the rule 'same_kind'

ちなみに、次のようなさまざまなソース形式に応じて、このようなタスク用の関数のセットがあります。

np.put
インデックスで指定された場所の出力配列に入力配列を順番に配置し、@ Ophionの回答のように機能します。

np.place
入力 (リストまたは 1 次元配列) の各要素を、マスクが true である出力配列内の場所に順次割り当てます (形状が一致する必要がないため、入力配列と整列しません)。

np.copyto
は常に、入力配列の値を出力配列の同じ (ブロードキャストされた) 場所に配置します。形状は一致する (またはブロードキャスト可能である) 必要があります。古い関数を効果的に置き換えますnp.putmask

于 2013-10-30T17:07:21.957 に答える