0

I was trying to solve an issue regarding deleting the last column of a dataframe until a certain column-length criteria is met, so I tried working on a very basic example before applying it to real problem but I am meeting this error I'm not too sure solve:

import pandas as pd
import numpy as np
a = {'ear':[1,3,32,2],'aear':[53,4,3,22],'was':[23,3,2,4]}
df = pd.DataFrame(a)
print(df.columns)
print(len(df.columns))
while len(df.columns) > 1: 
    df = df.drop(df.columns[len(df.columns)-1], axis=1, inplace=True)
print(df)

Output:

was
3
Traceback (most recent call last):
  File "C:\Users\Celius.Stingher\Desktop\PYTHON\soo.py", line 7, in <module>
    while len(df.columns) > 1:
AttributeError: 'NoneType' object has no attribute 'columns'

Could anyone please explain the source of the issue, because len(df.columns) is indeed resulting in 3, but using it in the while loop yields the error. Thanks a lot

3
  • 2
    Remove "inplace=True", because it returns None Commented Sep 2, 2019 at 17:20
  • 1
    @J.K: correct, but I'd rather remove the assignment instead of the inplace. Especially if the dataframe is large. Because removing it would cause unnecessary copy operations. Commented Sep 2, 2019 at 17:22
  • @jottbe, Yes remove the assignment will also solve the case Commented Sep 2, 2019 at 17:24

2 Answers 2

1

this is because you use inplace=True. If you use inplace=True, drop returns None and you assign that to the df-variable again.

So the following code should do, what you want:

import pandas as pd
import numpy as np
a = {'ear':[1,3,32,2],'aear':[53,4,3,22],'was':[23,3,2,4]}
df = pd.DataFrame(a)
print(df.columns)
print(len(df.columns))
while len(df.columns) > 1: 
    df.drop(df.columns[len(df.columns)-1], axis=1, inplace=True)
print(df)
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, it does work and thanks for the explination, will accept once the time is done.
1

Because once you drop all columns - the dataframe becomes None too :) After your code, before print(df) (last line):

>>> df
>>> type(df)
<class 'NoneType'>

3 Comments

That's not true. If you drop the last column, the dataframe still is a dataframe, but with no column. You can try that.
Well, it's functional dataframe - but it's somehow read as None i.e. you can add columns and make it work, but you cannot do everything as with the non-empty df.
Yes, that's right. An empty dataframe isn't much fun. But it's not read as None. df just contains None, because drop(inplace=True never returns anything else than None. No matter how many columns the dataframe contains. I guess it is the same philosopy as the sort method in listetc. They also return None to make clear, the receiver is stored and not a copy of it.

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.