<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 timeseries
Working with timeseries in pandas is a fullfilling to work with time-based data.
This Cheatbook (Cheatsheet + Notebook) introduces you to the core functionality when working with pandas' time series / date functionality.
References
API Reference
Timestamp
Using just pandas' time data types is fun. Pandas provides intuitive ways for working with time data.
Single time objects
Let's create some Timestamps / point in time.
Step1:  You can put in some standard date formats. Pandas' will convert them accordingly.
Step2:  We can also create relative time information
Step3:  We can also do calculations with thos objects.
Step4:  Time series
We can work with a list of time-based data, too. Here we use pandas' date_range method to create such a list (with m for end of months).
Step5:  With this, we calculate with time in a similar way as above.
Step6:  DateTimeProperties object
Especially the DateTimeProperties object contains time related data as attributes or methods that we can use.
Step7:  Let's take a look the some of the properties.
Step8:  We can e.g. call the method day_name() on a date time series to get the name of the day for a date.
Step9:  Timestamp Series
Let's work with some real data (or at least a part of it). 
Example Scenario
The following dataset is an excerpt from a change log of a software. We want to take a look at which hour of the day the changes are made to the software.
First try
We can read in time-based datasets as any other dataset.
Step10:  Note, if we import a dataset like this, the time data will be of a simple object data type.
Step11:  So we have to convert that data first into a time-based data type with pandas' to_datetime() function.
Step12:  Next, we want to see at whick hour of the day most changes were done. We can use the same strategies to get more detailed information like in the previous examples.
Step13:  Let's simply count the number of changes per hour.
Step14:  And create a little bar chart.
Step15:  At the first glance, this looks pretty fine. But there is a problem
Step16:  Now we are able to apply the resample function on it with the information that we want to group our data hourly. We also have to decided what we want to do with the
Step17:  Display progressions
Step18:  Grouping time and data
So far, we did group only on time-based data. But what if we want, e.g., group the weekly changes by each developer? Let's do this!
Once again, we read in the dataset that we already know. We only let pandas parse the timestamp information.
Step19:  For this scenario, we also need some developers.
Step20:  Let's add some artificial ones to the changes and also mark each change with a separate column.
Step21:  OK, we want to group the changes per week per developer to find out the most active developer of the week (if this makes sense is up to you to find out ;-).
For this, we use groupby with a pandas Grouper. With the Grouper, we can say which column we want to group at which frequency (seconds, minutes, ... , years and so on). In our case
Step22:  This give as a Dataframe which lists the number of changes per week for each developers. We sort this list to get a kind of "most active developer per week list"
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
pd.Timestamp("today")
Explanation: timeseries
Working with timeseries in pandas is a fullfilling to work with time-based data.
This Cheatbook (Cheatsheet + Notebook) introduces you to the core functionality when working with pandas' time series / date functionality.
References
API Reference
Timestamp
Using just pandas' time data types is fun. Pandas provides intuitive ways for working with time data.
Single time objects
Let's create some Timestamps / point in time.
End of explanation
new_years_dinner = pd.Timestamp("2020-01-01 19:00")
new_years_dinner
Explanation: You can put in some standard date formats. Pandas' will convert them accordingly.
End of explanation
time_needed_to_sober_up = pd.Timedelta("1 day")
time_needed_to_sober_up
Explanation: We can also create relative time information
End of explanation
completely_sober = new_years_dinner + time_needed_to_sober_up
completely_sober
Explanation: We can also do calculations with thos objects.
End of explanation
dates = pd.DataFrame(
            pd.date_range("2020-03-01", periods=5, freq="m"),
            columns=["day"]
        )
dates
Explanation: Time series
We can work with a list of time-based data, too. Here we use pandas' date_range method to create such a list (with m for end of months).
End of explanation
dates["day_after_tomorrow"] = dates['day'] + pd.Timedelta("2 days")
dates
Explanation: With this, we calculate with time in a similar way as above.
End of explanation
dt_properties = dates['day'].dt
dt_properties
Explanation: DateTimeProperties object
Especially the DateTimeProperties object contains time related data as attributes or methods that we can use.
End of explanation
# this code is just for demonstration purposes and not needed in an analysis
[x for x in dir(dt_properties) if not x.startswith("_")]
Explanation: Let's take a look the some of the properties.
End of explanation
dt_properties.day_name()
Explanation: We can e.g. call the method day_name() on a date time series to get the name of the day for a date.
End of explanation
change_log = pd.read_csv("datasets/change_history.csv")
change_log.head()
Explanation: Timestamp Series
Let's work with some real data (or at least a part of it). 
Example Scenario
The following dataset is an excerpt from a change log of a software. We want to take a look at which hour of the day the changes are made to the software.
First try
We can read in time-based datasets as any other dataset.
End of explanation
change_log.info()
Explanation: Note, if we import a dataset like this, the time data will be of a simple object data type.
End of explanation
change_log['timestamp'] = pd.to_datetime(change_log['timestamp'])
change_log.info()
Explanation: So we have to convert that data first into a time-based data type with pandas' to_datetime() function.
End of explanation
change_log['hour'] = change_log['timestamp'].dt.hour
change_log.head()
Explanation: Next, we want to see at whick hour of the day most changes were done. We can use the same strategies to get more detailed information like in the previous examples.
End of explanation
changes_per_hour = change_log['hour'].value_counts(sort=False)
changes_per_hour.head()
Explanation: Let's simply count the number of changes per hour.
End of explanation
changes_per_hour.plot.bar();
Explanation: And create a little bar chart.
End of explanation
change_log = pd.read_csv("datasets/change_history.csv", parse_dates=[0], index_col=0)
change_log.head()
change_log['changes'] = 1
change_log.head()
Explanation: At the first glance, this looks pretty fine. But there is a problem: Missing data. E.g. at 3am and 5am, there weren't any changes.
We can handle this by using the more advanced resample functionality of pandas. This allows us to determine at which frequency we summarize time-based data.
Second try: resampling time
For this, we create a time series Dataframe from the dataset again. This time, we import the dataset by additionally using the parse_dates keyword and the number of the column that contains dates. This would lead to an converted date column from the beginning.
End of explanation
hourly_changes = change_log.resample("h").count()
hourly_changes.head()
hourly_changes['hour'] = hourly_changes.index.hour
hourly_changes.head()
changes_per_hour = hourly_changes.groupby("hour").sum()
changes_per_hour.head()
changes_per_hour.plot.bar();
Explanation: Now we are able to apply the resample function on it with the information that we want to group our data hourly. We also have to decided what we want to do with the
End of explanation
hourly_changes.head()
accumulated_changes = hourly_changes[['changes']].cumsum()
accumulated_changes.head()
accumulated_changes.plot();
Explanation: Display progressions
End of explanation
change_log = pd.read_csv("datasets/change_history.csv", parse_dates=[0])
change_log.head() 
Explanation: Grouping time and data
So far, we did group only on time-based data. But what if we want, e.g., group the weekly changes by each developer? Let's do this!
Once again, we read in the dataset that we already know. We only let pandas parse the timestamp information.
End of explanation
devs = pd.Series(["Alice", "Bob", "John", "Steve", "Yvonne"])
devs
Explanation: For this scenario, we also need some developers.
End of explanation
change_log['dev'] = devs.sample(len(change_log), replace=True).values
change_log['changes'] = 1
change_log.head()
Explanation: Let's add some artificial ones to the changes and also mark each change with a separate column.
End of explanation
weekly_changes_per_dev = \
    change_log.groupby([
        pd.Grouper(key='timestamp', freq='w'),
        'dev']) \
    .sum()
weekly_changes_per_dev.head()
Explanation: OK, we want to group the changes per week per developer to find out the most active developer of the week (if this makes sense is up to you to find out ;-).
For this, we use groupby with a pandas Grouper. With the Grouper, we can say which column we want to group at which frequency (seconds, minutes, ... , years and so on). In our case: weekly. Additionally, we want to track which developer did how many weekly changes. So we take developers also in the list with the relevant information that should be grouped and sum up the changes accordingly.
End of explanation
weekly_changes_per_dev.sort_values(
    by=['timestamp', 'changes'],
    ascending=[True, False])
Explanation: This give as a Dataframe which lists the number of changes per week for each developers. We sort this list to get a kind of "most active developer per week list":
End of explanation
<END_TASK>