Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python only reads my if statement, not elif and else

I am learning how to use for loops with if statements, can someone tell why python is only reading the if statement and not the elif statements.

mydf = [['house',7,5, np.nan],['block',30,25,19],['else',20, np.nan, np.nan]]

mydf= pd.DataFrame(mydf, columns=['Thing','height1','height2','height3'])

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I am trying to create a loop that will go each line and first check: if index in height3 is NOT NaN then put that value in bottomHeight. Else if index in height2 is NOT NaN then put that value in bottomHeight. Or else put NaN in bottomHeight.

#Create a new column of NaN’s

mydf["bottomHeight"]=(np.nan)*len(mydf)

for index in range(len(mydf)):
if mydf.loc[index,'height3'] != np.nan: 
    mydf.loc[index,'bottomHeight'] = mydf.loc[index, 'height3']
elif mydf.loc[index,'height2'] != np.nan: 
    mydf.loc[index,"bottomHeight"] = mydf.loc[index, 'height2']
else: 
    mydf.loc[np.nan,'bottomHeight'] = np.nan

The result should be bottomHeight = [5.0, 19.0, NaN], but it’s not. The result is [NaN, 19.0, NaN]. Like it’s only reading the first if statement.

>Solution :

You can avoid loops in pandas, because here exist vectorized alternatives – simpliest is Series.fillna:

mydf['bottomHeight'] = mydf['height3'].fillna(mydf['height2'])
print (mydf)
   Thing  height1  height2  height3  bottomHeight
0  house        7      5.0      NaN           5.0
1  block       30     25.0     19.0          19.0
2   else       20      NaN      NaN           NaN

Or forward non missing values per rows in selected columns by ffill(axis=1) and select last column by position:

mydf['bottomHeight'] = mydf[['height2','height3']].ffill(axis=1).iloc[:, -1]
print (mydf)

   Thing  height1  height2  height3  bottomHeight
0  house        7      5.0      NaN           5.0
1  block       30     25.0     19.0          19.0
2   else       20      NaN      NaN           NaN

Your solution is possible if use notna for test non missing values:

for index in range(len(mydf)):
    if pd.notna(mydf.loc[index,'height3']):
        mydf.loc[index,'bottomHeight'] = mydf.loc[index, 'height3']
    elif pd.notna(mydf.loc[index,'height2']): 
        mydf.loc[index,"bottomHeight"] = mydf.loc[index, 'height2']
    else: 
        mydf.loc[index,'bottomHeight'] = np.nan
        
print (mydf)
   Thing  height1  height2  height3  bottomHeight
0  house        7      5.0      NaN           5.0
1  block       30     25.0     19.0          19.0
2   else       20      NaN      NaN           NaN

If need processing all heigth columns:

mydf['bottomHeight'] = mydf.filter(like='height').ffill(axis=1).iloc[:, -1]
print (mydf)
   Thing  height1  height2  height3  bottomHeight
0  house        7      5.0      NaN           5.0
1  block       30     25.0     19.0          19.0
2   else       20      NaN      NaN          20.0
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading