3
\$\begingroup\$

The function serves two purposes as follows:

  1. When dealing with the day of the week, Python will always assign 0 to Sunday and 6 to Saturday and I want to change that. The first part of the code is changing the start of the week from Sunday to users preference, i.e. Monday or Tuesday.

  2. The second section is assigning the correct week number based on the new day of the week. For example, the new day of the week is Tuesday and the week assignment should be from Tuesday to Monday instead of Sunday to Saturday by default.

The code works (obviously), but I want to optimize it. The current code takes about 30 seconds for a dataset with over 2000 rows, which don't seem to be normal. The delay is mostly in the loop, I can't seem to optimize the loop because it's assigning week number based on a condition. The condition is simple, assign week number until it reaches a new merchant then the week resets.

def date_manipulate(df,startday):
    df['Month']=df.index.strftime("%B")
    df['DOW']=df.index.strftime("%A")
    week_offset = collections.OrderedDict()
    default_week =['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
    temp_week = default_week[startday:] + default_week[0:startday]
    for index, day in enumerate(temp_week):
        week_offset[day] = index
    df.replace({"DOW":week_offset},inplace=True)
    df=df.reset_index().sort_values(['merchant_name', 'date'],ascending=['True','True']).set_index(['date'])
    df['temp_date']=df.index.map(lambda x: x.toordinal())

    current_merchant=df['merchant_name'][0]
    offset=list(week_offset.values())[df['DOW'][0]]
    startdate=df['temp_date'][0]-(offset)
    enddate=startdate+6

    week=1
    df['week']=0
    df.reset_index(inplace=True)
    for counter, day in enumerate (df['temp_date']):
        if df['merchant_name'][counter]==current_merchant:
            if(df['temp_date'][counter])<=enddate:
                df.loc[counter,'week']=week
            else:
                enddate+=7
                week+=1
                df.loc[counter,'week']=week
        else:
            offset=list(week_offset.values())[df['DOW'][counter]]
            print(offset)
            current_merchant=df.loc[counter,'merchant_name']
            startdate=df.loc[counter,'temp_date']-(offset)
            enddate=startdate+6
            week=1
            df.loc[counter,'week']=week

    df.set_index('date',inplace=True)
    return df
\$\endgroup\$
  • \$\begingroup\$ can you add an example of input and expeced output? \$\endgroup\$ – juvian Mar 19 '18 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.