41

Given a numpy 2d array (or a matrix), I would like to extract all the columns but the i-th.

E. g. from

1 2 3 4
2 4 6 8
3 6 9 12

I would like to have, e.g.

1 2 3
2 4 6
3 6 9

or

1 2 4
2 4 8
3 6 12

I cannot find a pythonic way to do this. I now that you can extract given columns by simply

a[:,n]

or

a[:,[n,n+1,n+5]]

But what about extracting all of them but one?

2

4 Answers 4

52

Since for the general case you are going to be returning a copy anyway, you may find yourself producing more readable code by using np.delete:

>>> a = np.arange(12).reshape(3, 4)
>>> np.delete(a, 2, axis=1)
array([[ 0,  1,  3],
       [ 4,  5,  7],
       [ 8,  9, 11]])
Sign up to request clarification or add additional context in comments.

2 Comments

This is perfect! One line, works for both an array and a matrix, very clear! Thanks
Wanted to mention that this doesn't mutate the a matrix. which is what I was expecting.
36

Use a slice that excludes the last element.

In [19]: a[:,:-1]
Out[19]: 
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])

If you want something other than the last element I'd just build a list to select with.

In [20]: selector = [x for x in range(a.shape[1]) if x != 2]
In [21]: a[:, selector]
Out[21]: 
array([[ 1,  2,  4],
       [ 2,  4,  8],
       [ 3,  6, 12]])

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html

3 Comments

Nice, note that this method uses advanced integer slicing (selecting columns by their indicies), whereas the solution I posted uses advanced boolean slicing (selecting columns with a boolean mask). Both are good.
I'm trying to make it even simpler by using the selector range(a.shape[1]).remove(2) but this doesn't seem to work. Do you know why?
@FerdinandoRandisi .remove doesn't return the array it modifies it in place, so the result of range(a.shape[1]).remove(2) is None. You could use selector = range(a.shape[1]); selector.remove(2)
11

Take a look at numpy's advanced slicing

>>> import numpy as np
>>> a = np.array([[1,2,3,4], [2,4,6,8], [3,6,9,12]])
>>> a[:,np.array([True, True, False, True])]
array([[ 1,  2,  4],
       [ 2,  4,  8],
       [ 3,  6, 12]])

Comments

0

The answers given already can easily be adapted to selecting all but a list of columns, but here are a couple of explicit examples:

In [1]: import numpy as np
In [2]: a = np.arange(12).reshape(3, 4)
In [3]: a
Out[3]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [4]: drop_cols = [0, 3]

# option 1: delete the columns you don't want (like @Jaime)
# (this is really the most straightforward)

In [5]: np.delete(a, drop_cols, axis=1)
Out[5]:
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10]])

# option 2: pass the indices of columns to keep (like @chrisb)

In [6]: a[:, [i for i in range(a.shape[1]) if i not in drop_cols]]
Out[6]:
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10]])

# option 3: use an array of T/F for each col (like @Peter Gibson)

In [7]: a[:, [i not in drop_cols for i in range(a.shape[1])]]
Out[7]:
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.