How can I implement x[i][j] = y[i+j] efficiently in numpy?
<p>Let <strong>x</strong> be a matrix with a shape of (A,B) and <strong>y</strong> be an array with a size of A+B-1.</p>

<pre><code>for i in range(A):
    for j in range(B):
        x[i][j] = y[i+j]
</code></pre>

<p>How can I implement equivalent code efficiently using functions in numpy?</p>

<p><strong>Approach #1</strong> Using <a href="http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hankel.html" rel="nofollow"><code>Scipy's hankel</code></a> -</p>

<pre><code>from scipy.linalg import hankel

x = hankel(y[:A],y[A-1:]
</code></pre>

<p><strong>Approach #2</strong> Using <a href="http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html" rel="nofollow"><code>NumPy broadcasting</code></a> -</p>

<pre><code>x = y[np.arange(A)[:,None] + np.arange(B)]
</code></pre>

<p><strong>Approach #3</strong> Using <code>NumPy strides technique</code> -</p>

<pre><code>n = y.strides[0]
x = np.lib.stride_tricks.as_strided(y, shape=(A,B), strides=(n,n))
</code></pre>

<hr>

<p>Runtime test -</p>

<pre><code>In [93]: def original_app(y,A,B):
    ...:     x = np.zeros((A,B))
    ...:     for i in range(A):
    ...:         for j in range(B):
    ...:             x[i][j] = y[i+j]
    ...:     return x
    ...: 
    ...: def strided_method(y,A,B):
    ...:     n = y.strides[0]
    ...:     return np.lib.stride_tricks.as_strided(y, shape=(A,B), strides=(n,n))
    ...: 

In [94]: # Inputs
    ...: A,B = 100,100
    ...: y = np.random.rand(A+B-1)
    ...: 

In [95]: np.allclose(original_app(y,A,B),hankel(y[:A],y[A-1:]))
Out[95]: True

In [96]: np.allclose(original_app(y,A,B),y[np.arange(A)[:,None] + np.arange(B)])
Out[96]: True

In [97]: np.allclose(original_app(y,A,B),strided_method(y,A,B))
Out[97]: True

In [98]: %timeit original_app(y,A,B)
100 loops, best of 3: 5.29 ms per loop

In [99]: %timeit hankel(y[:A],y[A-1:])
10000 loops, best of 3: 114 Âµs per loop

In [100]: %timeit y[np.arange(A)[:,None] + np.arange(B)]
10000 loops, best of 3: 60.5 Âµs per loop

In [101]: %timeit strided_method(y,A,B)
10000 loops, best of 3: 22.4 Âµs per loop
</code></pre>

<p>Additional ways based on <code>strides</code> -</p>

<p>It seems <code>strides</code> technique has been used at few places : <a href="http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.image.extract_patches_2d.html" rel="nofollow"><code>extract_patches</code></a> and <a href="http://scikit-image.org/docs/dev/api/skimage.util.html#skimage.util.view_as_windows" rel="nofollow"><code>view_as_windows</code></a> that are being used in such image-processing based modules. So, with those, we have two more approaches -</p>

<pre><code>from skimage.util.shape import view_as_windows
from sklearn.feature_extraction.image import extract_patches

x = extract_patches(y,(B))
x = view_as_windows(y,(B))

In [151]: np.allclose(original_app(y,A,B),extract_patches(y,(B)))
Out[151]: True

In [152]: np.allclose(original_app(y,A,B),view_as_windows(y,(B)))
Out[152]: True

In [153]: %timeit extract_patches(y,(B))
10000 loops, best of 3: 62.4 Âµs per loop

In [154]: %timeit view_as_windows(y,(B))
10000 loops, best of 3: 108 Âµs per loop
</code></pre>

python numpy