76

I am trying to drop multiple columns (column 2 and 70 in my data set, indexed as 1 and 69 respectively) by index number in a pandas data frame with the following code:

df.drop([df.columns[[1, 69]]], axis=1, inplace=True)

I get the following error:

TypeError: unhashable type: 'Index'

And in my code the [1, 69] is highlighted and says:

Expected type 'Integral', got 'list[int]' instead

The following code does what I want in two lines of repetitive code (first dropping col index 69, then 1, and order does matter because dropping earlier columns changes the index of later columns).

df.drop([df.columns[69]], axis=1, inplace=True)
df.drop([df.columns[1]], axis=1, inplace=True)

Is there a way to do this in one line similar to the first code snippet above?

cottontail
  • 10,268
  • 18
  • 50
  • 51
lukewitmer
  • 1,153
  • 3
  • 11
  • 21

3 Answers3

109

You don't need to wrap it in a list with [..], just provide the subselection of the columns index:

df.drop(df.columns[[1, 69]], axis=1, inplace=True)

as the index object is already regarded as list-like.

joris
  • 133,120
  • 36
  • 247
  • 202
22

Try this

df.drop(df.iloc[:, 1:69], inplace=True, axis=1)

This works for me

Okroshiashvili
  • 3,677
  • 2
  • 26
  • 40
  • 3
    For newer users, I recommend this answer as it will force you to work with positional indexing `df.iloc` which you will see appear in a lot of other questions looking to do something on a column or row in a given position (first, last, nth, between ith and jth, etc.). – blue_chip Jan 29 '19 at 14:36
0

A readable version is to pass the columns= argument.

df = df.drop(columns=df.columns[[1, 69]])

Putting df.columns[[1, 69]] inside a list (as in OP) becomes useful if we want to drop columns both by integer position and name(s) (simply need to unpack the array with *). For example, the following code drops the 2nd and the 70th columns along with another column named Some_Col.

df = df.drop(columns=[*df.columns[[1, 69]], 'Some_Col'])

Another way to drop columns is via the iloc indexer. For example, to drop the 2nd and 70th columns:

df = df.iloc[:, np.r_[:1, 2:69, 70:df.shape[1]]]
# or
df = df.iloc[:, ~np.isin(np.arange(df.shape[1]), [1,69])]
cottontail
  • 10,268
  • 18
  • 50
  • 51