1

A popular practice in numpy is a[:] = b[:], which copies the content of array b to array a. The two arrays a and b must be of the same size, of course. But many times what we want is just switching the content. For example, in time stepping of finite difference method, at the end of each time step, the current time step array a is updated to the new time step by a[:] = b[:]. I myself tend to use an alternative method a,b=b,a. Since a and b can be treated as references, I feel the latter is more lightweight/efficient. Following is a small benchmark script:

#!/usr/bin/python
import time
import numpy as np

a = np.random.random((100,100))
b = np.random.random((100,100))

N = 1000

print 'Method 1: a[:] = b[:]'
tstart = time.time()
for i in range(N):
    a[:] = b[:]
tend = time.time()
print tend - tstart

print 'Method 2: a, b = b, a'
tstart = time.time()
for i in range(N):
    a, b = b, a
tend = time.time()
print tend - tstart

On my laptop method 1 time 4 ms while method 2 times 0.1 ms, so the latter is 40 time faster. Many numerical code I came across use a[:] = b[:] unnecessarily. I feel as long as our real purpose is switching two arrays we should use a,b = b,a. And a[:] = b[:] should be used only when all we want is a copy of b (and nothing more). I don't have a deep knowledge about numpy even though I use it on a daily basis, so I post it here hoping some people can shed more light on this. * Just before I post this, I found another question asked two years ago which concerns mainly with synchronization (Swap Array Data in NumPy)

Update: this is more of an opinion rather than a question, I wish people using numpy be aware of this method and the significant speed difference and avoid unnecessary array copies.

Community
  • 1
  • 1
Taozi
  • 373
  • 5
  • 13
  • `a,b = b,a` only alters what the names `b` and `a` refer to, whereas `a[:] = b[:]` *mutates* `a`. – roippi May 22 '14 at 19:08
  • 1
    But anyway it doesn't appear that you've asked a question. – roippi May 22 '14 at 19:08
  • @roippi I don't think so. Some problems I solve use some large arrays of only two consecutive time steps, update b according to content of a, then copy content of b to a. I used to use a[:] = b[:] but now I use a,b=b,a, I tend to believe the latter way is better but not sure about it, that's why I ask here. – Taozi May 22 '14 at 19:13
  • this is not a `numpy` issue, this is just a python thing. Again, `a,b = b,a` flips what two variables refer to, it does not alter the underlying data in either. See @mgilson's answer. – roippi May 22 '14 at 19:16

1 Answers1

2

a, b = b, a works fine for simply swapping data associated with names so long as you don't do it in a function and expect the changes to propagate out. e.g.:

# wrong:
def swap(a, b):
    a, b = b, a
swap(x, y)  # x is still x and y is still y

# right-ish -- You really don't need the function if you're gonna do it this way.
def swap(a, b):
    return b, a
a, b = swap(a, b)

Also note that rather than b[:] = a[:], I think that b = a.copy() would be easier to understand and you don't need to pre-allocate b. The performance differences are likely to be irrelevant (though I haven't tested).

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • Hi, thank you for pointing this out. Could you further explain it a bit? The 'passing by reference' concept in C/C++ is so deep in my mind that I can't understand why inside a Python function the swap's effect won't propagate out as in C/C++. Sorry for this ignorance. – Taozi May 22 '14 at 19:34
  • People explain this lots of different ways ... From a C perspective (not sure about C++), think of it as `a` and `b` being pointers. Once you have the pointer, you can do stuff to the memory location that it points to and those changes will be seen outside the function. However, you can't make a pointer point to a _different_ memory location using pass by reference. In order to do that, you need to _return_ a pointer back. In the same way, with python, you can mutate an object in a function, but you can't (normally) change the object that a particular name refers to. – mgilson May 22 '14 at 19:46
  • Another reference: http://stackoverflow.com/a/10262945/748858 -- and I'm sure there are more if you look around StackOverflow for a bit. This is apparently a difficult thing for people coming from other languages to build an accurate mental model about. – mgilson May 22 '14 at 19:46