6

b配列を別の配列との算術演算の場合と同じ形にブロードキャストしたいと思いaます。

たとえば、a.shape = (3,3)とがスカラーだった場合、形状がスカラーであり、スカラーで埋められてbいる配列を取得したいと思います。(3,3)

これを行う1つの方法は次のとおりです。

>>> import numpy as np
>>> a = np.arange(9).reshape((3,3))
>>> b = 1 + a*0
>>> b
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

これは実際には機能しますが、少し奇妙に見えるので仕方がなく、私がやろうとしていたコードを見ている他の人にはわかりません。

これを行うためのよりエレガントな方法はありますか?のドキュメントを見てきましたがnp.broadcast、桁違いに遅くなっています。

In [1]: a = np.arange(10000).reshape((100,100))

In [2]: %timeit 1 + a*0
10000 loops, best of 3: 31.9 us per loop

In [3]: %timeit bc = np.broadcast(a,1);np.fromiter((v for u, v in bc),float).reshape(bc.shape)
100 loops, best of 3: 5.2 ms per loop

In [4]: 5.2e-3/32e-6
Out[4]: 162.5
4

4 に答える 4

7

配列をスカラーで埋めたいだけの場合fillは、おそらく最良の選択です。しかし、もっと一般化したものが必要なようです。使用するのではなく、(私が思うに)あなたが望む結果を得るためにbroadcast使用することができます。broadcast_arrays

>>> a = numpy.arange(9).reshape(3, 3)
>>> numpy.broadcast_arrays(a, 1)[1]
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

これは、任意の2つのブロードキャスト可能な形状に一般化されます。

>>> numpy.broadcast_arrays(a, [1, 2, 3])[1]
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

これは、ベースの方法ほど高速ではありませんufuncが、それでも同じ桁数です。

>>> %timeit 1 + a * 0
10000 loops, best of 3: 23.2 us per loop
>>> %timeit numpy.broadcast_arrays(a, 1)[1]
10000 loops, best of 3: 52.3 us per loop

しかし、スカラーfillは依然として明確な最有力候補です。

>>> %timeit b = numpy.empty_like(a, dtype='i8'); b.fill(1)
100000 loops, best of 3: 6.59 us per loop

最後に、さらにテストを行うと、最速のアプローチ(少なくとも一部のケースでは)は次の値を掛けることであることが示されていますones

>>> %timeit numpy.broadcast_arrays(a, numpy.arange(100))[1]
10000 loops, best of 3: 53.4 us per loop
>>> %timeit (1 + a * 0) * numpy.arange(100)
10000 loops, best of 3: 45.9 us per loop
>>> %timeit b = numpy.ones_like(a, dtype='i8'); b * numpy.arange(100)
10000 loops, best of 3: 28.9 us per loop
于 2012-07-24T02:48:31.113 に答える
2

私が知っている最速で最もクリーンなソリューションは次のとおりです。

b_arr = numpy.empty(a.shape)  # Empty array
b_arr.fill(b)  # Filling with one value
于 2012-07-24T02:49:21.663 に答える
2

fill最も簡単な方法のように聞こえます:

>>> a = np.arange(9).reshape((3,3))
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> a.fill(10)
>>> a
array([[10, 10, 10],
       [10, 10, 10],
       [10, 10, 10]])

編集: @EOLが指摘しているarangeように、新しい配列np.empty((100,100))(または任意の形状)を作成する場合は必要ありません。

タイミング:

In [3]: a = np.arange(10000).reshape((100,100))
In [4]: %timeit 1 + a*0
100000 loops, best of 3: 19.9 us per loop

In [5]: a = np.arange(10000).reshape((100,100))
In [6]: %timeit a.fill(1)
100000 loops, best of 3: 3.73 us per loop
于 2012-07-24T02:45:34.403 に答える
1

スカラーを任意の形状にブロードキャストする必要がある場合は、次のようにすることができます。

a = b*np.ones(shape=(3,3))

編集:np.tileより一般的です。これを使用して、任意の数の次元で任意のスカラー/ベクトルを複製できます。

b = 1
N = 100
a = np.tile(b, reps=(N, N))
于 2012-07-24T02:07:54.627 に答える