Swapping columns in a numpy array?
Solution 1:
There are two issues here. The first is that the data
you pass to your function apparently isn't a two-dimensional NumPy array -- at least this is what the error message says.
The second issue is that the code does not do what you expect:
my_array = numpy.arange(9).reshape(3, 3)
# array([[0, 1, 2],
# [3, 4, 5],
# [6, 7, 8]])
temp = my_array[:, 0]
my_array[:, 0] = my_array[:, 1]
my_array[:, 1] = temp
# array([[1, 1, 2],
# [4, 4, 5],
# [7, 7, 8]])
The problem is that Numpy basic slicing does not create copies of the actual data, but rather a view to the same data. To make this work, you either have to copy explicitly
temp = numpy.copy(my_array[:, 0])
my_array[:, 0] = my_array[:, 1]
my_array[:, 1] = temp
or use advanced slicing
my_array[:,[0, 1]] = my_array[:,[1, 0]]
Solution 2:
I find the following the fastest:
my_array[:, 0], my_array[:, 1] = my_array[:, 1], my_array[:, 0].copy()
Time analysis of:
import numpy as np
my_array = np.arange(900).reshape(30, 30)
is as follows:
%timeit my_array[:, 0], my_array[:, 1] = my_array[:, 1], my_array[:, 0].copy()
The slowest run took 15.05 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 1.72 µs per loop
The advanced slicing times are:
%timeit my_array[:,[0, 1]] = my_array[:,[1, 0]]
The slowest run took 7.38 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 6.9 µs per loop
Solution 3:
An elegant way to swap the columns in NumPy is analogy to swapping two variables
in Python like so: x, y = y, x
.
i, j = 0, 1
A.T[[i, j]] = A.T[[j, i]] # swap the columns i and j
Suppose you have a numpy array A
like this:
array([[ 0., -1., 0., 0.],
[ 0., 1., 1., 1.],
[ 0., 0., -1., 0.],
[ 0., 0., 0., -1.]])
A.T[[0, 1]] = A.T[[1, 0]]
will swap the first two columns:
array([[-1., 0., 0., 0.],
[ 1., 0., 1., 1.],
[ 0., 0., -1., 0.],
[ 0., 0., 0., -1.]])
Solution 4:
Building up on @Sven's answer:
import numpy as np
my_array = np.arange(9).reshape(3, 3)
print my_array
[[0 1 2]
[3 4 5]
[6 7 8]]
def swap_cols(arr, frm, to):
arr[:,[frm, to]] = arr[:,[to, frm]]
swap_cols(my_array, 0, 1)
print my_array
[[1 0 2]
[4 3 5]
[7 6 8]]
def swap_rows(arr, frm, to):
arr[[frm, to],:] = arr[[to, frm],:]
my_array = np.arange(9).reshape(3, 3)
swap_rows(my_array, 0, 2)
print my_array
[[6 7 8]
[3 4 5]
[0 1 2]]