web-dev-qa-db-ja.com

NumPy配列の初期化(同じ値で埋めます)

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

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

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

私はzerosonesがv = 0、1でうまくいくことを知っています。v * ones(n)を使うこともできますが vNoneであるときはうまくいきません。 はるかに遅くなります。

187
max

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]])

これは間違いなく特定の値で埋められた配列を作成する方法です。なぜなら、それは達成されていることを明示的に説明しているからです。それは非常に特定のタスクを実行します)。

241
Eric O Lebigot

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
84
Yariv

fill がこれを実行する最も速い方法だと思います。

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

また、自分の例で行っているように、繰り返しを避けるようにしてください。単純なa[:] = vはあなたの繰り返しがnumpy broadcast を使って行うことを達成します。

60
Paul

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

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!)

それで、試してみて、自分のプラットフォームで最も速いものを使ってください。

13
Rolf Bartstra

私は持っていた

numpy.array(n * [value])

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

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

enter image description here

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,
    )
9
Nico Schlömer

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は(この場合のようにスカラーの代わりに)配列を 'タイル'化することを目的としていますが、任意のサイズと次元の事前入力配列を作成して作業を行います。

6
Rolf Bartstra

ぎくしゃくせず

>>>[2]*3
[2, 2, 2]
1
Mr.Green