Python numpy array integer indexed flat slice assignment
<p>Was experimenting with numpy and found this strange behavior.
This code works ok:</p>

<pre><code>&gt;&gt;&gt; a = np.array([[1, 2, 3], [4, 5, 6]])    
&gt;&gt;&gt; a[:, 1].flat[:] = np.array([-1, -1])
&gt;&gt;&gt; a 
array([[ 1, -1,  3],
       [ 4, -1,  6]])
</code></pre>

<p>But why this code doesn't change to -1 elements of 0 and 2 column?</p>

<pre><code>&gt;&gt;&gt; a[:, [0, 2]].flat[:] = np.array([-1, -1])
&gt;&gt;&gt; a 
array([[ 1, -1,  3],
       [ 4, -1,  6]])
</code></pre>

<p>And how to write the code so that would change to -1 elements of 0 and 2 columns like this?</p>

<p>UPD: use of <code>flat</code> or smt similar is necessarily in my example</p>

<p>UPD2: I made example in question basing on this code:</p>

<pre><code>img = imread(img_name)
xor_mask = np.zeros_like(img, dtype=np.bool)
# msg_bits looks like array([ True, False, False, ..., False, False,  True], dtype=bool)
xor_mask[:, :, channel].flat[:len(msg_bits)] = np.ones_like(msg_bits, dtype=np.bool)
</code></pre>

<p>And after assignment to xor mask with channel == 0 or 1 or 2 code works ok, but if channel == [1,2] or smt like this, assignment does not happen </p>

<p>You could just remove the <code>flat[:]</code> <code>from a[:, [0, 2]].flat[:] += 100</code>:</p>

<pre><code>&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; a = np.array([[1, 2, 3], [4, 5, 6]])
&gt;&gt;&gt; a[:, 1].flat[:] += 100
&gt;&gt;&gt; a
array([[  1, 102,   3],
       [  4, 105,   6]])
&gt;&gt;&gt; a[:, [0, 2]] += 100
&gt;&gt;&gt; a
array([[101, 102, 103],
       [104, 105, 106]])
</code></pre>

<p>But you say it is necessary... Can't you just <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html" rel="nofollow"><code>reshape</code></a> whatever you are trying to add to the initial array instead of using <code>flat</code>?</p>

<p>The second index call makes a copy of the array while the first returns a reference to it:</p>

<pre><code>&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; a = np.array([[1, 2, 3], [4, 5, 6]])
&gt;&gt;&gt; b = a[:,1].flat
&gt;&gt;&gt; b[0] += 100
&gt;&gt;&gt; a
array([[  1, 102,   3],
       [  4,   5,   6]])
&gt;&gt;&gt; b =a[:,[0,2]].flat
&gt;&gt;&gt; b[0]
1
&gt;&gt;&gt; b[0] += 100
&gt;&gt;&gt; a
array([[  1, 102,   3],
       [  4,   5,   6]])
&gt;&gt;&gt; b[:]
array([101,   3,   4,   6])
</code></pre>

<p>It appears that when the elements you wish to iterate upon in a <code>flat</code> maner are not adjacent numpy makes an iterator over a copy of the array.</p>

python arrays python-2.7 numpy slice