
I have two 1d arrays, say `a` and `b`. I need to swap elements if a 1d boolean criterion `to_swap` is met. Here's one way: a, b = np.choose([to_swap,np.logical_not(to_swap)], [a, b]) Here is a much faster way: a[to_swap], b[to_swap] = b[to_swap], a[to_swap] Other better ways? Thanks, Alan Isaac

su, 2010-02-07 kello 10:11 -0500, Alan G Isaac kirjoitti:
I have two 1d arrays, say `a` and `b`. I need to swap elements if a 1d boolean criterion `to_swap` is met. [clip] Here is a much faster way: a[to_swap], b[to_swap] = b[to_swap], a[to_swap]
That doesn't necessarily work -- the above code expands to tmp = a[to_swap] a[to_swap] = b[to_swap] b[to_swap] = tmp It'll work provided `to_swap` is such that `tmp` is not a view on `a`... -- Pauli Virtanen

On 2/7/2010 10:21 AM, Alan Isaac wrote:
I have two 1d arrays, say `a` and `b`. I need to swap elements if a 1d boolean criterion `to_swap` is met. [clip] Here is a much faster way: a[to_swap], b[to_swap] = b[to_swap], a[to_swap]
On 2/7/2010 10:21 AM, Pauli Virtanen wrote:
That doesn't necessarily work -- the above code expands to
tmp = a[to_swap] a[to_swap] = b[to_swap] b[to_swap] = tmp
It'll work provided `to_swap` is such that `tmp` is not a view on `a`...
I thought that if `to_swap` is a boolean array that `a[to_swap]` will always own its own data. Can that fail? Alan

su, 2010-02-07 kello 10:39 -0500, Alan G Isaac kirjoitti: [clip]
I thought that if `to_swap` is a boolean array that `a[to_swap]` will always own its own data. Can that fail?
Ok, I don't think it can fail, then. But it's a slightly dangerous idiom nevertheless... -- Pauli Virtanen

On Sun, Feb 7, 2010 at 7:58 AM, Pauli Virtanen <pav@iki.fi> wrote:
su, 2010-02-07 kello 10:39 -0500, Alan G Isaac kirjoitti: [clip]
I thought that if `to_swap` is a boolean array that `a[to_swap]` will always own its own data. Can that fail?
Ok, I don't think it can fail, then. But it's a slightly dangerous idiom nevertheless...
I think it depends on how much you know about the inputs:
to_swap = np.array([True, True])
Good:
a = np.array([1, 2, 3]) b = a[1:].copy()
a[to_swap], b[to_swap] = b[to_swap], a[to_swap] a array([2, 3, 3]) b array([1, 2])
Bad:
a = np.array([1, 2, 3]) b = a[1:]
a[to_swap], b[to_swap] = b[to_swap], a[to_swap]
a array([2, 1, 2]) b array([1, 2])

On 2/7/2010 11:16 AM, Keith Goodman wrote:
Bad:
a = np.array([1, 2, 3]) b = a[1:]
a[to_swap], b[to_swap] = b[to_swap], a[to_swap]
a array([2, 1, 2]) b array([1, 2])
So that is an important point: if `a` and `b` share data, the "swap" is not well defined. But that affects the alternative idiom as well:
to_swap array([ True, True], dtype=bool) a = np.array([1, 2, 3]) b = a[1:] temp = a.copy() a[to_swap] = b[to_swap] b[to_swap] = temp a, b (array([2, 1, 2]), array([1, 2]))
Thanks, Alan
participants (3)
-
Alan G Isaac
-
Keith Goodman
-
Pauli Virtanen