I need to get a 7 day calendar view from a pandas dataframe that contains a list of events. Below is just a sample of the dates.
DatetimeIndex(['2017-05-15', '2017-05-12', '2017-05-07', '2017-05-15',
'2017-05-17', '2017-05-17', '2017-05-07', '2017-05-01',
'2017-05-07', '2017-05-04', '2017-05-02', '2017-05-01',
'2017-05-06', '2017-05-15', '2017-05-13', '2017-05-06',
'2017-05-03', '2017-04-21', '2017-04-10', '2017-04-10',
'2017-04-18', '2017-03-13', '2017-04-13', '2017-05-04',
'2017-03-16', '2017-05-01', '2017-04-15', '2017-04-01',
'2017-04-01', '2017-04-01'],
dtype='datetime64[ns]', name=u'Date', freq=None)
I need to get the above dataframe to anx 7 matrix. Where n is the number of weeks. The columns are (Monday,Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday).
Since there are missing dates, I have got a list of all the possible date in between.
min_date = min(df['Date'])
max_date = max(df['Date'])
idx = pd.date_range(min_date, max_date)
DatetimeIndex(['2017-04-01', '2017-04-02', '2017-04-03', '2017-04-04',
'2017-04-05', '2017-04-06', '2017-04-07', '2017-04-08',
'2017-04-09', '2017-04-10', '2017-04-11', '2017-04-12',
'2017-04-13', '2017-04-14', '2017-04-15', '2017-04-16',
'2017-04-17', '2017-04-18', '2017-04-19', '2017-04-20',
'2017-04-21', '2017-04-22', '2017-04-23', '2017-04-24',
'2017-04-25', '2017-04-26', '2017-04-27', '2017-04-28',
'2017-04-29', '2017-04-30', '2017-05-01', '2017-05-02',
'2017-05-03', '2017-05-04', '2017-05-05', '2017-05-06',
'2017-05-07'],
dtype='datetime64[ns]', freq='D')
and then using the following line, I have got an indication as to which column the date will be in the actual matrix
week = idx.dayofweek
>> array([5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6,
0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6])
Is there a pythonic way of transforming idx into an nx 7 matrix? So that I can just check if a date in the original data frame is equal to the date at (i,j) then I can just fill the matrix.
If you modify your initial creation of idx
to ensure it starts on a Monday & ends on a Sunday by changing
idx = pd.date_range(min_date, max_date)
to
idx = pd.date_range(min_date-dt.timedelta(days=min_date.weekday()),
max_date+dt.timedelta(days=6-max_date.weekday()))
You could use np.reshape
to rearrange this into seven columns:
idx.values.reshape(len(idx)//7, 7)
Which you can convert back to a DataFrame if desired.
Using your example,
import datetime as dt
date = pd.DatetimeIndex(['2017-05-15', '2017-05-12', '2017-05-07', '2017-05-15',
'2017-05-17', '2017-05-17', '2017-05-07', '2017-05-01',
'2017-05-07', '2017-05-04', '2017-05-02', '2017-05-01',
'2017-05-06', '2017-05-15', '2017-05-13', '2017-05-06',
'2017-05-03', '2017-04-21', '2017-04-10', '2017-04-10',
'2017-04-18', '2017-03-13', '2017-04-13', '2017-05-04',
'2017-03-16', '2017-05-01', '2017-04-15', '2017-04-01',
'2017-04-01', '2017-04-01'],
dtype='datetime64[ns]', name=u'Date', freq=None)
min_date = min(date)
max_date = max(date)
idx = pd.date_range(min_date-dt.timedelta(days=min_date.weekday()),
max_date+dt.timedelta(days=6-max_date.weekday()))
pd.DataFrame(idx.values.reshape(len(idx)//7, 7), columns=idx[:7].strftime('%A'))
Out[222]:
Monday Tuesday Wednesday Thursday Friday Saturday Sunday
0 2017-03-13 2017-03-14 2017-03-15 2017-03-16 2017-03-17 2017-03-18 2017-03-19
1 2017-03-20 2017-03-21 2017-03-22 2017-03-23 2017-03-24 2017-03-25 2017-03-26
2 2017-03-27 2017-03-28 2017-03-29 2017-03-30 2017-03-31 2017-04-01 2017-04-02
3 2017-04-03 2017-04-04 2017-04-05 2017-04-06 2017-04-07 2017-04-08 2017-04-09
4 2017-04-10 2017-04-11 2017-04-12 2017-04-13 2017-04-14 2017-04-15 2017-04-16
5 2017-04-17 2017-04-18 2017-04-19 2017-04-20 2017-04-21 2017-04-22 2017-04-23
6 2017-04-24 2017-04-25 2017-04-26 2017-04-27 2017-04-28 2017-04-29 2017-04-30
7 2017-05-01 2017-05-02 2017-05-03 2017-05-04 2017-05-05 2017-05-06 2017-05-07
8 2017-05-08 2017-05-09 2017-05-10 2017-05-11 2017-05-12 2017-05-13 2017-05-14
9 2017-05-15 2017-05-16 2017-05-17 2017-05-18 2017-05-19 2017-05-20 2017-05-21
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.