<jupyter_start><jupyter_text>**Datetime, NYC Film Permits, and PrettyPrint (PP)***as of: 13-Dec-2021* Attach Google Drive MyDocuments/data to /gdrive in Contents of ColabThe following files will be accessed using Google Drive from this notebook: *   avocado.csv*   family.csv*   Film_Permits_RuhRoh_03DEC2021.csv*   Film_Permits_03DEC2021.csvIn addition, the following file will be accessed using an internet URL in this notebook: *   http://bit.ly/uforeports<jupyter_code>from google.colab import drive
drive.mount('/content/gdrive')<jupyter_output><empty_output><jupyter_text>Import Pandas and Numpy libraries<jupyter_code>import pandas as pd
import numpy as np<jupyter_output><empty_output><jupyter_text>**Working with Dates and Times***using avocado.csv of price data as an example* One challenge in acquiring, scrubbing, and ETL (extract, translate, and load) of source date is the formatting of dates and times.This section references examples from: 1.   "DateTime in Pandas read_csv()" by <NAME> on medium.com -- https://bit.ly/333qcnF2.   Version 1 of "Avocado Prices: Historical data on avocado prices and sales volume in multiple US markets" by <NAME> on Kaggle -- https://www.kaggle.com/neuromusic/avocado-prices To begin, the file **avocados.csv** is uploaded and available in Google Drive at **content/gdrive/MyDrive/data/avocados.csv**The small file **family.csv** is also uploaded and available in Google Drive in the same folder.  This file is used later in this notebook.*See the google.colab import of drive() and the MyDrive mount to gdrive earlier* We should also import the Python datetime libary.To save typing, you could ```import datetime as dt```***For demonstration puroses in this notebook the datetime library is imported with its full name***<jupyter_code>import datetime<jupyter_output><empty_output><jupyter_text>As strings are represented as string objects, integers as Integer objects, floats as floating point objects in python, dates should be of type Datetime.<jupyter_code>print("The type of 5 is: ", type(5))
# <class 'int'>

print("The type of 'Nepal' is: ", type('Nepal'))
# <class 'str'>

print("The type of datetime.date(2051,7,14) is: ", type(datetime.date(2051,7,14)))
# <class 'datetime.date'><jupyter_output>The type of 5 is:  <class 'int'>
The type of 'Nepal' is:  <class 'str'>
The type of datetime.date(2051,7,14) is:  <class 'datetime.date'><jupyter_text>Reminder: the following libraries should be imported by now - *   pandas as pd*   numpy as np*   datetime Datetime objects are unique. For python to recognize an object as string, the value must be inside single/double quotes. For python to recognize Datetime objects, they must be created using **datetime.datetime() method**. Here is the link to the python documentation on datetime and basic date and time types:https://docs.python.org/3/library/datetime.htmlDatetime variables in Python cane be **aware** or **naive**.  The distinction is that **aware** datetime information is defined to include its relative time zone and can be used in conjunction with other **aware** datetime values whereas **naive** datetime information does not have its time zone defined and cannot be comingled with other datetime information from other time zones.The specific class of variable is supplied by the datetime module. This class can represent simple timezones (aware) or not (naive) and includes the following: *   **class datetime.date** - An idealized naive date, assuming the current Gregorian calendar always was, and always will be, in effect. Attributes: year, month, and day.*   **class datetime.time** - An idealized time, independent of any particular day, assuming that every day has exactly 24*60*60 seconds. (There is no notion of “leap seconds” here.) Attributes: hour, minute, second, microsecond, and tzinfo.*   **class datetime.datetime** - A combination of a date and a time. Attributes: year, month, day, hour, minute, second, microsecond, and tzinfo.*   **class datetime.timedelta** - A duration expressing the difference between two date, time, or datetime instances to microsecond resolution.*   **class datetime.tzinfo** - An abstract base class for time zone information objects. These are used by the datetime and time classes to provide a customizable notion of time adjustment (for example, to account for time zone and/or daylight saving time).*   **class datetime.timezone** - A class that implements the tzinfo abstract base class as a fixed offset from the UTC. Use the **.tzinfo** attribute of a datetime object to determine whether that object is **aware** or **naive**.1.   A datetime object **d** is **aware** if both of the following hold:```d.tzinfo is not Noned.tzinfo.utcoffset(d) does not return None```Otherwise, **d** is **naive**.2.   A time object **t** is aware if both of the following hold:```t.tzinfo is not Nonet.tzinfo.utcoffset(None) does not return None.```Otherwise, **t** is **naive**.The distinction between **aware** and **naive** doesn’t apply to **timedelta** objects. Working with dates and parsing them is one of the biggest challenges for programmers.Let's use an example to illustrate the point. We will be using the Avocado Prices dataset in a CSV file. You can download the data from the link presented earlier. Let's read the avocado.csv file to df_av with pd.read_csv()<jupyter_code>df_av = pd.read_csv('/content/gdrive/MyDrive/data/avocado.csv')<jupyter_output><empty_output><jupyter_text>Let's use head() to look at some of the file's contents<jupyter_code>df_av.head()<jupyter_output><empty_output><jupyter_text>... and have a look at the data type for each Variable (column) in the df_av DataFrame<jupyter_code>df_av.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 18249 entries, 0 to 18248
Data columns (total 14 columns):
 #   Column        Non-Null Count  Dtype  
---  ------        --------------  -----  
 0   Unnamed: 0    18249 non-null  int64  
 1   Date          18249 non-null  object 
 2   AveragePrice  18249 non-null  float64
 3   Total Volume  18249 non-null  float64
 4   4046          18249 non-null  float64
 5   4225          18249 non-null  float64
 6   4770          18249 non-null  float64
 7   Total Bags    18249 non-null  float64
 8   Small Bags    18249 non-null  float64
 9   Large Bags    18249 non-null  float64
 10  XLarge Bags   18249 non-null  float64
 11  type          18249 non-null  object 
 12  year          18249 non-null  int64  
 13  region        18249 non-null  object 
dtypes: float64(9), int64(2), object(3)
memory usage: 1.9+ MB<jupyter_text>**Parsing dates as datetime during read_csv()** We see the data type of the ‘Date’ column is not ‘DateTime’, but 'Object' which is the pandas equivalent of python’s String and is interchangeable with it in most cases.For python to treat an object as datetime object instead of str,int, float; the object should be created or parsed using **datetime.datetime()** or a **datetime parser**.By default, the date columns have been read as strings(objects) by the pandas **read_csv()** method and not as datetime objects.  We want pandas to read columns with dates not as strings(objects) but as datetime objects.We can achive this by parsing the dates as datetime at the time of reading the data.Set **parse_dateparameter** of **read_csv()** to the label/index of the column you want to parse(convert string date into datetime object).Only booleans, lists, and dictionaries are accepted for the 'parse_dates' parameter.```parse_date = ['Date'] or parse_date = [1]```<jupyter_code>df_av_parsed = pd.read_csv('/content/gdrive/MyDrive/data/avocado.csv', parse_dates=['Date'])<jupyter_output><empty_output><jupyter_text>Let's have a looked at our new DataFrame **df_av_parsed** with parsed '**Date**' variable (column)<jupyter_code>df_av_parsed.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 18249 entries, 0 to 18248
Data columns (total 14 columns):
 #   Column        Non-Null Count  Dtype         
---  ------        --------------  -----         
 0   Unnamed: 0    18249 non-null  int64         
 1   Date          18249 non-null  datetime64[ns]
 2   AveragePrice  18249 non-null  float64       
 3   Total Volume  18249 non-null  float64       
 4   4046          18249 non-null  float64       
 5   4225          18249 non-null  float64       
 6   4770          18249 non-null  float64       
 7   Total Bags    18249 non-null  float64       
 8   Small Bags    18249 non-null  float64       
 9   Large Bags    18249 non-null  float64       
 10  XLarge Bags   18249 non-null  float64       
 11  type          18249 non-null  object        
 12  year          18249 non-null  int64         
 13  region        18249 non-null  object        
dtypes: datetime64[ns](1), float64(9), int64(2), object(2)
memory usage: 1.9+ MB<jupyter_text>We can check the type of an element in the new DataFrame **df_av_parsed** for the variable '**Date**'<jupyter_code>type(df_av_parsed['Date'][0])<jupyter_output><empty_output><jupyter_text>**Timestamp** is the Pandas equivalent of python’s **Datetime** and is interchangeable with it in most cases.The benefits of using a datetime object instead of String objects include:*   chronological ordering of dates/times*   calculating differential time*   dealing with time zones*   daylight saving time*   accomodating different written date formats*   other date-specific logic  **Converting String Dates to Datetime Objects in a Pandas DataFrame** Pandas has a built-in function called **to_datetime(**) that can be used to convert strings to datetime object.```df['Date] = pd.to_datetime(df['Date'])```<jupyter_code>df_av.info()
df_av['Date'] = pd.to_datetime(df_av['Date'])<jupyter_output><empty_output><jupyter_text>Let's look at our original DataFrame df_av which had read in the 'Date' column as a String(Object).<jupyter_code>df_av.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 18249 entries, 0 to 18248
Data columns (total 14 columns):
 #   Column        Non-Null Count  Dtype         
---  ------        --------------  -----         
 0   Unnamed: 0    18249 non-null  int64         
 1   Date          18249 non-null  datetime64[ns]
 2   AveragePrice  18249 non-null  float64       
 3   Total Volume  18249 non-null  float64       
 4   4046          18249 non-null  float64       
 5   4225          18249 non-null  float64       
 6   4770          18249 non-null  float64       
 7   Total Bags    18249 non-null  float64       
 8   Small Bags    18249 non-null  float64       
 9   Large Bags    18249 non-null  float64       
 10  XLarge Bags   18249 non-null  float64       
 11  type          18249 non-null  object        
 12  year          18249 non-null  int64         
 13  region        18249 non-null  object        
dtypes: datetime64[ns](1), float64(9), int64(2), object(2)
memory usage: 1.9+ MB<jupyter_text>We can look at some of the values...<jupyter_code>selection = df_av.iloc[:10,1]
print("The first ten rows of the parsed Date value: \n",selection)<jupyter_output>The first ten rows of the parsed Date value: 
 0   2015-12-27
1   2015-12-20
2   2015-12-13
3   2015-12-06
4   2015-11-29
5   2015-11-22
6   2015-11-15
7   2015-11-08
8   2015-11-01
9   2015-10-25
Name: Date, dtype: datetime64[ns]<jupyter_text>... or ...<jupyter_code>selection = df_av['Date']
print(selection[:10])<jupyter_output>0   2015-12-27
1   2015-12-20
2   2015-12-13
3   2015-12-06
4   2015-11-29
5   2015-11-22
6   2015-11-15
7   2015-11-08
8   2015-11-01
9   2015-10-25
Name: Date, dtype: datetime64[ns]<jupyter_text>**Custom Date Formats** Sometimes, dates might be in a custom format, for example, YYYY-DD-MM HH:MM:SS.<jupyter_code>df_x = pd.DataFrame({'Date':['1994-10-31 12:30:00', '1995-11-23 15:30:00', '2004-1-1 00:30:00'], 'name':['psg','aw','prw']})
df_x
df_x.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   Date    3 non-null      object
 1   name    3 non-null      object
dtypes: object(2)
memory usage: 176.0+ bytes<jupyter_text>Pandas **to_datetime()** has a parameter called **format** that allows you to pass a custom format as the argument:<jupyter_code>df_x['Date'] = pd.to_datetime(df_x['Date'], format='%Y-%m-%d  %H:%M:%S')
df_x.info()
df_x.head()<jupyter_output><empty_output><jupyter_text>**Sourcing Date Components from Separate Variables** What if year, month and day are in separate columns? Can we assemble them into a single column as datetime objects?Set the **parameterparse_date** to a dictionary in the **read_csv()** method.The **key** in the dictionay should be the name of the column and the **value** should be a list with the index of the columns you want to combine.This will collapse the existing columns into the newly defined timedate object.  That means there will not be columns in the resultant DataFrame for the variables which were included as part of the value in the dictionary used to creat the parsed datetime variable.<jupyter_code>df_fam = pd.read_csv('/content/gdrive/MyDrive/data/family.csv', parse_dates={'date_of_birth':[0,1,2]},)
df_fam.info()
df_fam<jupyter_output><empty_output><jupyter_text>As mentioned above, the syntax used did not create columns in the resultant DataFrame for the variables which were included as part of the value in the dictionary used to creat the parsed datetime variable.  If you want to keep the existing columns then set:`keep_date_col = True`<jupyter_code>df_fam = pd.read_csv('/content/gdrive/MyDrive/data/family.csv', parse_dates={'date_of_birth':[0,1,2]}, keep_date_col=True)
df_fam.info()
df_fam<jupyter_output><empty_output><jupyter_text>**parse_dates** accepts the following types of arguments: bool or list of int or names or list of lists or dict.  The default argument is the Boolean False.The behavior of **parse_dates** arguments: *   boolean. If True -> try parsing the index.*   list of int or names. e.g. If [1, 2, 3] -> try parsing columns 1, 2, 3 each as a separate date column.*   list of lists. e.g. If [[1, 3]] -> combine columns 1 and 3 and parse as a single date column.*   dict, e.g. {‘foo’ : [1, 3]} -> parse columns 1, 3 as date and call result ‘foo’  **Assembling a Datetime from Columns Already in a DataFrame** We can use the pd.to_datetime() method to assemble a datetime in a single column (varible)  and convert them to datetime object.  By default, the existing columns will not be collapsed and will remain there.<jupyter_code>df_fam2 = pd.read_csv('/content/gdrive/MyDrive/data/family.csv')
df_fam2
df_fam2.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   year    3 non-null      int64 
 1   month   3 non-null      int64 
 2   day     3 non-null      int64 
 3   name    3 non-null      object
dtypes: int64(3), object(1)
memory usage: 224.0+ bytes<jupyter_text>Let's create a new datetime variable called 'Date'<jupyter_code>df_fam2['Date'] = pd.to_datetime(df_fam2[['year','month','day']])
df_fam2.info()
df_fam2<jupyter_output><empty_output><jupyter_text>---  **The Concept of Time Zones in Python**A time zone represents the standardized time depending on which part of the world is being considered.In simple terms, timezone refers to the local time of a region. UTC (Coordinated Universal Time) is the astronomical time based on earth’s rotation, is the standard against which the world’s region-based time is coordinated.*Note: UTC – Coordinated Universal Time is the common time standard across the world. So, in Python, to work with the timezone without any issues, it is recommended to use the UTC as your base timezone*For example, CT(Central Time) in North and South America is either 5 or 6 hours behind and represented as UTC-5 or UTC-6 based on the Day Light Saving. The following illustration shows a few examples. ![TimeZoneExamples.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDkAAAH7CAIAAABJ9NNbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAIeYSURBVHhe7d0PnFPlnej/<KEY>jFoyjnVSuCXtKFlQolKiUwjSkmGVGdhlRu+FXLYQWDXqhUCXV+C1MmMvTGjLhBYIFhqKNIo06NjQFRMVJ7RI2uJkV0q6UlPL9rgd7u+c5OTPJBnmPxzg82ZeM+ecHE7O3+d5vuc8z3M+cf78eQEAAAAAVOZvlL8AAAAAoCbEKgAAAADUiFgFAAAAgBoRqwAAAABQI2IVAAAAAGpErAIAAABAjYhVAAAAAKgRsQoAAAA<KEY>AAAA<KEY>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) Python provides the **datetime.tzinfo** abstract base class which provides methods to handle timezone. But this class is an abstract base class and should not be instantiated directly. We need to define a subclass of tzinfo to capture information about a particular time zone.The **pytz** library has implemented a timezone class for handling arbitrary fixed offsets from UTC and timezones. This library allows accurate and cross-platform timezone calculations and also solves the issue of ambiguous times at the end of daylight saving time.**pytz** is a concrete implementation of the abstract base class **tzinfo** and is used to create timezone-aware datetime objects.For example, The **datetime.now()** function returns the current local date-time without any timezone information. Using the **pytz** library, we can pass the timezone name to this function to get the current datetime in the given timezone.We can use the following attributes and methods of the pytz module to work with timezone in Python.*   **pytz.utc** - Get the standard UTC timezone*   **pytz.timezone('region')** - Create the timezone object of a particular region*   **pytz.astimezone()** - Convert the time of a particular time zone into another time zone **Create Timezone Aware Datetime Object**In Python, a date object can be mentioned with (aware) or without (naive) timezones. Based on that, an object is known as Naive or Aware. A date object, by default, is naive. A datetime or time object is aware if it holds the timezone(tz) value.Follow the below steps to create a timezone aware Datetime Object in Python: –1.   Install **pytz** module if not installed using the pip install pytz command.```pip install pytz``` ```import pytz```2.   Use the **pytz.timezone('region_name')** function to create the timezone object3.   Use the **datetime.now(timezone_obj)** or **datetime.datetime('timezone')** function to create the timezone aware current datetime. ![TimeZoneAwareDiagram.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABC0AAAIBCAIAAADiUNIrAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAP+lSURBVHhe7J0FgBzV/cfv1n333F1zF3d3SAgSCO5QCrT/Uhdoy79Q+7el3iJtseIQiBB3z13uknN3lz3Z3Vv3/X9HsrkYJMgR+X0y2Zt58+bNk5k3v+88mVC/3x9CEARBEARBEAQxhgj4vwRBEARBEARBEGMF6RCCIAiCIAiCIMYa0iEEQRAEQRAEQYw1pEMIgiAIgiAIghhrSIcQBEEQBEEQBDHWkA4hCIIgCIIgCGKsIR1CEARBEARBEMRYQzqEIAiCIAiCIIixhnQIQRAEQRAEQRBjDekQgiAIgiAIgiDGGtIhBEEQBEEQBEGMNaRDCIIgCIIgCIIYa0iHEARBEARBEAQx1pAOIQiCIAiCIAhirAn1+/386mfF11fPrxEEQRAEQRAEcUUjjMvl1z4f1B5CEARBEARBEMRYQzqEIAiCIAiCIIixhnQIQRAEQRAEQRBjDekQgiAIgiAIgiDGGtIhBEEQBEEQBEGMNaRDCIIgCIIgCIIYa0iHEARBEARBEAQx1pAOIQiCIAiCIAhirCEdQhAEQRAEQRDEWEM6hCAIgiAIgiCIsYZ0CEEQBEEQBEEQYw3pEIIgCIIgCIIgxhrSIQRBEARBEARBjDWkQwiCIAiCIAiCGGtIhxAEQRAEQRAEMdaQDiEIgiAIgiAIYqwhHUIQBEEQBEEQxFhDOoQgCIIgCIIgiLGGdAhBEARBEARBEGMN6RCCIAiCIAiCIMYa0iEEQRAEQRAEQYw1pEMIgiAIgiAIghhrSIcQBEEQBEEQBDHWkA4hCIIgCIIgCGKsIR1CEARBEARBEMRYQzqEIAiCIAiCIIixhnQIQRAEQRAEQRBjDekQgiAIgiAIgiDGGtIhBEEQBEEQBEGMNaRDCIIgCIIgCIIYa0iHEARBEARBEAQx1pAOIQiCIAiCIAhirCEdQhAEQRAEQRDEWEM6hCAIgiAIgiCIsYZ0CEEQBEEQBEEQYw3pEIIgCIIgCIIgxhrSIQRBEARBEARBjDWkQwiCIAiCIAiCGGtC/X4/v/pZ8fXV82vE58Dr9Ta1dbz42jt5OVnffOhu3jUkpKu3/3DRiY3bdv/u5z/MSE3mXS9Dho2mYyfK//D8y8FLTiQSRkWE/+8PvjUxL4dz+QQCgcDbH23SDw1PyM1asWQB73p+jKaRDz7eVlpZ88uffAdnEYlE3X39+48c+89ba3/z1PemTx6vVCg4nwRBEARBEMSFI4zL5dc+H9QecqngDwRsNkdtU0tXTy/vxOJ0ufr0gxU19XaHk3e6PPF4vAPDhuKyyjnTp9x9yw1Yrl++GJrkhdfe/njHXovVyvs7D9AhvfqB9s7uIYORd/pEcLqunr6ahmaXy428hYtaqYTGu/uW65PiY8UiMeeNIAiCIAiC+EoQPvPMM/zqZyVgHeLXiM+Bz+/XDw7vOVSQGBezbOFc3jUkxGAaaWhpK6movmP1qpioCFjhtY0txhFzeXVdSWUNfpta2zVqlUwqEQqF8O/2ePYfLTpeXlVRU9fc1mGz23VarVgswvqR4lKdViOVwKegu7f/SHGJ0+VWKuQSidhitTW2tNc3tWATS//A0Mc79lTVNWDpHxgUCARhWg0CHzaaWto765paBgaHi0or+geHxCKRXCZtbu8sPFF2orwK/huaWyPDwxAfHMWmgMdqsyMOW3cfeO4XP15z/bUzp0ycMC4bETtSVGI0jURGhCcnxsPbiMUC0XWwoJg7eyAkoFIoHC5nwfGy3YeOdnb32uwOSDKrzaZVq5GWju7erbv3c557+vUBfyBMp0GmHT52ApnZ2dOrUSmb2zolYrFapYSYGTKY8nOzsI40llfX+nz+guOlx8srcTiSlpqUAKlzvKwKqUMyVUqFTCYViUSIGI49UV4NHVVaWVPT0NTa0RkVEa6Qy9jEEQRBEARBXC0I1JH82ueDdMilwgXqkMraxrc/+rimvnnbngM7DxzZuf8IDO6YqKiEuGjY1k6Xq7Wj+88vvbpl1/59R44dO1HR3t07aXyuVqPesnv/7//x7/G5WTFRkRAP0Cq/+vPzLpcrKz0tXKdt7+x5b+PW3YcKcjLSYPcfOnb8F3/4+9HjZQgE5nhIaMjUCXnQFXWNLR/v3Pv+xq29+oEN23ZDFEWE6+Qy2dsffgzHnfsPHzhafOjYifSUpJjoSOgZPg0sQR3y0F1rEuNj4SKVSiBFICpqGpuRzCXzZnl9vrKquvc3bnvzw42Hj5Vs3XMgNDQ0Pjba7/f/+833DxeVtHV2t3Z0IUp+f2BcVjr8I11P//5vx8sqIatqG5q9Xm9eTlZPn/7199YdKChGsPXNbYUl5ckJcdBgR4tLv/6Dn9983fLEuFgoihdef8dssb714cfb9hzcc7hw7+HCmVMnHio8/tHmHeu27ERuREeEJ8TFIvc8Ho9+aPjvL78J971HCqGdkO0T83JioyPFYmpaIQiCIAjiKuKL0iHUL+vyA7b1f956f+mCOe+8+OcP/vO31SuX/euNdxtb27Grvqn1t3998e5bblj/2vO71/73e489uGH77uNlVQajKToyIjMtpbq+yeZwjJgtppERl8tdXlNvZjtEmcxmaIzczPQwrQYCY/3WXRtef/7wpnfXvvz3vOzM99Zv6e0fgC0On4NDhrrG5ujI8Ff+8ts///Ip6JZtew/96833v/31+wu3rt389r+//ch9/3z17dLKWiauF0BGajJCbmxpg9jQDwy+uXZDUkIcgjq08Z2ffudxSAvIm9SkhL/+6mcP3H7zmlXXPPPDJ3a+/9pT33kMYubNtRs379r35Lcf3b/hLRyyculCKI2jxSXw/+snv/vA7avzszORFYc/fue+21ZDh/CnPMngsPG3f3vpvttu2rX29f/86dcQJ7d+7dvIom8/cv/615+//7bV76zbXF3XCJ89/QN/fvG1gcHhn3z7UZxo3WvPz5s5DWIPecsFRRAEQRAEQVwUpEMuP1QKxbIFc2ZPm5ySFJ+SGI+V/oEhu50ZPQKbHgb6gtnT42NjYqIiU5MTIsJ00BgOpzM5IW7qhPzy6jqbza4fHA6EhM6bNU0/MOR0MgcaTebq+sbpk/IjI8KvXTL/qe88np6SDE2SnZGWEBdjdzhgsnu8PviUyaRpyYm333RdSlKCXCYbNBiPl1dCC2WlpahVSpxl8bxZQwZDfVNL/8AgE91PI1ynRTg+v18gEODs33vsoTtvug5BaTWq8bnZXp9v2GjCLrlMKpGIASLAdJeSSju6exuaW7Fy6/UrIsPDcEhedkZSfOyeQ4Uutxvu8C4UCpUKuUqlxLGhofwZg2jVqjtWr5o2KT82OjIuJmrqxPxxWenXLV04bfJ4aJKFs6dDv1ltdvhEHDZs2zVn+uQJudk4UUxUxPIFc6HiOPlHEARBEARBXCykQy4/RCJRXEx0eJgWhjmM7TCdxu3xjFgsEBswvmHWv/beumf/+I9nnvv7a++tdzicLpfb5/NHRYRDlpyoqLbY7L36AbjPmDQ+KSGut3+goaVtYHhYJBJCxqiVSugcs8X667+88PTv/vrbv76493ChPxCAZR9gR3uLhEKVUpkUHwddgE2n04UQmts6Xvrvez//<KEY>//<KEY>//<KEY>FRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqDGHEBERERFRqCkCgYBcS0REREREFBI8H0JERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKHGHEJERERERKEVFvb/0j7OZYMiYfMAAAAASUVORK5CYII=)<jupyter_code># from datetime import datetime - if you want to save typing
# import datetime as dt - another way to save typing
import datetime
import pytz

# current local Datetime unaware
unaware = datetime.datetime.now()
print('Local - Timezone naive:\t', unaware)

# Standard UTC timezone aware Datetime
aware = datetime.datetime.now(pytz.utc)
print('UTC - Timezone aware:\t', aware)

# US/Central timezone datetime
aware_us_central = datetime.datetime.now(pytz.timezone('US/Central'))
print('US Central - Timezone DateTime\t', aware_us_central)

# US/Eastern timezone datetime
aware_us_eastern = datetime.datetime.now(pytz.timezone('US/Eastern'))
print('US Eastern - Timezone DateTime\t', aware_us_eastern)<jupyter_output>Local - Timezone naive:	 2021-12-06 18:09:01.617220
UTC - Timezone aware:	 2021-12-06 18:09:01.619198+00:00
US Central - Timezone DateTime	 2021-12-06 12:09:01.649253-06:00
US Eastern - Timezone DateTime	 2021-12-06 13:09:01.651660-05:00<jupyter_text>Let's use the **dir()** function to look at each variable...<jupyter_code># Current local unaware Datetime tzinfo
print('\nLocal - Timezone Naive unaware.tzinfo:\n', unaware.tzinfo)

# Standard UTC aware Datetime tzinfo
print('\n\nUTC - Timezone Aware aware.tzinfo:\n', aware.tzinfo)

# US/Central timezone aware datetime tzinfo
print('\n\nUS Central DateTime Aware aware_us_central.tzinfo:\n', aware_us_central.tzinfo)

# US/Eastern timezone aware datetime tzinfo
print('\n\nUS Eastern DateTime Aware aware_us_eastern.tzinfo:\n', aware_us_eastern.tzinfo)

# Rules for aware datetime:
# d.tzinfo is not None
# d.tzinfo.utcoffset(d) does not return None<jupyter_output>Local - Timezone Naive unaware.tzinfo:
 None


UTC - Timezone Aware aware.tzinfo:
 UTC


US Central DateTime Aware aware_us_central.tzinfo:
 US/Central


US Eastern DateTime Aware aware_us_eastern.tzinfo:
 US/Eastern<jupyter_text>Refer to [list all time zones in Python](https://pynative.com/list-all-timezones-in-python/) if you do not know the exact name of the timezone you would like to reference.  To make an old/existing datetime timezone aware, use the **timezone.replace()** method.<jupyter_code>unaware = datetime.datetime(2021, 12, 6, 12, 45, 17, 5)
print('Timezone naive:', unaware, "\t\t unaware.tzinfo: ", unaware.tzinfo)

# Convert unaware Datetime to UTC timezone aware Datetime
aware = unaware.replace(tzinfo=pytz.UTC)
print('Timezone aware:', aware, "\t aware.tzinfo:\t ", aware.tzinfo)<jupyter_output>Timezone naive: 2021-12-06 12:45:17.000005 		 unaware.tzinfo:  None
Timezone aware: 2021-12-06 12:45:17.000005+00:00 	 aware.tzinfo:	  UTC<jupyter_text>**Get Current Time in Different Timezone**Using the **pytz** module we can get the current date and time of any timezone by passsing the timezone **region_name** as an argument to the **timezone()** method.Steps:1.   Use the **pytz.timezone('region_name')** function to create the timezone object(timezone_obj).2.   Use **datetime.now(timezone_obj)** function to get the current datetime of the given timezone.*Note: UTC – Coordinated Universal Time is the common time standard across the world. To avoid confusion , it is recommended to use the UTC as the base timezone for analysis then translate to the desired timezone for any reporting or other uses.* In the next example, we get the current datetime (date and time) in the following TimeZones of United States.<jupyter_code>dt_us_eastern = datetime.datetime.now(pytz.timezone('America/New_York'))
print("US Eastern timezone DateTime:\t", dt_us_eastern.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_us_central = datetime.datetime.now(pytz.timezone('America/Mexico_City'))
print("US Central timezone DateTime:\t", dt_us_central.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_us_mountain = datetime.datetime.now(pytz.timezone('America/Chihuahua'))
print("US Mountain timezone DateTime:\t", dt_us_mountain.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_us_pacific = datetime.datetime.now(pytz.timezone('America/Tijuana'))
print("US Pacific timezone DateTime:\t", dt_us_pacific.strftime("%Y:%m:%d %H:%M:%S %Z %z"))<jupyter_output><empty_output><jupyter_text>Let's try some international time zone regions...<jupyter_code>dt_japan = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
print("Japan DateTime:\t\t\t", dt_japan.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_brazil = datetime.datetime.now(pytz.timezone('America/Sao_Paulo'))
print("Brazil DateTime:\t\t", dt_brazil.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_uk = datetime.datetime.now(pytz.timezone('Europe/London'))
print("Uk DateTime:\t\t\t", dt_uk.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_germany = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
print("Germany DateTime:\t\t", dt_germany.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_aus = datetime.datetime.now(pytz.timezone('Australia/Canberra'))
print("Australia Oceanic DateTime:\t", dt_aus.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

dt_africa = datetime.datetime.now(pytz.timezone('Africa/Maputo'))
print("Central Africa DateTime:\t", dt_africa.strftime("%Y:%m:%d %H:%M:%S %Z %z"))<jupyter_output><empty_output><jupyter_text>**Get TimeZone Information Using tzinfo**The **datetime.tzinfo** is an abstract base class containing information about the date or time object passed to them.The tzinfo generally contains the following information: –*   The time zone name (region_name) of a Datetime*   Offset from the UTC (Coordinated Universal Time)*   The DST(Daylight Saving Time) statusThe **tzinfo** class provides the following method to get the timezone information: –*   **tzinfo.tzname(dt)** - Returns the time zone name corresponding to the datetime object dt. This method returns the name that is used while creating the timezone object*   **tzinfo.utcoffset(dt)** - This method returns the total offset from the UTC which should be a timedelta object. The values of the timedelta is positive if it is east of UTC and negative for the west of UTC. The total offset includes both timezone and the DST(Day light savings) values. The range of the timedelta is therfore between -timedelta(hours=24) to timedelta(hours=24)*   **tzinfo.dst(dt)** - This method returns dst offset in the zones where dst is in effect. In other cases it will return only timedelta(0). The dst information is already part of the the utcoffset therefore the **tz.utcoffset(dt)** - **tz.dst(dt)** should return the standard offset of the timezone irrespective of the date and time but only on the geographic location.<jupyter_code># example using US Eastern time

# timezone: US Eastern Time
dt_us_eastern = datetime.datetime.now(pytz.timezone('America/New_York'))
print("US Eastern DateTime:", dt_us_eastern.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

# Get current TimeZone name
print("Current time zone (region_name) name: ", dt_us_eastern.tzname())

# Get UTC Offset
print("Current time zone offset from UTC: ", dt_us_eastern.utcoffset())

# Get the daylight saving time (DST offset) adjustment
print("Current time zone DST adjustment: ", dt_us_eastern.dst())<jupyter_output><empty_output><jupyter_text>The datetime modules have the **timezone** class, which in turn is the subclass of the abstract base class **tzinfo** **Converting Between Timezones**Use the **datetime.astimezone()** method to convert the datetime from one timezone to another. This method uses an instance of the datetime object and returns a new datetime of a given timezone.<jupyter_code># UTC timezone Datetime
dt_local = datetime.datetime.now(pytz.utc)
print("UTC DateTime:\t\t", dt_local.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

# convert UTC timezone to 'US/Central'
dt_us_central = dt_local.astimezone(pytz.timezone('US/Central'))
print("US Central DateTime:\t", dt_us_central.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

# Convert 'US/Central' timezone to US/Eastern
dt_us_eastern = dt_us_central.astimezone(pytz.timezone('America/New_York'))
print("US Eastern DateTime:\t", dt_us_eastern.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

# Convert US/Eastern timezone to IST (India) timezone
dt_ind = dt_us_eastern.astimezone(pytz.timezone('Asia/Kolkata'))
print("India DateTime:\t\t", dt_ind.strftime("%Y:%m:%d %H:%M:%S %Z %z"))<jupyter_output>UTC DateTime:		 2021:12:06 18:21:32 UTC +0000
US Central DateTime:	 2021:12:06 12:21:32 CST -0600
US Eastern DateTime:	 2021:12:06 13:21:32 EST -0500
India DateTime:		 2021:12:06 23:51:32 IST +0530<jupyter_text>--- **Reference:  Timezones in Python***Finding a time zone:*Also, see [Working with Time Zones in Python](https://pynative.com/python-timezone/) by PyNative.**pytz** is based on the Olson time zone database. Some of the following examples are sourced from [pvlib python](https://pvlib-python.readthedocs.io/en/stable/timetimezones.html)We can obtain a list of all valid time zone strings with pytz.all_timezones. The Olson time zone list is long, so we only print every 20th time zone in the following example.<jupyter_code>import pytz

print(len(pytz.all_timezones))

print(pytz.all_timezones[::20])<jupyter_output>592
['Africa/Abidjan', 'Africa/Douala', 'Africa/Mbabane', 'America/Argentina/Catamarca', 'America/Belize', 'America/Curacao', 'America/Guatemala', 'America/Kentucky/Louisville', 'America/Mexico_City', 'America/Port-au-Prince', 'America/Sitka', 'Antarctica/Casey', 'Asia/Ashkhabad', 'Asia/Dubai', 'Asia/Khandyga', 'Asia/Qatar', 'Asia/Tomsk', 'Atlantic/Reykjavik', 'Australia/Queensland', 'Canada/Yukon', 'Etc/GMT+7', 'Etc/UCT', 'Europe/Guernsey', 'Europe/Paris', 'Europe/Vienna', 'Indian/Cocos', 'NZ', 'Pacific/Honolulu', 'Pacific/Samoa', 'US/Eastern']<jupyter_text>Let's use **pytz** to look at Timezone **Region_Names** in the USA.<jupyter_code>print(pytz.country_timezones('US'))<jupyter_output>['America/New_York', 'America/Detroit', 'America/Kentucky/Louisville', 'America/Kentucky/Monticello', 'America/Indiana/Indianapolis', 'America/Indiana/Vincennes', 'America/Indiana/Winamac', 'America/Indiana/Marengo', 'America/Indiana/Petersburg', 'America/Indiana/Vevay', 'America/Chicago', 'America/Indiana/Tell_City', 'America/Indiana/Knox', 'America/Menominee', 'America/North_Dakota/Center', 'America/North_Dakota/New_Salem', 'America/North_Dakota/Beulah', 'America/Denver', 'America/Boise', 'America/Phoenix', 'America/Los_Angeles', 'America/Anchorage', 'America/Juneau', 'America/Sitka', 'America/Metlakatla', 'America/Yakutat', 'America/Nome', 'America/Adak', 'Pacific/Honolulu']<jupyter_text>[Wikipedia's List of tz](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) database of time zones is also good reference. ---  **Working with Dates and Times in Pandas***from Geeks for Geeks*see: https://www.geeksforgeeks.org/python-working-with-date-and-time-using-pandas/Let's look at some of what we can do with dates and times when we have them available in Pandas DataFrame variables.  We should also import the Python datetime libary.To save typing, you could ```import datetime as dt```***For demonstration puroses in this notebook the datetime library is imported with its full name***<jupyter_code>import datetime<jupyter_output><empty_output><jupyter_text>**Accessing the Current Datetime Information**There are several means of accessing the current system date and time using Datetime in Python.*Remember that datetime information may be aware or naive.* ***When running on Colab, local time is the same as UTC time zone.***  **Accessing Current Local Datetime**The **datetime.now(**) method provides the current date and time.<jupyter_code>date_time_local = datetime.datetime.now()
print("The current local date and time as of the execution of this code was: ", date_time_local)<jupyter_output>The current local date and time as of the execution of this code was:  2021-12-06 18:26:32.843349<jupyter_text>**Accessing Current UTC Datetime**The following example uses the time zone argument in the datetime.now() function and displays the time in UTC (Universal Time Coordinated):<jupyter_code>date_time_utc = datetime.datetime.now(datetime.timezone.utc)
print("The current UTC date and time as of the execution of this code was: ", date_time_utc)<jupyter_output>The current UTC date and time as of the execution of this code was:  2021-12-06 18:26:38.361340+00:00<jupyter_text>**Accessing Current Date Only**In the prior examples, we accessed the date and time as using the **now()** method. To only access the current date, use the **date()** method as in the next example:<jupyter_code>date_only_local = datetime.datetime.now().date()
print("The current local date as of the execution of this code was: ", date_only_local)<jupyter_output>The current local date as of the execution of this code was:  2021-12-06<jupyter_text>**Accessing Current Time Only**In a similar manner to accessing only the date with the **.now().date()** method we can access only the time with the **.now().time()** method.<jupyter_code>time_only_local = datetime.datetime.now().time()
print("The current local time as of the execution of this code was: ", time_only_local)<jupyter_output>The current local time as of the execution of this code was:  18:27:17.725728<jupyter_text>**Accessing Current UTC Time Only**Similarly, the current time only in UTC time (or any other time zone) can be accessed.<jupyter_code>time_only_utc = datetime.datetime.now(datetime.timezone.utc).time()
print("The current UTC time as of the execution of this code was: ", time_only_utc)<jupyter_output>The current UTC time as of the execution of this code was:  18:28:00.111507<jupyter_text>--- **Working with Datetime Variables and Transformations in Pandas**Examples in this section are derived from [Working with Date and Time Using Pandas](https://www.geeksforgeeks.org/python-working-with-date-and-time-using-pandas/) from Geeks for Geeks.First, let's create a Series df_dates with dates and a frequency of 'H'<jupyter_code>ds_dates = pd.date_range('12/6/2021', periods = 10, freq ='H')
ds_dates
# Create a date and time dataframe and show basic features
ds_dates = pd.date_range('12/6/2011', periods = 10, freq ='H')
  
x = datetime.datetime.now()
x.month, x.year<jupyter_output><empty_output><jupyter_text>**Datetime** features can be divided into two categories.1.   The first one time moments in a period2.   The second one is the time passed since a particular periodThese features are useful to understand patterns in time-related data.Datetime Series features:*   **pandas.Series.dt.year** - returns the year of the date time.*   **pandas.Series.dt.month** - returns the month of the date time.*   **pandas.Series.dt.day** - returns the day of the date time.*   **pandas.Series.dt.hour** - returns the hour of the date time.*   **pandas.Series.dt.minute** - returns the minute of the date time.<jupyter_code># Create date and time with dataframe
df_rng = pd.DataFrame()
df_rng['date'] = pd.date_range('12/6/2011', periods = 72, freq ='H')
  
# Print the dates in dd-mm-yy format
df_rng[:5]
  
# Create features for year, month, day, hour, and minute
df_rng['year'] = df_rng['date'].dt.year
df_rng['month'] = df_rng['date'].dt.month
df_rng['day'] = df_rng['date'].dt.day
df_rng['hour'] = df_rng['date'].dt.hour
df_rng['minute'] = df_rng['date'].dt.minute
  
# Print the dates divided into features
print("The first three rows of df_rng:")
print(df_rng.head(3))
print("\nThe last three rows of df_rng:")
print(df_rng.tail(3))<jupyter_output><empty_output><jupyter_text>**To Create a Timestamp**To get the present time, use **Timestamp.now()** and then convert timestamp to datetime and directly access year, month or day.In older versions of Python or code you may see tslib as a member of Pandas but now it is in the _lib. member of Pandas as:  ```pandas._libs.tslib```So invoking **Timestamp.now()** takes the following form: ```pandas._libs.tslib.Timestamp.now() or, with an alias of pd for pandas as: pd._libs.tslib.Timestamp.now()```<jupyter_code># Input present datetime using Timestamp from the tslib library in Pandas
ts = pd._libs.tslib.Timestamp.now()
print("Timestamp generated at code execution: ", ts)<jupyter_output><empty_output><jupyter_text>Then convert the timestamp variable **ts** to **Datetime** with the in-place **to_datetime64()** method<jupyter_code>ts.to_datetime64()
print("Timestamp converted to Datetime: ", ts)<jupyter_output><empty_output><jupyter_text>Now you can directly access the features of the **ts** Datetime variable.<jupyter_code># Directly access and print the ts Datetime features
print("Timestamp ts year:\t", ts.year)
print("Timestamp ts month:\t", ts.month)
print("Timestamp ts day:\t", ts.day)
print("Timestamp ts hour:\t", ts.hour)
print("Timestamp ts minute:\t", ts.minute)
print("Timestamp ts second:\t", ts.second)<jupyter_output><empty_output><jupyter_text>Let’s work this approach on a real dataset uforeports.<jupyter_code>url = 'http://bit.ly/uforeports'
  
# read csv file
df_uf = pd.read_csv(url)           
df_uf.head()<jupyter_output><empty_output><jupyter_text>Let's look at the type of variable in each column of the **df_uf** Dataframe.<jupyter_code># show the type of each variable(column)
df_uf.dtypes<jupyter_output><empty_output><jupyter_text>Let's convert the **Time** object(String) variable to Timedate in the **df_uf** Dataframe.<jupyter_code># Convert the Time column to datatime format
df_uf['Time'] = pd.to_datetime(df_uf.Time)
  
df_uf.head()<jupyter_output><empty_output><jupyter_text>Let's look again at the type of variable in each column of the **df_uf** Dataframe.<jupyter_code># show the type of each variable(column)
df_uf.dtypes<jupyter_output><empty_output><jupyter_text>We can extract the hour information from the Datetime variable **Time**<jupyter_code># Get hour detail from Time variable in df_uf Dataframe
df_uf.Time.dt.hour.head()<jupyter_output><empty_output><jupyter_text>We can even derive the name of each date from the Datetime variable **Time** using the **dt.day_name()** method.Note that older versions of Pandas may have a method **dt.weekday_name()** which has been deprecated and replaced by **dt.day_name()**<jupyter_code># Get name of each date for the Time variable in the df_uf Dataframe
df_uf.Time.dt.day_name().head()<jupyter_output><empty_output><jupyter_text>The ordinal day of the year is the sequential number of the day of the year from January 1st.  That is: *   01-Jan = 1, *   02-Jan = 2, *   03-Jan = 3, *   ... *   01-Feb = 32, *   02-Feb = 33, *   etc.We can retrieve the ordinal day of a Datetime variable with the **dt.dayofyear()** method which is useful for plots and analysis.<jupyter_code># Get the ordinal day of the year for the **Time** variable in the **df_uf** Dataframe
df_uf.Time.dt.dayofyear.head()<jupyter_output><empty_output><jupyter_text>You may also want to explore examples of working with dates and times in Pandas at [Dates in Pandas Cheatsheet](https://dzone.com/articles/dates-in-pandas-cheatsheet) by <NAME> on DZone. *Let's try working with an open data file from NYC on film permist to see what we can do with Datetime variables...* ---  **Analyzing NYC Film Permits***from the NYC OpenData Collection* First, let's read the unedited version of the NYC OpenData Film Permits CSV file from: *   Film_Permits_RuhRoh_03DEC2021.csv<jupyter_code>df_fp = pd.read_csv('gdrive/MyDrive/data/Film_Permits_RuhRoh_03DEC2021.csv', sep=",")
df_fp.head(3)
# use this snippet to read the file as a text file and explore its contents
# handle_fp = open('gdrive/MyDrive/data/Film_Permits_RuhRoh_03DEC2021.csv', "r")
# or look at the file in Google Drive, or downloaded to a text editor<jupyter_output><empty_output><jupyter_text>Now, read the edited Film_Permits_03DEC2021.csv file into DataFrame df_fp<jupyter_code>df_fp = pd.read_csv('gdrive/MyDrive/data/Film_Permits_03DEC2021.csv', sep=",")<jupyter_output><empty_output><jupyter_text>Inspect the DataFrame **df_fp**<jupyter_code>df_fp.head(3)
df_fp.info()
df_fp.describe()<jupyter_output><empty_output><jupyter_text>By default, describe() won’t give us any information on the variables of object data type (categorical variables). To get their summary statistics, submit the **np.object** data type to the include argument.<jupyter_code>df_fp.describe(include=np.object)<jupyter_output><empty_output><jupyter_text>It seems that we are having trouble with the Datetime information in the following variables *   StartDateTime[1]*   EndDateTime[2]*   EnteredOn[3]Let's read the CSV file again and apply Datetime to the appropriate columns.<jupyter_code>df_fp = pd.read_csv('gdrive/MyDrive/data/Film_Permits_03DEC2021.csv', sep=",", parse_dates=['StartDateTime', 'EndDateTime', 'EnteredOn'])<jupyter_output><empty_output><jupyter_text>Now, let's inspect the Dataframe **df_fp** again...<jupyter_code>df_fp.info()
df_fp.describe(include=np.object)<jupyter_output><empty_output><jupyter_text>By default, the **describe(**) methods displays:*   the count of non-null occurrences (**count**),*   the number of unique values (**unique**),*   the mode (**top**) and*   the number of times the mode was observed (**freq**).The **describe()** method ignores missing values when calculating the summary statistics.Use the following Pandas DataFrame methods for specific metrics: *   **count()**: The number of non-null values*   **sum():** The total of the values*   **cumsum():** The cumulative sum*   **mean():** The average of the values*   **median():** The median of the values*   **min():** The minimum of the values*   **max():** The maximum of the values*   **abs():** The absolute value of the values*   **std():** The standard deviation*   **var():** The variance*   **cov():** Pairwise covariance of columns*   **corr():** Pairwise correlation of columns*   **quantile(q=0.7):** 70% quantileBy default, the calculations will be done column-wise (**axis=0**). If you want to get row-wise calculations, specify the axis parameter to 1 ---  **pprint (PrettyPrint)** **Well-formatted printing of Pandas DataFrames and other data in Python.**We will import the following module to prepare well-formatted printouts of our df_fp DataFrame and learn to use pprint with other data structures in Python*   from pprint import pprintWe will also import the requests module to access some data for pprint exercises: *   from urllib import requestsThis section utilizes information from the RealPython tutorial on pprint at: https://realpython.com/python-pretty-print/ Also see: [pprint - Data pretty print from Python.org](https://docs.python.org/3/library/pprint.html) The Python pprint module is helpful in many situations. It comes in handy when making API requests, dealing with JSON files, or handling complicated and nested data. You’ll probably find that using the normal print() function isn’t adequate to efficiently explore your data and debug your application. When you use print() with dictionaries and lists, the output doesn’t contain any newlines.Before you start exploring pprint, you’ll first use urllib to make a request to get some data. You’ll make a request to {JSON} Placeholder for some mock user information. The first thing to do is to make the HTTP GET request and put the response into a dictionary:<jupyter_code>from urllib import request
response = request.urlopen("https://jsonplaceholder.typicode.com/users")
json_response = response.read()
import json
users = json.loads(json_response)<jupyter_output><empty_output><jupyter_text>Here, you make a basic **GET** request and then parse the response into a dictionary with **json.loads()**. With the dictionary now in a variable, a common next step is to print the contents with **print()**:<jupyter_code>print(users)<jupyter_output><empty_output><jupyter_text>Depending on your console settings, this might appear as one very long line. Alternatively, your console output might have its word-wrapping mode on, which is the most common situation. Unfortunately, that doesn’t make the output much friendlier!If you look at the first and last characters, you can see that this appears to be a list. You might be tempted to start writing a loop to print the items:<jupyter_code>for user in users:
    print(user)<jupyter_output><empty_output><jupyter_text>This for loop would print each object on a separate line, but even then, each object takes up way more space than can fit on a single line. Printing in this way does make things a bit better, but it’s by no means ideal. The above example is a relatively simple data structure, but what would you do with a deeply nested dictionary 100 times the size?Sure, you could write a function that uses recursion to find a way to print everything. Unfortunately, you’ll likely run into some edge cases where this won’t work. You might even find yourself writing a whole module of functions just to get to grips with the structure of the data!This is one of many cases where the **pprint** module is invaluable.  **Working With pprint**pprint is a Python module made to print data structures in a pretty way. It has long been part of the Python standard library, so installing it separately isn’t necessary. All you need to do is to import its **pprint()** function using its alias **pp**:<jupyter_code>from pprint import pprint as pp<jupyter_output><empty_output><jupyter_text>Then, instead of going with the normal **print**(users) approach as you did in the example above, you can call your new favorite function to make the output pretty:<jupyter_code>pp(users)<jupyter_output><empty_output><jupyter_text>**Exploring Optional Parameters of pprint()**Let's look at the parameters available for pprint(). There are seven parameters that you can use to configure your Pythonic pretty printer. You don’t need to use them all, and some will be more useful than others. The one you’ll find most valuable will probably be **depth**. **Summarizing Your Data: depth**One of the handiest parameters to play around with is **depth**. The following Python command will only print the full contents of users if the data structure is at or lower than the specified depth—all while keeping things pretty, of course. The contents of deeper data structures are replaced with three dots:<jupyter_code>pp(users, depth=1)
pp(users, depth=2)<jupyter_output><empty_output><jupyter_text>**Giving Your Data Space: indent**The **indent** parameter controls how indented each level of the pretty-printed representation will be in the output. The *default indent is just 1*, which translates to one space character:<jupyter_code>pp(users[0], depth=1)<jupyter_output><empty_output><jupyter_text>The most important part of the indenting behavior of **pprint(**) is keeping all the keys aligned visually. How much indentation is applied depends on both the indent parameter and where the key is.Since there’s no nesting in the examples above, the amount of indentation is based completely on the indent parameter. In both examples, note how the opening curly bracket ({) is counted as a unit of indentation for the first key. In the first example, the opening single quote for the first key comes right after { without any spaces in between because the indent is set to 1.When there is nesting, however, the indentation is applied to the first element in-line, and **pprint()** then keeps all following elements aligned with the first one. So if you set your indent to 4 when printing users, the first element will be indented by four characters, while the nested elements will be indented by more than eight characters because the indentation starts from the end of the first key:<jupyter_code>pp(users[0], depth=2, indent=4)<jupyter_output><empty_output><jupyter_text>**Limiting Your Line Lengths: width**By default, **pprint()** will only output up to eighty characters per line. You can customize this value by passing in a width argument. **pprint(**) will make an effort to fit the contents on one line. If the contents of a data structure go over this limit, then it’ll print every element of the current data structure on a new line:<jupyter_code>pp(users[0])<jupyter_output><empty_output><jupyter_text>When you leave the width at the default of eighty characters, the dictionary at users[0]['address']['geo'] only contains a 'lat' and a 'lng' attribute. This means that taking the sum of the indent and the number of characters needed to print out the dictionary, including the spaces in between, comes to less than eighty characters. Since it’s less than eighty characters, the default width, pprint() puts it all on one line.However, the dictionary at users[0]['company'] would go over the default width, so **pprint()** puts each key on a new line. This is true of dictionaries, lists, tuples, and sets:ta structure go over this limit, then it’ll print every element of the current data structure on a new line:<jupyter_code>pp(users[0], width=160)<jupyter_output><empty_output><jupyter_text>**Squeezing Your Long Sequences: compact**You might think that **compact** refers to the behavior you explored in the section about width—that is, whether **compact** makes data structures appear on one line or separate lines. However, **compact** only affects the output once a line goes over the width.*Note: compact only affects the output of sequences: lists, sets, and tuples, and not dictionaries. This is intentional, though it’s not clear why this decision was taken. There’s an ongoing discussion about that in Python Issue 34798.*If **compact** is **True**, then the output will wrap onto the next line. The default behavior is for each element to appear on its own line if the data structure is longer than the width:<jupyter_code>print("\ndepth=1")
pp(users, depth=1)
print("\ndepth=1 and width=40")
pp(users, depth=1, width=40)
print("\ndepth=1, width=40, and compact=True")
pp(users, depth=1, width=40, compact=True)<jupyter_output><empty_output><jupyter_text>**Directing Your Output: stream**The **stream** parameter refers to the output of **pprint()**. By default, it goes to the same place that **print()** goes to. Specifically, it goes to sys.stdout, which is actually a file object in Python. However, you can redirect this to any file object, just like you can with **print()**:<jupyter_code># This code writes to the sample_data folder under /content in the current Colab session
with open("/content/sample_data/output.txt", mode="w") as file_object:
    pp(users, stream=file_object)<jupyter_output><empty_output><jupyter_text>The code above created a file object with open(), and then set the stream parameter in **pprint()** to that file object. If you then open the **output.txt** file in **sample_data** under the /content folder in thjis Colab session, you should see that you’ve pretty-printed everything in users there.Python does have its own logging module. However, you can also use **pprint()** to send pretty outputs to files and have these act as logs if you prefer.  **Creating a Custom PrettyPrinter Object**It’s possible to create an instance of PrettyPrinter that has defaults you’ve defined. Once you have this new instance of your custom **PrettyPrinter** object, you can use it by calling the **.pprint()** method on the PrettyPrinter instance:<jupyter_code>from pprint import PrettyPrinter
custom_printer = PrettyPrinter(
    indent=4,
    width=100,
    depth=2,
    compact=True
    # sort_dicts=False, this argument is deprecated
    # underscore_numbers=True this argument is deprecated
)
custom_printer.pprint(users[0])<jupyter_output><empty_output><jupyter_text>**Getting a Pretty String With pformat()**What if you don’t want to send the pretty output of **pprint()** to a stream? Perhaps you want to do some **regex** matching and replace certain keys. For plain dictionaries, you might find yourself wanting to remove the brackets and quotes to make them look even more human-readable.Whatever it is that you might want to do with the string pre-output, you can get the string by using **pformat()**:<jupyter_code>from pprint import pformat
address = pformat(users[0]["address"])
chars_to_remove = ["{", "}", "'"]
for char in chars_to_remove:
    address = address.replace(char, "")

print(address)<jupyter_output><empty_output><jupyter_text>**pformat()** is a tool you can use to get between the pretty printer and the output stream.Another use case for this might be if you’re building an API and want to send a pretty string representation of the JSON string. ---  **Pretty Print (pprint) and Pandas DataFrames**This section of the notebook refers to examples from [How to Pretty Print an Entire Pandas Series or DataFrame by Geeks-for-Geeks](https://www.geeksforgeeks.org/how-to-pretty-print-an-entire-pandas-series-or-dataframe/) There are 2 ways to Pretty Print an entire **Pandas Series / Dataframe**:1.   Use **pd.set_options()** method2.   Use **pd.option_context()** method **Method 1: Using pd.set_options() method**Sets the value of the specified option. There are various pretty print options are available for use with this method.For example display.max_columns, display.max_colwidth, display.max_rows, display.colheader_justify, display.precision, etc.  Some pretty print options are discussed below:*   **display.max_columns** - The maximum number of columns pandas should print. If None is provided as an argument all columns are printed.*   **display.max_rows** - The maximum number of rows pandas should print. If None is provided as an argument all rows are printed.*   **display.colheader_justify** - Controls the alignment of column headers*   **display.precision** - Floating point output precision in terms of a number of places after the decimal, for regular formatting as well as scientific notation.*   **display.date_dayfirst** - When True, prints and parses dates with the day first, e.g. 20/12/2020*   **display.date_yearfirst** - When True, prints and parses dates with the year first, e.g. 2020/12/20*   **display.width** - Width of the display in characters. If set to None, pandas will correctly auto-detect the width.<jupyter_code>import pandas as pd
  
# Create a dataframe
df = pd.DataFrame({
  'Product_id': ['ABC', 'DEF', 'GHI', 'JKL', 
                 'MNO', 'PQR', 'STU', 'VWX'],
    
  'Stall_no': [37, 38, 9, 50, 7, 23, 33, 4],
  'Grade': [1, 0, 0, 2, 0, 1, 3, 0],
    
  'Category': ['Fashion', 'Education', 'Technology', 
               'Fashion', 'Education', 'Technology', 
               'Fashion', 'Education'],
    
  'Demand': [10, 12, 14, 15, 13, 20, 10, 15],
  'charges1': [376, 397, 250, 144, 211, 633, 263, 104],
  'charges2': [11, 12, 9, 13, 4, 6, 13, 15],
  'Max_Price': [4713, 10352, 7309, 20814, 9261, 
                6104, 5257, 5921],
    
  'Selling_price': [4185.9477, 9271.490256, 6785.701362, 
                    13028.91782, 906.553935, 5631.247872, 
                    3874.264992, 4820.943]})
display(df)<jupyter_output><empty_output><jupyter_text>We will use some options of **set_options()** method on above **df** to see all rows, all columns, all columns in one row with center aligned column headers and rounding number of places after the decimal for each floating value to 2.<jupyter_code>pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)
pd.set_option('display.colheader_justify', 'center')
pd.set_option('display.precision', 2)
display(df)<jupyter_output><empty_output><jupyter_text>Once set through **pd.set_options()** method, the same settings are used with all the next dataframe printing commands.  **Method 2: Using pd.option_context()****pd.set_option()** method provides permanent setting for displaying dataframe. **pd.option_context()** temporarily sets the options in with statement context. **pd.option_context()** is a one liner code for above **pd.set_options()** and has a temporary effect. The following code prints the above **df** with 5 rows, all columns, all columns in one row with left-aligned column headers and rounding number of places after the decimal for each floating value to 3.<jupyter_code>with pd.option_context('display.max_rows', 5,
                       'display.max_columns', None,
                       'display.width', 1000,
                       'display.precision', 3,
                       'display.colheader_justify', 'left'):
    display(df)<jupyter_output><empty_output><jupyter_text>---  **Charting (Plots) with np.plot(), matplotlib, and Seaborn** **Graphical Descriptions of a Pandas DataFrame**With the Pandas plot() method we can easily create:*   vertical bar plots*   pie charts*   boxplots*   density plots*   scatter plots **Vertical Bar Plots**A vertical bar plot presents categorical data with rectangular bars that have bar heights proportional to the values represented by the variable.<jupyter_code># plot with vertical bars of permit count by Borough
df_fp.Borough.value_counts().plot(kind="bar",
                           title="Permits by Boro",
                           rot=15,
                           xlabel="Borough",
                           ylabel="Count")<jupyter_output><empty_output><jupyter_text>Stacked Vertical Bar PlotsWe can use the **groupby()** method to summarize totals and subtotals by categorical variables and use the result to created a stacked bar plot with the **plot()** method. The following example shows our **df_fp** DataFrame grouped by Category of permit then Borough to produce a stacked bar plot.<jupyter_code>df_fp.groupby(['Category', 'Borough']).size().unstack().plot(kind='bar', stacked=True)
df_fp.groupby(['Borough', 'Category']).size().unstack().plot(kind='bar', stacked=True)<jupyter_output><empty_output><jupyter_text>**Pie Charts**A pie chart uses the **plot()** method to present categorical data with pie slices as a relative size of a category's value as a proportion of a circle whose circumference represents the value of the total of all categories' values.<jupyter_code>df_fp.Borough.value_counts().plot(kind="pie",
                           title="Permits by Boro")<jupyter_output><empty_output><jupyter_text>*Notice from the plot() output header lines that Pandas is invoking matplotlib for graphical representation of results.* --- For simplicity, let's create a new variable 'Date' in the **df_fp** DataFrame.  We can use the .date part of 'StartDateTime' to create 'Date'<jupyter_code>df_fp['Date'] = df_fp['StartDateTime'].dt.date<jupyter_output><empty_output><jupyter_text>Let's calculate the duration in hours from **StartDateTime** to **EndDateTime** as a new variable **OnLocationHours**<jupyter_code>df_fp['OnLocationDelta'] = df_fp['EndDateTime'] - df_fp['StartDateTime']
df_fp['OnLocationTime'] = df_fp['OnLocationDelta'].astype('timedelta64[h]')
df_fp.describe()
df_fp.head(3)
del df_fp['OnLocationDelta'] 
df_fp.describe()
df_fp.info()<jupyter_output><empty_output><jupyter_text>--- **Create Boxplots**A boxplot shows the summary statistics of a continuous variable.<jupyter_code>df_fp.plot(y="OnLocationTime",
        kind="box",
        title="Boxplot - Time on Location")<jupyter_output><empty_output><jupyter_text>**Create Density Plots**A density plot shows the distribution (Kernel Density Estimation Curve) of a continuous variable.<jupyter_code>df_fp.plot(y="OnLocationTime",
        kind="density",
        title="Density plot - Time on Location")<jupyter_output><empty_output><jupyter_text>--- Let's add another variable for the ordinal day of the **StartDateTime** to estimate the time of year when on location work will begin.  We can assign values to the new variable **OrdinalStartDay** using the **.dt.dayofyear()** method on the **StartDateTime** variable.<jupyter_code>df_fp['OrdinalStartDay'] = df_fp.StartDateTime.dt.dayofyear

df_fp.describe()<jupyter_output><empty_output><jupyter_text>--- **Create Scatter Plot**A scatter plot shows the relationship between two continuous variables.<jupyter_code>df_fp.plot(x="OnLocationTime",
        y="OrdinalStartDay",
        kind="scatter",
        title="Time on Location vs. Ordinal Start Day")<jupyter_output><empty_output><jupyter_text>**Create Histogram**A histogram of a continuous variable presents the distribution of the values of that variable. Instead of the **plot()** method, here we use the hist() method from **pyplot** in the **matplotlib** library on the Pandas DataFrame.<jupyter_code>#import pyplot from matplotlib library 
import matplotlib.pyplot as mplot

# create a histogram of TimeOnLocation by OrdinalStartDay
df_fp.hist(column="OrdinalStartDay",
        bins=366,
        grid=False)
mplot.title("Histogram - Time on Location by Ordinal Start Day")
mplot.xlabel("TimeOnLocation")<jupyter_output><empty_output><jupyter_text>**Create a Heatmap**A heatmap can be used to visualize the correlation coefficients of continuous variables with a beautiful colourmap. Pairwise correlations between the variables can be calculated using the Pandas DataFrame **corr()** method. Then we use the Seaborn **heatmap()** function to create the heatmap. First things to do in creating a heatmap is to create an array for the heatmap to use.  That array should be wide not long, so we will want to pivot from the current df_fp Dataframe.<jupyter_code># pivot the dataframe from long to wide form
df_result = df_fp.groupby(['Borough']).mean()
df_result.head(5)
del df_result['EventID']
df_result.head(5)
df_result['ReallyLong'] = df_result['OnLocationTime']*10
del df_result['OnLocationTime']
df_result.head(5)
# import pyplot from matplotlib library 
import matplotlib.pyplot as mplot
# import seaborn as sns
import seaborn as sns

# create a heatmap using Seaborn (sns)
sns.heatmap(df_result, annot=True, fmt="g", cmap='viridis')
mplot.show()<jupyter_output><empty_output><jupyter_text>**Create a Scatter Matrix**A scatter matrix contains pairwise scatter plots between the continuous variables. They are very useful in machine learning to see which variable are useful in building a model. By default, the diagonal of the scatter matrix contains histograms of each continuous variable itself. The Pandas plotting subpackage provides the **scatter_matrix()** function that can be used to create a scatter matrix.<jupyter_code>from pandas.plotting import scatter_matrix

scatter_matrix(df_fp, figsize=(15,15))<jupyter_output><empty_output><jupyter_text>Given our source data, some of the aforementioned plots and graphical representations are not appropriate but they do provide examples of discovery analysis which may be used against other data sets.For more information see [Pandas Visualization Tools](https://pbpython.com/dataframe-gui-overview.html) by <NAME> in Practical Business Python.  --- **Create an Area Plot**An area chart, plot, or  graph displays graphically quantitative data. It is based on the line chart. The area between axis and line are commonly emphasized with colors, textures and hatchings. Commonly one compares two or more quantities with an area chart. Let's  create new **df_fp** variables 'PermitsNYC', 'PermitsSI', 'PermitsBK', 'PermitsQNS','PermitsBX' which each have a value of 1 for each row where a permit was issued in there respective Borough.<jupyter_code>df_fp['PermitsNYC'] = np.where(df_fp['Borough'] == "Manhattan",     1, 0)

df_fp['PermitsSI'] = np.where(df_fp['Borough']  == "Staten Island", 1, 0)

df_fp['PermitsBK'] = np.where(df_fp['Borough']  == "Brooklyn",      1, 0)

df_fp['PermitsQNS'] = np.where(df_fp['Borough'] == "Queens",        1, 0)

df_fp['PermitsBX'] = np.where(df_fp['Borough']  == "Bronx",         1, 0)
df_fp.info()<jupyter_output><empty_output><jupyter_text>Let's create a DataFrame **df_boro** with ['Date', 'Borough', 'PermitsNYC',  'PermitsSI', 'PermitsBK', 'PermitsQNS', 'PermitsBX'] for film permits in **df_fp**<jupyter_code>df_boro = df_fp[['Date', 'PermitsBK', 'PermitsBX', 'PermitsSI', 'PermitsQNS', 'PermitsNYC']]
df_boro.info()
df_boro.head()<jupyter_output><empty_output><jupyter_text>Now we can sort our new **df_boro** DataFrame by 'Date'.<jupyter_code>df_boro_sorted = df_boro.sort_values('Date')
df_boro_sorted.head()
df_boro_sorted.tail()
df_boro_ready = df_boro_sorted.groupby('Date').sum()
df_boro_ready.info()<jupyter_output><empty_output><jupyter_text>Let's look at that new **df_boro_ready** DataFrame.<jupyter_code>df_boro_ready.head(10)
df_boro_ready.tail(10)
# do not reset the index or the Date will be lost for plotting
# df_boro_ready = df_boro_ready.reset_index()<jupyter_output><empty_output><jupyter_text>We can use the **df_boro_ready** DataFrame to plot an area chart of the number of permits by Borough over time.<jupyter_code>df_boro_ready.plot.area(figsize=(8, 6), title='Area Plot')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07467523865874229, 'fraction_numerical': 0.08458366081757729, 'mean_word_length': 8.842503259452412, 'pattern_counts': {'":': 0, '<': 351, '<?xml version=': 0, '>': 355, 'https://': 15, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '87', 'dir': 'jupyter-structured-clean-dedup', 'id': '124335', 'license': 'MIT', 'n_tokens_mistral': 60607, 'n_tokens_neox': 55561, 'n_words': 7124, 'path': 'CST2312_WK17CL28_Dates_Films_PP_13Dec2021.ipynb', 'repo_name': 'ProfessorPatrickSlatraigh/CST2312', 'size': '208056'}