9

Example: By using

df['Week_Number'] = df['Date'].dt.strftime('%U') 
for 29/12/2019 the week is 52. and this week is from 29/12/2019 to 04/01/2020.

but for 01/01/2020 the week is getting as 00.

I require the week for 01/01/2020 also as 52. and for 05/01/2020 to 11/01/2020 as 53. This need to be continued.

Suhas_mudam
  • 185
  • 3
  • 13
  • Can you give an example Series? – peer Dec 20 '19 at 12:30
  • `pd.to_datetime(pd.Series(['2019-12-29'])).dt.strftime('%U')` returns `52` for me and not `53`. It would be really helpful If you would provide code to reproduce your example. – peer Dec 20 '19 at 12:55
  • Whatever, your assumptions are wrong. 29/12/2019 is in week 52 and 01/01/2020 in week 1. There is no week 54 and no 53 in 2019... What you want to do? – Jean-Baptiste Yunès Dec 20 '19 at 13:00
  • Did you get a solution for the week 53 of 2019? – Jonathan Lam May 09 '20 at 09:53
  • @Jean-BaptisteYunès there is week 53 in 2019, depends which "convention" you are using.. 29,30,31 is week 53 and week 1 starts on the 1st of jan – Jonathan Lam May 09 '20 at 09:56
  • So if I understand the question (which could use some clarification) you want the number of weeks that have passed since a particular date/week? That is, *not* the week number. If so it seems like a duplicate of e.g. https://stackoverflow.com/questions/14191832/how-to-calculate-difference-between-two-dates-in-weeks-in-python – Magnus Persson Mar 24 '21 at 09:16

5 Answers5

1

I used a logic to solve the question.

First of all, let's write a function to create an instance of Dataframe involving dates from 2019-12-01 to 2020-01-31 by a function

def create_date_table(start='2019-12-01', end='2020-01-31'):
    df = pd.DataFrame({"Date": pd.date_range(start, end)})
    df["Week_start_from_Monday"] = df.Date.dt.isocalendar().week
    df['Week_start_from_Sunday'] = df['Date'].dt.strftime('%U')
    return df

Run the function and observe the Dataframe

date_df=create_date_table()
date_df.head(n=40)

enter image description here

There are two fields in the Dataframe about weeks, Week_start_from_Monday and Week_start_from_Sunday, the difference come from they count Monday or Sunday as the first day of a week.

In this case, Week_start_from_Sunday is the one we need to focus on.

Now we write a function to add a column containing weeks continuing from last year, not reset to 00 when we enter a new year.

def add_continued_week_field(date: Timestamp, df_start_date: str = '2019-12-01') -> int:
    start_date = datetime.strptime(df_start_date, '%Y-%m-%d')
    year_of_start_date = start_date.year
    year_of_date = date.year
    week_of_date = date.strftime("%U")
    year_diff = year_of_date - year_of_start_date
    if year_diff == 0:
        continued_week = int(week_of_date)
    else:
        continued_week = year_diff * 52 + int(week_of_date)
    return continued_week

Let's apply the function add_continued_week_field to the dates' Dataframe.

date_df['Week_continue'] = date_df['Date'].apply(add_continued_week_field)

We can see the new added field in the dates' Dataframe enter image description here

BoHuang
  • 109
  • 4
0

As stated in converting a pandas date to week number, you can use df['Date'].dt.week to get week numbers.

To let it continue you maybe could sum up the last week number with new week-values, something like this? I cannot test this right now...

if(df['Date'].dt.strftime('%U') == 53):
  last = df['Date'].dt.strftime('%U')

df['Week_Number'] = last + df['Date'].dt.strftime('%U')
Kjell
  • 432
  • 4
  • 11
  • 2
    This gives me only for a particular year but I need the week number to be continued even if the year changes. – Suhas_mudam Dec 20 '19 at 12:26
0

You can do this with isoweek and isoyear. I don't see how you arrive at the values you present with '%U' so I will assume that you want to map the week starting on Sunday 2019-12-29 ending on 2020-01-04 to 53, and that you want to map the following week to 54 and so on. For weeks to continue past the year you need isoweek.
isocalendar() provides a tuple with isoweek in the second element and a corresponding unique isoyear in the first element. But isoweek starts on Monday so we have to add one day so the Sunday is interpreted as Monday and counted to the right week. 2019 is subtracted to have years starting from 0, then every year is multiplied with 53 and the isoweek is added. Finally there is an offset of 1 so you arrive at 53.

In [0]: s=pd.Series(["29/12/2019", "01/01/2020", "05/01/2020", "11/01/2020"])                                    
        dts = pd.to_datetime(s,infer_datetime_format=True)                                                        
In [0]: (dts + pd.DateOffset(days=1)).apply(lambda x: (x.isocalendar()[0] -2019)*53 + x.isocalendar()[1] -1)                              
Out[0]: 
0    53
1    53
2    54
3    54
dtype: int64

This of course assumes that all iso years have 53 weeks which is not the case, so instead you would want to compute the number of iso weeks per iso year since 2019 and sum those up.

peer
  • 4,171
  • 8
  • 42
  • 73
0

Maybe you are looking for this. I fixed an epoch. If you have dates earlier than 2019, you can choose other epoch.

epoch= pd.Timestamp("2019-12-23")  

# Test data:
df=pd.DataFrame({"Date":pd.date_range("22/12/2019",freq="1D",periods=25)})   
df["Day_name"]=df.Date.dt.day_name()

# Calculation:
df["Week_Number"]=np.where(df.Date.astype("datetime64").le(epoch), \
                               df.Date.dt.week, \
                               df.Date.sub(epoch).dt.days//7+52)
    df                                                                                                                  

        Date   Day_name  Week_Number
0  2019-12-22     Sunday           51
1  2019-12-23     Monday           52
2  2019-12-24    Tuesday           52
3  2019-12-25  Wednesday           52
4  2019-12-26   Thursday           52
5  2019-12-27     Friday           52
6  2019-12-28   Saturday           52
7  2019-12-29     Sunday           52
8  2019-12-30     Monday           53
9  2019-12-31    Tuesday           53
10 2020-01-01  Wednesday           53
11 2020-01-02   Thursday           53
12 2020-01-03     Friday           53
13 2020-01-04   Saturday           53
14 2020-01-05     Sunday           53
15 2020-01-06     Monday           54
16 2020-01-07    Tuesday           54
17 2020-01-08  Wednesday           54
18 2020-01-09   Thursday           54
19 2020-01-10     Friday           54
20 2020-01-11   Saturday           54
21 2020-01-12     Sunday           54
22 2020-01-13     Monday           55
23 2020-01-14    Tuesday           55
24 2020-01-15  Wednesday           55
kantal
  • 2,331
  • 2
  • 8
  • 15
0

I got here wanting to know how to label consecutive weeks - I'm not sure if that's exactly what the question is asking but I think it might be. So here is what I came up with:

# Create dataframe with example dates
# It has a datetime index and a column with day of week (just to check that it's working)
dates = pd.date_range('2019-12-15','2020-01-10')
df = pd.DataFrame(dates.dayofweek,index=dates,columns=['dow'])

# Add column 
# THESE ARE THE RELEVANT LINES
woy = df.index.weekofyear
numbered = np.cumsum(np.diff(woy,prepend=woy[0])!=0)

# Append for easier comparison
df['week_num'] = numbered

df then looks like this:

            dow  week_num
2019-12-15    6         0
2019-12-16    0         1
2019-12-17    1         1
2019-12-18    2         1
2019-12-19    3         1
2019-12-20    4         1
2019-12-21    5         1
2019-12-22    6         1
2019-12-23    0         2
2019-12-24    1         2
2019-12-25    2         2
2019-12-26    3         2
2019-12-27    4         2
2019-12-28    5         2
2019-12-29    6         2
2019-12-30    0         3
2019-12-31    1         3
2020-01-01    2         3
2020-01-02    3         3
2020-01-03    4         3
2020-01-04    5         3
2020-01-05    6         3
2020-01-06    0         4
2020-01-07    1         4
2020-01-08    2         4
2020-01-09    3         4
2020-01-10    4         4
pasnik
  • 226
  • 1
  • 5