Austin
Austin

Reputation: 7329

global variable and reference before assignment

I'm trying to create an empty global pandas dataframe and then append to it within data processing functions. I'm having trouble figuring out what's going wrong. Here's a minimal example:

from datetime import datetime
import pandas as pd

def do_stuff_and_append_df():
    dt = datetime.now()
    row = dict.fromkeys(df.columns.tolist())
    row['datetime'] = dt
    row['pduType'] = 'blah'
    df = df.append(row, ignore_index=True)
    print(df.head())

def main():
    # empty dataframe for appending
    header = ['datetime', 'pduType']
    global df 
    df = pd.DataFrame(columns=header)
    # Main loop
    try:
        while True:
            do_stuff_and_append_df()

    except KeyboardInterrupt:
        print('\nSaving and exiting.')
        df.to_csv('data.csv')

main()

I'm getting the error UnboundLocalError: local variable 'df' referenced before assignment. Anybody know why I can't call df within this function?

Upvotes: 0

Views: 1348

Answers (4)

C.Nivs
C.Nivs

Reputation: 13106

If you want a global var, put it explicitly in global scope:

from datetime import datetime
import pandas as pd

def do_stuff_and_append_df():
    dt = datetime.now()
    row = dict.fromkeys(df.columns.tolist())
    row['datetime'] = dt
    row['pduType'] = 'blah'
    df = df.append(row, ignore_index=True)
    print(df.head())

def main():
    # Main loop
    try:
        while True:
            do_stuff_and_append_df()

    except KeyboardInterrupt:
        print('\nSaving and exiting.')
        df.to_csv('data.csv')

if __name__ == "__main__":
    header = ['datetime', 'pduType']
    df = pd.DataFrame(columns=header)

Either that, or see chepner's answer. It's preferable that you don't use global vars

Upvotes: 0

Andy Chang
Andy Chang

Reputation: 79

try to add global declaration in do_stuff_and_append_df

def do_stuff_and_append_df():
    global df

Upvotes: 1

chepner
chepner

Reputation: 531460

Better yet, don't use a global variable. Pass the desired data frame as an argument.

from datetime import datetime
import pandas as pd

def do_stuff_and_append_df(df):
    dt = datetime.now()
    row = dict.fromkeys(df.columns.tolist())
    row['datetime'] = dt
    row['pduType'] = 'blah'
    df = df.append(row, ignore_index=True)
    print(df.head())
    return df

def main():
    # empty dataframe for appending
    header = ['datetime', 'pduType']
    df = pd.DataFrame(columns=header)
    # Main loop
    try:
        while True:
            df = do_stuff_and_append_df(df)

    except KeyboardInterrupt:
        print('\nSaving and exiting.')
        df.to_csv('data.csv')

main()

Upvotes: 1

vijay lingam
vijay lingam

Reputation: 46

You will have to declare "global df" under the function do_stuff_and_append_df() as well.

Because the function do_stuff_and_append_df() doesn't know whether you are referring the local variable or Global variable.

Upvotes: 3

Related Questions