2013-10-14 7 views
6

2次元配列内に5ピクセル×5ピクセルの規則的なグリッドを作成する関数を記述しようとしています。 numpy.repeatはちょうど同じ行に沿って繰り返されるので、私はnumpy.arangenumpy.repeatのいくつかの組み合わせがそれをするかもしれないが、今まで私は運がなかったことを望んでいた。ここで2次元配列内に規則的なグリッドを作成するNumpyルーチン

は一例です:

はのは、私は形状(20, 15)の2D配列内の5x5のグリッドをしたいとしましょう。私は単純にこれを達成するためにループやスライスを使用することができます実現が、私は非常に大きな配列にこれを適用することができ、私はそれのパフォーマンスが遅すぎるか、非現実的であろうと心配

array([[ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11], 
     [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11], 
     [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11], 
     [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11], 
     [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11]]) 

:それは次のようになります。 。

誰でもこの方法をお勧めしますか?

ありがとうございます。

UPDATE

提供されたすべての答えはうまく動作するように見えます。大規模な配列の中で最も効率的なものを教えてもらえますか?大きな配列では、100000 x 100000以上のグリッドセルサイズの15 x 15である可能性があります。

+1

「numpy.kron」、「numpy.repeat」を含むものの2つの解決策があります:http://stackoverflow.com/questions/7525214/how-to-scale-a-numpy-array – Brionius

+0

投稿ここでの答えですが、リンクされた質問で使用されている同じメソッド@NPEが使用されています。 – jorgeca

+0

@Brionius - numpy.kronは間違いなく働いた。あなたと@Mrの間にはパフォーマンスの違いがあると思いますか? Eの答えは? – Brian

答えて

3

放送はここに答えは:

ハイメの答えと同様に
m, n, d = 20, 15, 5 
arr = np.empty((m, n), dtype=np.int) 
arr_view = arr.reshape(m // d, d, n // d, d) 
vals = np.arange(m // d * n // d).reshape(m // d, 1, n // d, 1) 
arr_view[:] = vals 

>>> arr 
array([[ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], 
     [ 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11], 
     [ 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11], 
     [ 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11], 
     [ 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11], 
     [ 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11]]) 
+0

答えをありがとう。残念ながら、これは私のためには機能しませんでした。私は 'arr_view.shape =(4L、5L、3L、5L)'ではなく '(20,15)'で終わった。 – Brian

+0

@Brian 'arr_view'は元の配列のビューで、ブロードキャスト可能なシェイプを持つためにのみ使用されます。それはあなたが見たいと思う 'arr'です:それは形 '(20,15)'で残っています。 – Jaime

+0

私は参照してください。明確化のためにありがとう。私はビューの概念に精通していません。私はそれを調べなければならないでしょう。 – Brian

3

:(Brioniusもコメントで示唆したように)

np.repeat(np.arange(0, 10, 3), 4)[..., None] + np.repeat(np.arange(3), 5)[None, ...] 
+0

これは、ハイメの答えよりもはるかに簡単で、私がやろうとしていたことに非常に近いようです。私は '[...、なし]'に慣れていません。これはどういう意味ですか? – Brian

+0

これは放送と呼ばれています。最善の説明はこちら[http://scipy-lectures.github.io/intro/numpy/numpy.html#broadcasting]と[こちら](http://docs.scipy.org/doc/numpy/user /basics.broadcasting.html)。省略記号と放送の詳細については、こちらを参照してください(http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html)。ドキュメントに 'N​​one'の代わりに' np.newaxis'が使われることがあります。 – YXD

2

kronは、この拡張を行います。

xi, xj, ni, nj = 5, 5, 4, 3 
r = np.kron(np.arange(ni*nj).reshape((ni,nj)), np.ones((xi, xj))) 

私はそれをテストしていませんが、私はそれが放送アプローチよりも効率的ではないと考えますが、もう少し簡潔で理解しやすい(私が望む)。 1)1の配列が必要であり、2)xi*xjの乗算が1であり、3)複数のコンカチがあるからです。

+0

これは実際には機能しませんでした。小さな修正が必要です。 'np.ones((xi * ni、xj * nj))'は 'np.ones((xi、xj))'でなければなりません。訂正でそれはうまくいった。効率の説明をありがとう。 – Brian

+0

ありがとうございます。修正されました。 – tom10

関連する問題