これを試して:
np.copyto(b, c[...,None], where=b.mask)
c
各行に適用することを認識できるように、追加の軸を追加する必要があります。( のようなオプションがあればnp.mean
、keepdims
これ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
。