datetime.date(2010, 1, 1).isocalendar()[1]
gives week number 53 since 1st Jan 2010 was in a week which started in 2009. However, I would like to start Jan 1, 2010 as week 1. Is there any option in datetime isocalendar to do this?
If I follow the solution at How can I get the current week using Python?, I get 53 as result
Compute the number of days since the first of the year, integer-divide by 7 and add 1:
>>> import datetime as DT
>>> (DT.date(2010,1,1)-DT.date(2010,1,1)).days // 7 + 1
1
This notion of week number is very different from the ISO week definition, so you aren't going to find an option to do this in isocalendar.
If you're going to be getting data in total weeks since a point, you can mod that number by the number of weeks in a year (52) to get the remainder (ie, how many weeks into the year you are):
>>> 53 % 52
>>> 1
>>> 925 % 52
>>> 41
Related
This question already has answers here:
How to convert columns into one datetime column in pandas?
(8 answers)
Closed 1 year ago.
I'm using pandas and have 3 columns of data, containing a day, a month, and a year. I want to input my numbers into a loop so that I can create a new column in my dataframe that shows the week number. My data also starts from October 1, and I need this to be my first week.
I've tried using this code:
for (a,b,c) in zip(year, month, day):
print(datetime.date(a, b, c).strftime("%U"))
But this assumes that the first week is in January.
I'm also unsure how to assign what's in the loop to a new column. I was just printing what was in the for loop to test it out.
Thanks
I think this is what you want :
import pandas as pd
import datetime
# define a function to get the week number according to January
get_week_number = lambda y, m, d : int(datetime.date(y, m, d).strftime('%U'))
# get the week number for October 1st; the offset
offset = get_week_number(2021, 10, 1)
def compute_week_number(year, month, day):
"""
Function that computes the week number with an offset
October 1st becomes week number 1
"""
return get_week_number(year, month, day) - offset + 1
df = pd.DataFrame({'year':[2021, 2021, 2021],
'month':[10, 10, 10],
'day':[1, 6, 29]})
df['week_number'] = df.apply(lambda x: compute_week_number(x['year'],
x['month'],
x['day']),
axis=1)
apply with the use of axis=1 allows to call a function for each line of the dataframe to return the value of the new column we want to compute for this line.
I used % (modulo) to compute the new week number according to what you asked for.
Week 39 becomes week 1, week 40 becomes week 2 and so on.
This gives :
year
month
day
week_number
2021
10
1
1
2021
10
6
2
2021
10
29
5
If I have a column of dates filed like the below;
Date
2021-08-01
2021-08-02
2021-08-03
2021-08-01
2021-08-02
What I wish to do is add a new column that will tell me the number of mondays for example that the date is in the year.
so I can see that for the first record the first of August was a Sunday and it was the 31st Sunday of the year, whereas the 12th was a Thursday and was the 32nd Thursday of the year.
Date Number Of WeekDay in Year
2021-08-01 31
2021-08-02 31
2021-08-03 31
2021-08-12 32
... ...
If it makes it easier is there a way to do it using the python tool within Alteryx?
The answer by johnjps111 explains it all, but here's an implementation using python only (no alteryx):
import math
from datetime import datetime
def get_weekday_occurrences(date_string):
year_day = datetime.strptime(date_string, '%Y-%m-%d').timetuple().tm_yday
return math.ceil(year_day / 7)
Which can be used as follows:
get_weekday_occurrences('2021-08-12')
Note we use datetime.timetuple to get the day of the year (tm_yday).
For Alteryx, try the formula Ceil(DateTimeFormat([date],'%j') / 7) ... explanation: regardless of day of week, if it's the first day of the year, it's also the first "of that weekday" of the year... at day number 8, it becomes the 2nd "of that weekday" of the year, and so on. Since Alteryx gives you "day of the year" for free using the given DateTimeFornat function, it's then a simple division and Ceil() function.
To get the week in the year from a date string:
from datetime import datetime
a = '2021-08-02'
b = datetime.fromisoformat(a)
print('week of the year:', b.strftime('%W'))
output:
week of the year: 31
For more information about datetime: link
This question is related to Get date from week number, and is possibly a duplicate of the latter, however, I think what is suggested in the accepted answer to that question does not really work.
In [6]: datetime.datetime.strptime('2019-18-1', "%Y-%W-%w")
Out[6]: datetime.datetime(2019, 5, 6, 0, 0)
Notice how it returns Monday 2019-5-6. However, according to the calendar (I use http://whatweekisit.org for reference), 2019-5-6 the Monday of week 19.
Similarly, the example provided in the original question:
In [7]: datetime.datetime.strptime('2013-26-1', "%Y-%W-%w")
Out[7]: datetime.datetime(2013, 7, 1, 0, 0)
According to http://whatweekisit.org/calendar-2013.html 2013-7-1 is the Monday of week 27.
Also
In [8]: datetime.datetime.strptime('2019-18-1', "%Y-%W-%w").isocalendar()[1]
Out[8]: 19
Notice how I give week 18 to strptime, and get week 19 back from isocalendar.
I am completely lost and would very much appreciate if someone could explain what is going on here. My original goal though is to get week start date from week number.
Based off of my testing, datetime does not consider the first week of 2019 (i.e. Jan 1-Jan 6) as week 1 because it isn't a full week; December 31st, 2018 is part of the week but is not in 2019. I suppose you'll have to accomodate for that by checking the output of datetime.datetime.strptime('year-1-1', "%Y-%W-%w") == datetime.datetime.strptime('year-0-1', "%Y-%W-%w"). If false, subtract 1.
2018 is an example of a year where datetime does return the same value as isocalendar because the first Monday of the year is Jan 1.
From the isocalendar docs:
The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first (Gregorian) calendar week of a year containing a Thursday. This is called week number 1, and the ISO year of that Thursday is the same as its Gregorian year.
On the other hand, strptime starts from the first full week, in fact, since 2019 starts from Tuesday, they start from different weeks:
import datetime as dt
strp_first = dt.datetime.strptime('2019-1-1', "%Y-%W-%w")
>>> print(strp_first)
2019-01-07 00:00:00
>>> print(strp_first.isocalendar()[1])
2
While in 2021, which starts from Friday:
strp_first = dt.datetime.strptime('2021-1-1', "%Y-%W-%w")
>>> print(strp_first)
2021-01-04 00:00:00
>>> print(strp_first.isocalendar()[1])
1
Is there a workaround for the following
from datetime import datetime, timedelta
a = datetime.now() # <== 2016-03-09 11:06:04.824047
print a.strftime("%U")
>>> 10
#go back to previous Sunday
b = a - timedelta(days = 3)
print b.strftime("%U")
>>> 10
print b.weekday()
>>> 6
Shouldn't b.strftime("%U") be 9 as it the last day of the week?
%U treats weeks as starting on Sunday, not on Monday. From the documentation:
%U
Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0.
You could use the %W format, which gives a zero-padded week number based on Monday being the first day of the week:
%W
Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0.
The alternative is to use b.isocalendar()[1] if you need to get the week number as per ISO 8601. The rules for what is considered week 1 differ from the ISO calendar calculations; %W bases this on the first Monday in the year, while ISO 8601 states that the week that includes January 4 is the first week. For 2016 both systems align, but that's not the case in 2014, 2015 or 2019:
>>> d = datetime(2019, 3, 9)
>>> d.strftime('%W')
'09'
>>> d.isocalendar()[1]
10
If you wait until Python 3.6, you can use the %V format to include the ISO week number, see issue 12006.
By this I am getting current week number
datetime.date(2014, 9, 30).isocalendar()[1]
but I want to get what is next ISO week number and max ISO week number in current year in python.
I can't add current week number + 1 to get next week number, because it may be that year doesn't have that week number.
To get next week's week number, add a timedelta:
>>> import datetime
>>> today = datetime.date(2014, 9, 30)
>>> next_week = today + datetime.timedelta(days=7)
>>> next_week.isocalendar()[1]
41
To get the last week number in the year, note that the following rule is used:
The following years have 53 weeks:
years starting with Thursday
leap years starting with Wednesday