web-dev-qa-db-ja.com

numpy行列を0または1以外に初期化する

私は次のコードを持っています:

r = numpy.zeros(shape = (width, height, 9))

ゼロで埋められた幅x高さx 9のマトリックスを作成します。代わりに、NaNの代わりにそれらを初期化する関数または方法があるかどうかを知りたいです。

何かありますか?ループなどを手動で行うことに頼る必要はありませんか?

ありがとう

155

Numpyでのベクトル演算のループはほとんど必要ありません。初期化されていない配列を作成して、すべてのエントリに一度に割り当てることができます。

>>> a = numpy.empty((3,3,))
>>> a[:] = numpy.nan
>>> a
array([[ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN]])

Blaenkが投稿したa[:] = numpy.nanの代替とa.fill(numpy.nan)のタイミングを調整しました。

$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)"
10000 loops, best of 3: 54.3 usec per loop
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a[:] = np.nan" 
10000 loops, best of 3: 88.8 usec per loop

タイミングでは、ndarray.fill(..)がより高速な代替手段として優先されます。 OTOH、私はnumpyの便利な実装が好きです。この実装では、一度にスライス全体に値を割り当てることができます。コードの意図は非常に明確です。

223
u0b34a0f6ae

別のオプションは numpy.full を使用することです。これはNumPy 1.8+で利用可能なオプションです

a = np.full([height, width, 9], np.nan)

これは非常に柔軟性があり、必要な他の番号を入力できます。

127
pietro

速度の推奨代替案を比較し、十分な大きさのベクトル/行列を埋めるために、val * onesarray(n * [val])を除くすべての代替案が同等に高速であることを発見しました。

enter image description here


プロットを再現するコード:

import numpy
import perfplot

val = 42.0


def fill(n):
    a = numpy.empty(n)
    a.fill(val)
    return a


def colon(n):
    a = numpy.empty(n)
    a[:] = val
    return a


def full(n):
    return numpy.full(n, val)


def ones_times(n):
    return val * numpy.ones(n)


def list(n):
    return numpy.array(n * [val])


perfplot.show(
    setup=lambda n: n,
    kernels=[fill, colon, full, ones_times, list],
    n_range=[2**k for k in range(20)],
    logx=True,
    logy=True,
    xlabel='len(a)'
    )
35
Nico Schlömer

numpy.nanに精通していますか?

次のような独自のメソッドを作成できます。

def nans(shape, dtype=float):
    a = numpy.empty(shape, dtype)
    a.fill(numpy.nan)
    return a

それから

nans([3,4])

出力します

array([[ NaN,  NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN,  NaN]])

メーリングリストスレッド でこのコードを見つけました。

25

.emptyまたは.fullメソッドをすぐにリコールしない場合は、いつでも乗算を使用できます。

>>> np.nan * np.ones(shape=(3,2))
array([[ nan,  nan],
       [ nan,  nan],
       [ nan,  nan]])

もちろん、他の数値でも動作します:

>>> 42 * np.ones(shape=(3,2))
array([[ 42,  42],
       [ 42,  42],
       [ 42, 42]])

しかし、@ u0b34a0f6aeの 受け入れられた答え は3倍高速です(numpy構文を記憶する脳サイクルではなく、CPUサイクル;):

$ python -mtimeit "import numpy as np; X = np.empty((100,100));" "X[:] = np.nan;"
100000 loops, best of 3: 8.9 usec per loop
(predict)laneh@predict:~/src/predict/predict/webapp$ master
$ python -mtimeit "import numpy as np; X = np.ones((100,100));" "X *= np.nan;"
10000 loops, best of 3: 24.9 usec per loop
10
hobs

前述のように、numpy.empty()が方法です。ただし、オブジェクトの場合、fill()は、思ったとおりに動作しない場合があります。

In[36]: a = numpy.empty(5,dtype=object)
In[37]: a.fill([])
In[38]: a
Out[38]: array([[], [], [], [], []], dtype=object)
In[39]: a[0].append(4)
In[40]: a
Out[40]: array([[4], [4], [4], [4], [4]], dtype=object)

1つの方法は、たとえば次のとおりです。

In[41]: a = numpy.empty(5,dtype=object)
In[42]: a[:]= [ [] for x in range(5)]
In[43]: a[0].append(4)
In[44]: a
Out[44]: array([[4], [], [], [], []], dtype=object)
4
ntg

別の代替手段はnumpy.broadcast_to(val,n)です。これはサイズに関係なく一定の時間で戻り、最もメモリ効率がよくなります(繰り返し要素のビューを返します)。注意点は、返される値が読み取り専用であることです。

以下は、 NicoSchlömer's answer と同じベンチマークを使用して提案された他のすべての方法のパフォーマンスの比較です。

enter image description here

4

ここでまだ触れていないもう1つの可能性は、NumPyタイルを使用することです。

a = numpy.tile(numpy.nan, (3, 3))

また与える

array([[ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN]])

速度の比較については知りません。

2
JHBonarius