Python Obtaining Week Number - python

I am trying to pass the week number (week_num) into a dataframe to analyze further my Kmeans output. Here is where I am struggling:
from datetime import date, timedelta, datetime
d1 = date(2013, 1, 1) # start date
d2 = date(2014, 12, 31) # end date
delta = d2 - d1 # timedelta
daysyear = []
day = []
month = []
year = []
#week_num = []
D = {0:'mon', 1:'tue', 2:'wed', 3:'thu', 4:'fri', 5:'sat', 6:'sun'}
for i in range(delta.days + 1):
daysyear.extend([D[(d1 + timedelta(days=i)).weekday()]+"-"+str(d1 + timedelta(days=i))])
day.extend([D[(d1 + timedelta(days=i)).weekday()]])
month.extend([(d1 + timedelta(days=i)).month])
year.extend([(d1 + timedelta(days=i)).year])
#week.extend([(d1 + timedelta(days=i))])
#week.extend(datetime.strptime([(d1 + timedelta(days=i)).year], "%Y-%W-%w").isocalendar()[1])
#week.pd.to_datetime([(d1 + timedelta(days=i))], errors ='coerce')
#yearnum, month_num, day_of_week = (d1 + timedelta(days=i))#.isocalendar()
Then passing into:
labels_2 = pd.DataFrame({'Date': daysyear, 'Cluster_ID': kmeans_2.labels_, 'Power_Usage': np.array(X).mean(axis=1), 'Day_of_Wk': day, 'Month_Num': month, 'Year': year})
Thank you for your help.
I have tried several methods and I am expecting the week number in numerical format to be passed into here
labels_2 = pd.DataFrame({'Date': daysyear, 'Cluster_ID': kmeans_2.labels_, 'Power_Usage': np.array(X).mean(axis=1), 'Day_of_Wk': day, 'Month_Num': month, 'Year': year, 'Week_Num: week_num'})

Related

Nested for loop to create list of urls

I am looking for a way to create a list of urls by modifying the name of the country and the date/time.
For each country, each day and each hour of the day I need to create a unique url.
import datetime
start_date = datetime.date(2019, 4, 4)
end_date = datetime.date(2019, 4, 5)
delta = datetime.timedelta(days=1)
list_of_urls = []
list_of_countries = ['france', 'germany', 'spain']
for country in list_of_countries:
while start_date <= end_date:
for hour in range(0, 24, 1):
base_url = 'https://thewebsite.com/'+ country +'/'+ start_date.strftime("%Y-%m-%d")
url = base_url + '/' + str(hour) + '/'
list_of_urls.append(url)
start_date += delta
print(list_of_urls)
It must be very basic but I don't understand why the for loop is applying only to the first country and not the three of them. When printing list_of_urls, only france appears (each day from 0 to 24hours)...
Any help would be greatly appreciated.
Thank you,
You need to reset the start date each time through the for loop. Here is the fixed script:
import datetime
start_date = datetime.date(2019, 4, 4)
end_date = datetime.date(2019, 4, 5)
delta = datetime.timedelta(days=1)
list_of_urls = []
list_of_countries = ['france', 'germany', 'spain']
for country in list_of_countries:
current_date = start_date
while current_date <= end_date:
for hour in range(0, 24, 1):
base_url = 'https://thewebsite.com/'+ country +'/'+ current_date.strftime("%Y-%m-%d")
url = base_url + '/' + str(hour) + '/'
list_of_urls.append(url)
current_date += delta
print(list_of_urls)

Python: Hours between two datetimes by day

I tried to develop a Python function that determines the difference between two datetime objects. I need an algorithm that calculates the number of hours per day. Is there a built-in function for this?
from datetime import datetime, timedelta, date
def getHoursByDay(dateA, dateB):
...
dateA = datetime.strptime('2018-09-01 09:00:00', '%Y-%m-%d %H:%M:%S')
dateB = datetime.strptime('2018-09-03 11:30:00', '%Y-%m-%d %H:%M:%S')
hours = getHoursByDay(dateA, dateB)
print hours
# {
# '2018-09-01': 15,
# '2018-09-02': 24,
# '2018-09-03': 11.5,
# }
There is no built-in function, though it is very simple to build one.
from datetime import datetime, timedelta, time
def deltaByDay(dateA, dateB):
dateAstart = datetime.combine(dateA, time())
dateBstart = datetime.combine(dateB, time())
result = {}
oneday = timedelta(1)
if dateAstart == dateBstart:
result[dateA.date()] = dateB - dateA
else:
nextDate = dateAstart + oneday
result[dateA.date()] = nextDate - dateA
while nextDate < dateBstart:
result[nextDate.date()] = oneday
nextDate += oneday
result[dateB.date()] = dateB - dateBstart
return result
def deltaToHours(delta, ndigits=None):
return delta.days * 24 + round(delta.seconds / 3600.0, ndigits)
dateA = datetime.strptime('2018-09-01 09:00:00', '%Y-%m-%d %H:%M:%S')
dateB = datetime.strptime('2018-09-03 11:30:00', '%Y-%m-%d %H:%M:%S')
deltas = deltaByDay(dateA, dateB);
output = {k.strftime('%Y-%m-%d'): deltaToHours(v, 1) for k, v in deltas.items()}
print(output)
# => {'2018-09-01': 15.0, '2018-09-02': 24.0, '2018-09-03': 11.5}
The built in timedelta functions would be able to get you the total days, and the remaining hours difference. If you want the output specifically in that dictionary format posted you would have to create it manually like this:
from datetime import datetime, time, timedelta
def getHoursByDay(dateA, dateB):
if dateA.strftime("%Y-%m-%d") == dateB.strftime("%Y-%m-%d"):
return {dateA.strftime("%Y-%m-%d"): abs(b-a).seconds / 3600}
result = {}
delta = dateB - dateA
tomorrow = dateA + timedelta(days=1)
day1 = datetime.combine(tomorrow, time.min) - dateA
result[dateA.strftime("%Y-%m-%d")] = day1.seconds / 3600
for day in range(1, delta.days):
result[(dateA + timedelta(days=day)).strftime("%Y-%m-%d")] = 24
priorday = dateB - timedelta(days1)
lastday = dateB - datetime.combine(priorday, time.min)
result[dateB.strftime("%Y-%m-%d")] = lastday.seconds / 3600
return result
Essentially this function calculates the first day and the last day values, then populates all the days in between with 24.
There is a kind of simple way to do this.
hours = (dateA - dateB).hours
I've used this to caclulate a difference in days.
https://docs.python.org/2/library/datetime.html#datetime.timedelta

How to roll start and end date in a month?

I want to write a function that looks ahead 1 year but can accept a certain month as the date to start counting from.
For example, if the start time is 1/1/2011, then the end time is 1/1/2012. The new start time would be 1/2/2011 and new end time would be 1/2/2012. The start and end times should advance like that.
Here is my attempt:
import datetime
from dateutil.relativedelta import relativedelta
from datetime import date
def Count(StartDate, EndDate,count):
#while StartDate < FinalDate:
count = 1
print (StartDate, EndDate)
StartDate = date(2011,01,01)
FinalDate = date (2014,01,01)
EndDate = StartDate + relativedelta(years=+1)
count = 1
a = Count(StartDate, EndDate,count)
print a
print something like
(datetime.date(2011, 2, 1), datetime.date(2012, 2, 1))
None
(datetime.date(2011, 3, 1), datetime.date(2012, 3, 1))
None
(datetime.date(2011, 4, 1), datetime.date(2012, 4, 1))
None
(datetime.date(2011, 5, 1), datetime.date(2012, 5, 1))
None
(datetime.date(2011, 6, 1), datetime.date(2012, 6, 1))
None
from dateutil.relativedelta import relativedelta
new_date = old_date + relativedelta(years=1)
#you can use this for getting the 1 year later date
#or use
#adding to date
from datetime import datetime, timedelta
new_date = datetime.today()
new_date = new_date + timedelta(months=1)
new_date = new_date + timedelta(years=1)
import datetime
from dateutil.relativedelta import relativedelta
from datetime import date
def Count(StartDate, EndDate,count):
#while StartDate < FinalDate:
count = 1
print (StartDate, EndDate)
StartDate = date(2011,01,01)
FinalDate = date (2014,01,01)
EndDate = StartDate + relativedelta(years=+1)
count = 1
while StartDate < FinalDate:
StartDate = StartDate + relativedelta(months=+1)
EndDate = StartDate + relativedelta(years=+1)
a = Count(StartDate, EndDate,count)
print a

How to account for weekends and holidays when using python

I am trying to format this data monthly, but by the current date of the month.
import pandas as pd
import datetime
import quandl
import numpy as np
start = datetime.datetime(1993, 10, 2)
end = datetime.date.today()
df = quandl.get("FRED/DGS20", collapse="daily").reset_index()
df.index=np.arange(0,len(df))
print (df)
l=[]
for i in range(0,len(df)):
if (df['DATE'].loc[i]).day == (df['DATE'].loc[len(df)-1]).day:
l.append(df['DATE'].loc[i])
The issue I am running in to is if that date is on a weekend or a holiday, it skips the month. How can I get python to choose the closest applicable day of the month if the given day is N/A?
A bit long but no for loops! insert my code after your df.index=np.arange(0,len(df)) line:
years = pd.DatetimeIndex(df['DATE']).year
years_u = np.unique(years)
years_u_norm = years_u - years_u[0]
months = pd.DatetimeIndex(df['DATE']).month
months_u = np.unique(months)
months_u_norm = months_u - months_u[0]
days = pd.DatetimeIndex(df['DATE']).day
days_u = np.unique(days)
days_u_norm = days_u - days_u[0]
shp = (years_u_norm[-1]+1, months_u_norm[-1]+1, days_u_norm[-1]+1)
mat = np.full(shp, np.nan).ravel()
y_ind = years - years_u[0]
m_ind = months - months_u[0]
d_ind = days - days_u[0]
inds = np.vstack([y_ind[np.newaxis], m_ind[np.newaxis], d_ind[np.newaxis]])
inds2 = np.ravel_multi_index(inds, shp)
inds_grid = np.indices(shp)[2].ravel()
mat[inds2] = inds_grid[inds2]
start_ind = np.ravel_multi_index([[start.year - years_u[0]], [start.month - months_u[0]], [start.day - days_u[0]]], shp)
mat[:start_ind] = np.inf
end_ind = np.ravel_multi_index([[end.year - years_u[0]], [end.month - months_u[0]], [end.day - days_u[0] + 1]], shp)
mat[end_ind:] = np.inf
mat = mat.reshape(shp)
dist = np.absolute(mat - np.full(shp, end.day-1))
min_dist = np.nanargmin(dist, axis=2) + 1
inds_f = np.unique(np.ravel_multi_index(inds[:-1, :], shp[:-1]))
res_inds = np.indices(min_dist.shape)
res_y = res_inds[0].ravel()[inds_f] + years_u[0]
res_m = res_inds[1].ravel()[inds_f] + months_u[0]
res_d = min_dist.ravel()[inds_f]
df = pd.DataFrame({'year': res_y,
'month': res_m,
'day': res_d})
print(df)

Get the last thursday of the current month using python

Following this answer I tried to get the date for last Thursday of the current month. But my code doesn't get out of loop.
from datetime import datetime
from dateutil.relativedelta import relativedelta, TH
todayte = datetime.today()
cmon = todayte.month
nthu = todayte
while nthu.month == cmon:
nthu += relativedelta(weekday=TH(1))
#print nthu.strftime('%d%b%Y').upper()
Looking at the documentation of relativedelta
Notice that if the calculated date is already Monday, for example, using (0, 1) or (0, -1) won’t change the day.
If nthu is already Thursday then adding TH(1) or TH(-1) won't have any effect but result in the same date and that's why your loop is running infinitely.
I will assume maximum 5 weeks in a month and do it like following:
todayte = datetime.today()
cmon = todayte.month
for i in range(1, 6):
t = todayte + relativedelta(weekday=TH(i))
if t.month != cmon:
# since t is exceeded we need last one which we can get by subtracting -2 since it is already a Thursday.
t = t + relativedelta(weekday=TH(-2))
break
Based on Adam Smith's answer on How can I get the 3rd Friday of a month in Python?, you can get the date of the last Thursday of the current month as follows:
import calendar
import datetime
def get_thursday(cal,year,month,thursday_number):
'''
For example, get_thursday(cal, 2017,8,0) returns (2017,8,3)
because the first thursday of August 2017 is 2017-08-03
'''
monthcal = cal.monthdatescalendar(year, month)
selected_thursday = [day for week in monthcal for day in week if \
day.weekday() == calendar.THURSDAY and \
day.month == month][thursday_number]
return selected_thursday
def main():
'''
Show the use of get_thursday()
'''
cal = calendar.Calendar(firstweekday=calendar.MONDAY)
today = datetime.datetime.today()
year = today.year
month = today.month
date = get_thursday(cal,year,month,-1) # -1 because we want the last Thursday
print('date: {0}'.format(date)) # date: 2017-08-31
if __name__ == "__main__":
main()
You should pass 2 to TH instead of 1, as 1 doesn't change anything. Modify your code to:
while (nthu + relativedelta(weekday=TH(2))).month == cmon:
nthu += relativedelta(weekday=TH(2))
print nthu.strftime('%d-%b-%Y').upper()
# prints 26-MAY-2016
Note that I modified the loop's condition in order to break in the last occurrence of the day on the month, otherwise it'll break in the next month (in this case, June).
from datetime import datetime , timedelta
todayte = datetime.today()
cmon = todayte.month
nthu = todayte
while todayte.month == cmon:
todayte += timedelta(days=1)
if todayte.weekday()==3: #this is Thursday
nthu = todayte
print nthu
You can also use calendar package.
Access the calendar in the form of monthcalendar. and notice that, the Friday is the last day of a week.
import calendar
import datetime
now = datetime.datetime.now()
last_sunday = max(week[-1] for week in calendar.monthcalendar(now.year,
now.month))
print('{}-{}-{:2}'.format(now.year, calendar.month_abbr[now.month],
last_sunday))
I think this will be fastest perhaps:
end_of_month = datetime.datetime.today() + relativedelta(day=31)
last_thursday = end_of_month + relativedelta(weekday=TH(-1))
This code can be used in python 3.x for finding last Thursday of current month.
import datetime
dt = datetime.datetime.today()
def lastThurs(dt):
currDate, currMth, currYr = dt, dt.month, dt.year
for i in range(31):
if currDate.month == currMth and currDate.year == currYr and currDate.weekday() == 3:
#print('dt:'+ str(currDate))
lastThuDate = currDate
currDate += datetime.timedelta(1)
return lastThuDate
You can do something like this:
import pandas as pd
from dateutil.relativedelta import relativedelta, TH
expiry_type = 0
today = pd.datetime.today()
expiry_dates = []
if expiry_type == 0:
# Weekly expiry
for i in range(1,13):
expiry_dates.append((today + relativedelta(weekday=TH(i))).date())
else:
# Monthly expiry
for i in range(1,13):
x = (today + relativedelta(weekday=TH(i))).date()
y = (today + relativedelta(weekday=TH(i+1))).date()
if x.month != y.month :
if x.day > y.day :
expiry_dates.append(x)
print(expiry_dates)
import datetime
def get_thursday(_month,_year):
for _i in range(1,32):
if _i > 9:
_dateStr = str(_i)
else:
_dateStr = '0' + str(_i)
_date = str(_year) + '-' + str(_month) + '-' + _dateStr
try:
a = datetime.datetime.strptime(_date, "%Y-%m-%d").strftime('%a')
except:
continue
if a == 'Thu':
_lastThurs = _date
return _lastThurs
x = get_thursday('05','2017')
print(x)
It is straightforward fast and easy to understand, we take the first of every month and then subtract it by 3 coz 3 is Thursday weekday number and then multiply it by either 4 and check if it is in the same month if it is then that is last Thursday otherwise we multiply it with 3 and we get our last Thursday
import datetime as dt
from datetime import timedelta
#start is the first of every month
start = dt.datetime.fromisoformat('2022-08-01')
if start.month == (start + timedelta((3 - start.weekday()) + 4*7)).month:
exp = start + timedelta((3 - start.weekday()) + 4*7)
else:
exp = start + timedelta((3 - start.weekday()) + 3*7)
You can use Calendar to achieve your result. I find it simple.
import calendar
import datetime
testdate= datetime.datetime.now()
weekly_thursday=[]
for week in calendar.monthcalendar(testdate.year,testdate.month):
if week[3] != 0:
weekly_thursday.append(week[3])
weekly_thursday
The list weekly_thursday will have all the Thursdays from the month.
weekly_thursday[-1] will give you the last Thursday of the month.
testdate : datetime.datetime(2022, 9, 9, 6, 35, 16, 752465)
weekly_thursday : [1, 8, 15, 22, 29]
weekly_thursday [-1]:29

Categories

Resources