Week of a month pandas

后端 未结 5 1540
孤街浪徒
孤街浪徒 2020-12-16 01:21

I\'m trying to get week on a month, some months might have four weeks some might have five. For each date i would like to know to which week does it belongs to. I\'m mostly

5条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-16 01:48

    TL;DR

    import pandas as pd
    
    def weekinmonth(dates):
        """Get week number in a month.
        
        Parameters: 
            dates (pd.Series): Series of dates.
        Returns: 
            pd.Series: Week number in a month.
        """
        firstday_in_month = dates - pd.to_timedelta(dates.dt.day - 1, unit='d')
        return (dates.dt.day-1 + firstday_in_month.dt.weekday) // 7 + 1
        
        
    df = pd.DataFrame(pd.date_range(' 1/ 1/ 2000', periods = 100, freq ='D'), columns=['Date'])
    weekinmonth(df['Date'])
    
    0     1
    1     1
    2     2
    3     2
    4     2
         ..
    95    2
    96    2
    97    2
    98    2
    99    2
    Name: Date, Length: 100, dtype: int64
    

    Explanation

    At first, calculate first day in month (from this answer: How floor a date to the first date of that month?):

    df = pd.DataFrame(pd.date_range(' 1/ 1/ 2000', periods = 100, freq ='D'), columns=['Date'])
    df['MonthFirstDay'] = df['Date'] - pd.to_timedelta(df['Date'].dt.day - 1, unit='d')
    df
    
             Date MonthFirstDay
    0  2000-01-01    2000-01-01
    1  2000-01-02    2000-01-01
    2  2000-01-03    2000-01-01
    3  2000-01-04    2000-01-01
    4  2000-01-05    2000-01-01
    ..        ...           ...
    95 2000-04-05    2000-04-01
    96 2000-04-06    2000-04-01
    97 2000-04-07    2000-04-01
    98 2000-04-08    2000-04-01
    99 2000-04-09    2000-04-01
    
    [100 rows x 2 columns]
    

    Obtain weekday from first day:

    df['FirstWeekday'] = df['MonthFirstDay'].dt.weekday
    df
    
             Date MonthFirstDay  FirstWeekday
    0  2000-01-01    2000-01-01             5
    1  2000-01-02    2000-01-01             5
    2  2000-01-03    2000-01-01             5
    3  2000-01-04    2000-01-01             5
    4  2000-01-05    2000-01-01             5
    ..        ...           ...           ...
    95 2000-04-05    2000-04-01             5
    96 2000-04-06    2000-04-01             5
    97 2000-04-07    2000-04-01             5
    98 2000-04-08    2000-04-01             5
    99 2000-04-09    2000-04-01             5
    
    [100 rows x 3 columns]
    

    Now I can calculate with modulo of weekdays to obtain the week number in a month:

    1. Get day of the month by df['Date'].dt.day and make sure that begins with 0 due to modulo calculation df['Date'].dt.day-1.
    2. Add weekday number to make sure which day of month starts + df['FirstWeekday']
    3. Be safe to use the integer division of 7 days in a week and add 1 to start week number in month from 1 // 7 + 1.

    Whole modulo calculation:

    df['WeekInMonth'] = (df['Date'].dt.day-1 + df['FirstWeekday']) // 7 + 1
    df
    
             Date MonthFirstDay  FirstWeekday  WeekInMonth
    0  2000-01-01    2000-01-01             5            1
    1  2000-01-02    2000-01-01             5            1
    2  2000-01-03    2000-01-01             5            2
    3  2000-01-04    2000-01-01             5            2
    4  2000-01-05    2000-01-01             5            2
    ..        ...           ...           ...          ...
    95 2000-04-05    2000-04-01             5            2
    96 2000-04-06    2000-04-01             5            2
    97 2000-04-07    2000-04-01             5            2
    98 2000-04-08    2000-04-01             5            2
    99 2000-04-09    2000-04-01             5            2
    
    [100 rows x 4 columns]
    

提交回复
热议问题