web-dev-qa-db-ja.com

numpy配列を初期化して埋める最良の方法は?

numpy配列を初期化して埋めたい。最善の方法は何ですか?

これは期待どおりに機能します:

_>>> import numpy as np
>>> np.empty(3)
array([ -1.28822975e-231,  -1.73060252e-077,   2.23946712e-314])
_

しかし、これはそうではありません:

_>>> np.empty(3).fill(np.nan)
>>> 
_

何もない?

_>>> type(np.empty(3))
<type 'numpy.ndarray'>
_

np.empty()呼び出しが正しいタイプのオブジェクトを返しているように思えるので、なぜ.fill()が機能しないのか理解できませんか?

np.empty()の結果を最初に割り当てるとうまくいきます:

_>>> a = np.empty(3)
>>> a.fill(np.nan)
>>> a
array([ nan,  nan,  nan])
_

np.fill()を使用するために変数に割り当てる必要があるのはなぜですか?より良い代替手段がありませんか?

26
tbc

np.fill は配列をその場で変更し、Noneを返します。そのため、結果を名前に割り当てる場合、Noneの値を取得します。

別の方法は、nanを返す式を使用することです。例:

a = np.empty(3) * np.nan
27
shx2

また試すことができます:

In [79]: np.full(3, np.nan)
Out[79]: array([ nan,  nan,  nan])

関連ドキュメント:

Definition: np.full(shape, fill_value, dtype=None, order='C')
Docstring:
Return a new array of given shape and type, filled with `fill_value`.

これはnumpy 1.8+でのみ利用可能だと思うが

40
JoshAdel

これは覚えやすいと思います。

numpy.array([numpy.nan]*3)

好奇心から時間を計ったところ、 @ JoshAdelの答え@ shx2の答え の両方が、大きな配列の場合よりもはるかに高速でした。

In [34]: %timeit -n10000 numpy.array([numpy.nan]*10000)
10000 loops, best of 3: 273 µs per loop

In [35]: %timeit -n10000 numpy.empty(10000)* numpy.nan
10000 loops, best of 3: 6.5 µs per loop

In [36]: %timeit -n10000 numpy.full(10000, numpy.nan)
10000 loops, best of 3: 5.42 µs per loop
3
ryanjdillon

後で参照するために、np.nanの数学的特性のために、np.nanによる乗算のみが機能します。汎用値Nの場合、受け入れられた答えを模倣するnp.ones() * Nを使用する必要がありますが、速度的には、これはあまり良い選択ではありません。

既に指摘したように、最適な選択はnp.full()であり、それが利用できない場合は、np.zeros() + Nnp.ones() * Nよりも良い選択であるように見えますが、np.empty() + Nまたはnp.empty() * Nは単に適切ではありません。 Nnp.nanの場合、np.zeros() + Nも機能することに注意してください。

%timeit x = np.full((1000, 1000, 10), 432.4)
8.19 ms ± 97.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.zeros((1000, 1000, 10)) + 432.4
9.86 ms ± 55.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.ones((1000, 1000, 10)) * 432.4
17.3 ms ± 104 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.array([432.4] * (1000 * 1000 * 10)).reshape((1000, 1000, 10))
316 ms ± 37.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1
norok2