Fastest way to insert a 2D array into a (larger) 2D array
<p>Say there's two 2D arrays, <code>a</code> and <code>b</code></p>

<pre><code>import numpy as np
a = np.random.rand(3, 4)
b = np.random.zeros(8, 8)
</code></pre>

<p>and <code>b</code> is always larger than <code>a</code> over both axes.</p>

<p><em>(Edit: <code>b</code> is initialized as an array of zeros, to reflect the fact that all elements not occupied by <code>a</code> will remain zero.)</em></p>

<p><strong>Question</strong>. What's the <em>fastest</em> or <em>most Pythonic</em> way to "insert" <code>a</code> into <code>b</code>?</p>

<p>So far I've tried 2 things:</p>

<ol>
<li>Using <code>np.pad</code> to "turn" <code>a</code> into an array of shape <code>(8, 8)</code></li>
<li>Loop through every row in <code>a</code> and place it in some the corresponding row in <code>b</code></li>
</ol>

<p>What I <strong>haven't</strong> tried is using a doubly-nested loop to iterate over every element of <code>a</code>, since I think that's not performance-friendly.</p>

<p><strong>Motivation</strong>. Each array <code>a</code> is a tiny character, and I'd like to feed each character to a neural net that accepts <em>flattened</em> arrays of shape <code>(8, 8)</code>, ie. arrays of shape <code>(64,)</code>. (I <em>think</em> I can't simply flatten <code>a</code> to one dimension and pad it with zeros because then its two-dimensional structure gets warped, so, rather, I must first "reshape" it into <code>(8, 8)</code>, right?) There's a few millions of characters.</p>

<p>More generally you can determine the position where you want to insert the array if you create a tuple of slices (this works for arbitary dimensions):</p>

<pre><code>&gt;&gt;&gt; a = np.random.random((5,5))
&gt;&gt;&gt; b = np.ones((3,3))

&gt;&gt;&gt; edge_coordinate = (0,0)
&gt;&gt;&gt; slicer = tuple(slice(edge, edge+i) for edge, i in zip(edge_coordinate, b.shape))
&gt;&gt;&gt; a[slicer] = b
&gt;&gt;&gt; a
array([[ 1.        ,  1.        ,  1.        ,  0.14206495,  0.36385016],
       [ 1.        ,  1.        ,  1.        ,  0.08861402,  0.7888898 ],
       [ 1.        ,  1.        ,  1.        ,  0.1975496 ,  0.13345192],
       [ 0.550487  ,  0.22471952,  0.47050879,  0.04669643,  0.13480528],
       [ 0.25139511,  0.06499812,  0.42247189,  0.05840351,  0.74735495]])
</code></pre>

<p>by varying the <code>edge_coordinate</code> you can vary the position:</p>

<pre><code>&gt;&gt;&gt; a = np.random.random((5,5))
&gt;&gt;&gt; b = np.ones((3,3))

&gt;&gt;&gt; edge_coordinates = (1,1)  # changed
&gt;&gt;&gt; slicer = tuple(slice(edge, edge+i) for edge, i in zip(edge_coordinates, b.shape))
&gt;&gt;&gt; a[slicer] = b
&gt;&gt;&gt; a
array([[ 0.21385714,  0.68789872,  0.3915475 ,  0.67342566,  0.05642307],
       [ 0.19778658,  1.        ,  1.        ,  1.        ,  0.70717406],
       [ 0.73678924,  1.        ,  1.        ,  1.        ,  0.90285997],
       [ 0.39709332,  1.        ,  1.        ,  1.        ,  0.96959814],
       [ 0.89627195,  0.21295355,  0.72598992,  0.80749348,  0.76660287]])
</code></pre>

<p>Ideally one could make a function of it - if you regularly use it.</p>

python numpy