简体   繁体   中英

How to iterate over a list of dataframes in pandas?

I have multiple dataframes, on which I want to run this function which mainly drops unnecessary columns from the dataframe and returns a dataframe:

def dropunnamednancols(df):
    """
    Drop any columns staring with unnamed and NaN

    Args:
        df ([dataframe]): dataframe of which columns to be dropped
    """
    
    #first drop nan columns
    df = df.loc[:, df.columns.notnull()]
    #then search for columns with unnamed 
    df = df.loc[:, ~df.columns.str.contains('^Unnamed')]
    
    return df

Now I iterate over the list of dataframes: [df1, df2, df3]

dfsublist = [df1, df2, df3]
for index in enumerate(dfsublist):
    dfsublist[index] = dropunnamednancols(dfsublist[index])

Whereas the items of dfsublist have been changed, the original dataframes df1 , df2 , df3 still retain the unnecessary columns. How could I achieve this?

If I understand correctly you want to apply a function to multiple dataframes seperately.

The underlaying issue is that in your function you return a new dataframe and replace the stored dataframe in the list with a new own instead of modifying the old orignal one.

If you want to modify the orignal one you have to use the inplace=True parameters of the pandas functions. This is possible, but not recommended, as seen here .

Your code could therefore look like this:

def dropunnamednancols(df):
    """
    Drop any columns staring with unnamed and NaN

    Args:
        df ([dataframe]): dataframe of which columns to be dropped
    """

    cols = [col for col in df.columns if (col is None) | (col.startswith('Unnamed'))]
    df.drop(cols, axis=1, inplace=True)

As example on sample data:

import pandas as pd
df_1 = pd.DataFrame({'a':[0,1,2,3], 'Unnamed':[9,8,7,6]})
df_2 = pd.DataFrame({'Unnamed':[9,8,7,6], 'b':[0,1,2,3]})

lst_dfs = [df_1, df_2]

[dropunnamednancols(df) for df in lst_dfs]

# df_1 
# Out[55]: 
#    a
# 0  0
# 1  1
# 2  2
# 3  3
# df_2
# Out[56]: 
#    b
# 0  0
# 1  1
# 2  2
# 3  3

The reason is probably because your are using enumerate wrong. In your case, you just want the index, so what you should do is:

for index in range(len(dfsublist)):
    ...

Enumerate returns a tuple of an index and the actual value in your list. So in your code, the loop variable index will actually be asigned:

(0, df1) # First iteration
(1, df2) # Second iteration
(2, df3) # Third iteration

So either, you use enumerate correctly and unpack the tuple:

for index, df in enumerate(dfsublist):
    ...

or you get rid of it altogether because you access the values with the index either way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM