NumPy配列の初期化(同一の値で埋める)


237

n各要素がである長さのNumPy配列を作成する必要がありますv

より良いものはありますか:

a = empty(n)
for i in range(n):
    a[i] = v

私が知っているzerosones、V Iは、使用することができます= 0、1のために働くだろうv * ones(n)が、それは時に動作しませんvNone、またはるかに遅くなります。


1
私のコンピューターでは、0の場合、a = np.zeros(n)ループでの使用はよりも高速ですa.fill(0)a=np.zeros(n)新しいメモリを割り当てて初期化する必要があると思ったので、これは私が期待していたこととは逆です。誰かがこれを説明できたら、私はそれを感謝します。
user3731622 2016

セルは特定のデータ型で作成されますが、Noneには独自の型があり、実際にはポインタであるため、numpy配列にNoneを置くことはできません。
カミオン

@Camionええ、私は今知っています:)もちろんv * ones(n)、それは高価な乗算を使用するため、依然として恐ろしいです。と置き換え*+も、v + zeros(n)場合によっては驚くほど良いことがわかります(stackoverflow.com/questions/5891410/…)。
最大

max、vを追加する前に0の配列を作成する代わりに、空の配列を作成してvar = np.empty(n)から 'var [:] = v'で埋めるのがさらに高速です。(ところで、これnp.full()と同じくらい高速です)
Camion

回答:


308

導入numpyの1.8 np.full()より直接的な方法であり、empty()続いてfill()一定の値で充填アレイを作成します。

>>> np.full((3, 5), 7)
array([[ 7.,  7.,  7.,  7.,  7.],
       [ 7.,  7.,  7.,  7.,  7.],
       [ 7.,  7.,  7.,  7.,  7.]])

>>> np.full((3, 5), 7, dtype=int)
array([[7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7]])

これは間違いなく特定の値で満たされた配列を作成する方法です。これは達成されていることを明示的に示すためです(そして、非常に特定のタスクを実行するため、原則として非常に効率的です)。


1
このfull()メソッドは私にとってはうまく機能していますが、そのためのドキュメントが少し見つかりません。誰かが私を正しい場所に向けることができますか?
James Adams

1
少なくともhelp(numpy.full)Pythonシェルで実行できます。また、それがWebドキュメントにないことにも驚いています。
エリックOレビゴット2014年

私のシステム(Python 2.7、Numpy 1.8)では、np.full()は実際にはnp.empty()に続いてnp.fill()よりも少し遅いです。
John Zwinck 14

1
10,000要素の場合、同じものが観察されます(ただし、np.fill()存在しないためarr.fill())、約10%の違いがあります。差がもっと大きければ、NumPyバグ追跡システムで問題を提起します。:)私は、実行時間のこのような小さな違いのために、より明示的で明確なコードを好みますnp.full()
エリックOレビゴット2014

私のマシンでは、np.full()はnp.array.fill()と同じ速度です
Fnord

92

Numpy 1.7.0用に更新:(@Rolf Bartstraへのヒント)

a=np.empty(n); a.fill(5) 最速です。

速度の降順:

%timeit a=np.empty(1e4); a.fill(5)
100000 loops, best of 3: 5.85 us per loop

%timeit a=np.empty(1e4); a[:]=5 
100000 loops, best of 3: 7.15 us per loop

%timeit a=np.ones(1e4)*5
10000 loops, best of 3: 22.9 us per loop

%timeit a=np.repeat(5,(1e4))
10000 loops, best of 3: 81.7 us per loop

%timeit a=np.tile(5,[1e4])
10000 loops, best of 3: 82.9 us per loop

13
より最近の直接のタイミングを追加するnp.full()と便利です。私のマシンでは、NumPy 1.8.1を使用しているため、直接性の低いfill()バージョンよりも約15%遅くなっています(これは予想外ですが、full()わずかに速くなる可能性があります)。
エリックOレビゴット2014年

@DavidSanders:私があなたをフォローしているのかわかりません:fill()最速のソリューションです。乗算ソリューションははるかに遅いです。
エリックOレビゴット2015年

2
注:速度が本当に問題になる場合は、10000代わりにのサイズを使用する1e4と、何らかの理由で顕著な違いが生じます(を使用すると、full()ほぼ50%遅くなります1e4)。
エリックOレビゴット2015年

結果をfull()で追加するだけで、データ型が明示的にfloatでない場合、実行速度がかなり遅くなります。それ以外の場合は、ここでの最良の方法に匹敵します(ただし少し遅くなります)。
user2699

:@ user2699 I、10万個の要素で、これを観察していないですfull(100000, 5)full(100000, 5, dtype=float)full(100000, 5, dtype=int)およびa =np.empty(100000); a.fill(5)(キャッシングなしで:私のマシンで同じ時間についてのすべてのテイク%timeit -r1 -n1 …)(numpyの1.11.2)。
Eric O Lebigot、2016年

65

私は信じてfillこれを行うための最速の方法です。

a = np.empty(10)
a.fill(7)

また、例で行っているように、常に反復を避ける必要があります。シンプルなa[:] = vものは、numpy ブロードキャストを使用してイテレーションが行うことを実現します。


1
ありがとうございました。を見るとfill、それがrepeat自分のニーズによりよく合っていることがわかりました。
最大の

の回答を更新して、あなたのおすすめa[:]=vが実際には全体よりも速いと言ってもfillよろしいですか?
最大の

@max速いですか?ブロードキャスティングは、配列を埋めるためのより一般的な方法であり、の非常に狭いユースケースと同じか、遅いと思いfillます。
ポール

16

どうやら、絶対速度だけでなく、速度の順序(user1579844によって報告される)もマシンに依存します。これが私が見つけたものです:

a=np.empty(1e4); a.fill(5) 最速です。

速度の降順:

timeit a=np.empty(1e4); a.fill(5) 
# 100000 loops, best of 3: 10.2 us per loop
timeit a=np.empty(1e4); a[:]=5
# 100000 loops, best of 3: 16.9 us per loop
timeit a=np.ones(1e4)*5
# 100000 loops, best of 3: 32.2 us per loop
timeit a=np.tile(5,[1e4])
# 10000 loops, best of 3: 90.9 us per loop
timeit a=np.repeat(5,(1e4))
# 10000 loops, best of 3: 98.3 us per loop
timeit a=np.array([5]*int(1e4))
# 1000 loops, best of 3: 1.69 ms per loop (slowest BY FAR!)

したがって、試してみて、プラットフォームで最速のものを使用してください。


14

持っていた

numpy.array(n * [value])

念頭に置いてください、しかし明らかにそれは十分に大きい他のすべての提案よりも遅いですn

これはperfplot(私のペットプロジェクト)との完全な比較です。

ここに画像の説明を入力してください

2つのempty代替手段が(NumPy 1.12.1で)依然として最速です。full大きな配列に追いつきます。


プロットを生成するコード:

import numpy as np
import perfplot


def empty_fill(n):
    a = np.empty(n)
    a.fill(3.14)
    return a


def empty_colon(n):
    a = np.empty(n)
    a[:] = 3.14
    return a


def ones_times(n):
    return 3.14 * np.ones(n)


def repeat(n):
    return np.repeat(3.14, (n))


def tile(n):
    return np.repeat(3.14, [n])


def full(n):
    return np.full((n), 3.14)


def list_to_array(n):
    return np.array(n * [3.14])


perfplot.show(
    setup=lambda n: n,
    kernels=[empty_fill, empty_colon, ones_times, repeat, tile, full, list_to_array],
    n_range=[2 ** k for k in range(27)],
    xlabel="len(a)",
    logx=True,
    logy=True,
)

7

使用できますnumpy.tile。例:

v = 7
rows = 3
cols = 5
a = numpy.tile(v, (rows,cols))
a
Out[1]: 
array([[7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7]])

tile「タイル」(この場合のように代わりのスカラー)配列することを意味する、それは任意のサイズおよび寸法のプレフィルアレイを作成する仕事をします。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.