Calculating week number of year (dealing with first week of year) - python

I am trying to convert the date into week number of year.
In my case, I cannot include the day of one year into another year.
The isocalendar() works fine to find week number, however, it assumes some rules: if the first week in January has less than 4 days, it is counted as the last week of the year before.
So, this function returns:
date(2016, 1, 1).isocalendar()[1]
53
Is there some way, using this function, to change this, to return week 0 instead of week 53 (from previous year) ?

how about this?
import datetime
datetime.date(2016, 1, 1).strftime("%U")

Related

Pandas pivot table function values into wrong rows

I'm making a pivot table from a CSV (cl_total_data.csv) file using pandas pd.pivot_table() and need find a fix to values in the wrong rows.
[Original CSV File]
The error occurs when the year has 53 weeks(i.e. 53 values) instead of 52, the first value in the year with 53 weeks is set as the last value in the pivot table
[Pivot Table with wrong values top]
[Pivot Table with wrong values bottom]
[Original CSV 2021 w/ 53 values]
The last value for the pivot table 2021 row 53 (1123544) is the first value of the year for 2021-01-01 (1123544) in the original CSV table for 2021.
I figured out how to fix this in the pivot table after making it. I use
Find columns with 53 values:
cl_total_p.columns[~cl_total_p.isnull().any()]
Then take the values from the original CSV files to its corresponding year and replace the values in the pivot table
cl_total_p[2021] = cl_total_data.loc['2021'].Quantity.values
My problem is:
I can't figure out what I'm coding wrong in the pivot table function that causes this misplacement of values. Is there a better way to code it?
Using my manual solution takes a lot of time especially when I'm using multiple CSV files 10+ and having to fix every single misplacement in columns with 53 weeks. Is there a for loop I can code to loop through all columns with 53 weeks and replace them with their corresponding year?
I tried
import numpy
import pandas
year_range = np.arange(1982,2023)
week_range = np.arange(54)
for i in year_range:
for y in week_range:
cl_total_p[i] = cl_total_data.loc['y'].Quantity.values
But I get an error :( How can I fix the pivot table value misplacement? and/or find a for loop to take the original values and replace them in the pivot table?
I can't figure out what I'm coding wrong in the pivot table function that causes this misplacement of values. Is there a better way to code it?
The problem here lies in the definition of the ISO week number. Let's look at this line of code:
cl_total_p = pd.pivot_table(cl_total_data, index = cl_total_data.index.isocalendar().week, columns = cl_total_data.index.year, values = 'Quantity')
This line uses the ISO week number to determine the row position, and the non-ISO year to determine the column position.
The ISO week number is defined as the number of weeks since the first week of the year with a majority of its days in that year. This means that it is possible for the first week of the year to not line up with the first day of the year. For that reason, the ISO week number is used alongside the ISO year number, which says that the part of the year before the first week belongs to the the previous year.
For that reason, January 1st, 2021 was not the first week of 2021 in the ISO system. It was the 53rd week of 2020. When you mix the ISO week with the non-ISO year, you get the result that it was the 53rd week of 2021, a date which is a year off.
Here's an example of how to show this with the linux program date:
$ date -d "Jan 1 2021" "+%G-%V"
2020-53
You have a few options:
Use both the ISO week and the ISO year for consistency. The isocalendar() function can provide both the ISO week and ISO year.
If you don't want the ISO system, you can come up with your own definition of "week" which avoids having the year's first day belong to the previous year. One approach you could take is to take the day of year, divide by seven, and round down. Unfortunately, this does mean that the week will start on a different day each year.

Python - How to get the date after entering a number between 1-365

How would you write a Python program that prompts a user for a year, a day of the year (an integer between 1 and either 365 or 366 to account for leap year), and gives the month, day and year?
You can use datetime.timedelta to add a number of days to a starting date. Use datetime.datetime to create the starting date with January 1st of the year.

Python: Date conversion to year-weeknumber, issue at switch of year

I am trying to convert a dataframe column with a date and timestamp to a year-weeknumber format, i.e., 01-05-2017 03:44 = 2017-1. This is pretty easy, however, I am stuck at dates that are in a new year, yet their weeknumber is still the last week of the previous year. The same thing that happens here.
I did the following:
df['WEEK_NUMBER'] = df.date.dt.year.astype(str).str.cat(df.date.dt.week.astype(str), sep='-')
Where df['date'] is a very large column with date and times, ranging over multiple years.
A date which gives a problem is for example:
Timestamp('2017-01-01 02:11:27')
The output for my code will be 2017-52, while it should be 2016-52. Since the data covers multiple years, and weeknumbers and their corresponding dates change every year, I cannot simply subtract a few days.
Does anybody have an idea of how to fix this? Thanks!
Replace df.date.dt.year by this:
(df.date.dt.year- ((df.date.dt.week>50) & (df.date.dt.month==1)))
Basically, it means that you will substract 1 to the year value if the week number is greater than 50 and the month is January.

Date counter in Python 3

I want to make a date counter, but I don't want to use datetime. I have made a list of the days of the month:
monthDays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
This way, if a month number is input, then I can search through the list for the same number and find the corresponding amount of days in that month e.g. monthDays[7] will find me 31.
The input of my date is of the form: dd/mm/yyyy, so I just use date[0:2] to extract the date ... and so on. First I check if the input date is in the future - fine.
Then I say, if the month is equal to today's month and the year is equal to today's year, then the difference is just the difference of the two day values.
I'm seriously a little bit stuck from here...
I've got, if today's month is less than or equal to the input month AND today's year is equal to the input year, then the elapsed days is the sum of:
the days left in the current month; and
the days between today's month and the input month
taken away from:
the difference of the two day values.
Can anybody help from here onwards? I want to be able to calculate the days elapsed between today and ANY date in the future.
If the date is after the current year, then you'll need to calculate the number of days left in this year, then, the number of days into the new year of the new date and any whole years inbetween.
Don't forget, monthDays[2] can be 28 or 29, depending on the year. Leap years are identified by years where:
The year is evenly divisible by 4;
If the year can be evenly divided by 100, it is NOT a leap year, unless;
The year is also evenly divisible by 400. Then it is a leap year.
(Source: http://www.timeanddate.com/date/leapyear.html)

Algorithm to get the current week number (not ISO)

I'm looking for an easy way to get the current week number of the year in Python. I'm well aware of the datetime.datetime.isocalendar() function in the standard library, but this function stipulates that week 1 is the first Monday of the new year. My dilemma is that I'm using Sunday as a starting point for each week, and if Sunday is for example December 27 and January 1st appears at some point during that week, I need to represent that week as week 1 (and year 2015).
I thought of doing something like (pseudocode):
if (Jan 1) - (current_sunday) < 7 days:
week_num = 1
And then storing that week number somewhere to iterate over next week. However, I feel that this is a very hackish method and would prefer something cleaner.
Generally to get the current week number (starts from Sunday):
>>> import datetime
>>> import calendar
>>> today = datetime.date.today())
>>> (int(today.strftime('%U')) + (datetime.date(today.year+1, 1, 1).weekday() != calendar.SUNDAY)) % 53
12
From the documentation of strftime('%U'):
"Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0."
Hence the modified code for your specific requirements. There isn't really a non-hacky way to do what you want.

Categories

Resources