<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Pandas Data Types
Accompanying the PB Python article here
Step1:  Use df.info and df.dtypes to look at the types that pandas automatically infers based on the data
Step2:  df.dtypes
Since the 2016 and 2017 columns were read in as objects, trying to add the values will result in string concatenation not numerical addition
Step3:  The simplest way to to convert to a type is using astype.
We can apply it to the customer number first.
Step4:  The code above does not alter the original dataframe
Step5:  Assign the new integer customer number back to the original frame and check the type
Step6:  The data all looks good for the Customer Number.
If we try to convert the Jan Units column, we will get an error.
Step7:  In a similar manner we get an error if we try to convert the sales column
Step8:  We can try to use astype with a bool type but that does not give expected results
Step11:  In order to convert the currency and percentages, we need to use custom functions
Step12:  Use apply to convert the 2016 and 2017 columns to floating point numbers
Step13:  We could use a lambda function as well but it may be more difficult for new users to understand
Step14:  Use a lambda function to convert the percentage strings to numbers
Step15:  pd.to_numeric is another option for handling column conversions when invalid values are included
Step16:  Make sure to populate the original column of data
Step17:  pd.to_datetime is very useful for working with date conversions
Step18:  Use np.where to convert the active column to a boolean
Step19:  Many of the examples shown above can be used when reading in data using dtypes or converters arguments
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
import numpy as np
df = pd.read_csv("https://github.com/chris1610/pbpython/blob/master/data/sales_data_types.csv?raw=True")
df
Explanation: Pandas Data Types
Accompanying the PB Python article here
End of explanation
df.info()
Explanation: Use df.info and df.dtypes to look at the types that pandas automatically infers based on the data
End of explanation
df['2016'] + df['2017']
Explanation: df.dtypes
Since the 2016 and 2017 columns were read in as objects, trying to add the values will result in string concatenation not numerical addition
End of explanation
df['Customer Number'].astype('int')
Explanation: The simplest way to to convert to a type is using astype.
We can apply it to the customer number first.
End of explanation
df.dtypes
Explanation: The code above does not alter the original dataframe
End of explanation
df["Customer Number"] = df['Customer Number'].astype('int')
df.dtypes
df
Explanation: Assign the new integer customer number back to the original frame and check the type
End of explanation
df['Jan Units'].astype('int')
Explanation: The data all looks good for the Customer Number.
If we try to convert the Jan Units column, we will get an error.
End of explanation
df['2016'].astype('float')
Explanation: In a similar manner we get an error if we try to convert the sales column
End of explanation
df['Active'].astype('bool')
# astype can take a dictionary of column names and data types
df.astype({'Customer Number': 'int', 'Customer Name': 'str'}).dtypes
Explanation: We can try to use astype with a bool type but that does not give expected results
End of explanation
def convert_currency(val):
    
    Convert the string number value to a float
     - Remove $
     - Remove commas
     - Convert to float type
    
    new_val = val.replace(',','').replace('$', '')
    return float(new_val)
def convert_percent(val):
    
    Convert the percentage string to an actual floating point percent
    
    new_val = val.replace('%', '')
    return float(new_val) / 100
Explanation: In order to convert the currency and percentages, we need to use custom functions
End of explanation
df['2016'].apply(convert_currency)
df['2017'].apply(convert_currency)
Explanation: Use apply to convert the 2016 and 2017 columns to floating point numbers
End of explanation
df['2016'].apply(lambda x: x.replace('$', '').replace(',', '')).astype('float')
# Assign the converted values back to the columns
df['2016'] = df['2016'].apply(convert_currency)
df['2017'] = df['2017'].apply(convert_currency)
Explanation: We could use a lambda function as well but it may be more difficult for new users to understand
End of explanation
df['Percent Growth'].apply(lambda x: x.replace('%', '')).astype('float') / 100
df['Percent Growth'] = df['Percent Growth'].apply(convert_percent)
df.dtypes
# Let's look at the data so far
df
Explanation: Use a lambda function to convert the percentage strings to numbers
End of explanation
pd.to_numeric(df['Jan Units'], errors='coerce')
# Fill in the NaN with 0
pd.to_numeric(df['Jan Units'], errors='coerce').fillna(0)
Explanation: pd.to_numeric is another option for handling column conversions when invalid values are included
End of explanation
df["Jan Units"] = pd.to_numeric(df['Jan Units'], errors='coerce').fillna(0)
Explanation: Make sure to populate the original column of data
End of explanation
pd.to_datetime(df[['Month', 'Day', 'Year']])
df["Start_Date"] = pd.to_datetime(df[['Month', 'Day', 'Year']])
# Check out the dataframe
df
Explanation: pd.to_datetime is very useful for working with date conversions
End of explanation
df["Active"] = np.where(df["Active"] == "Y", True, False)
df
df.dtypes
Explanation: Use np.where to convert the active column to a boolean
End of explanation
df_2 = pd.read_csv("https://github.com/chris1610/pbpython/blob/master/data/sales_data_types.csv?raw=True", 
                   dtype={'Customer Number':'int'},
                   converters={'2016':convert_currency,
                               '2017': convert_currency,
                               'Percent Growth': convert_percent,
                               'Jan Units': lambda x: pd.to_numeric(x, errors='coerce'),
                               'Active': lambda x: np.where(x == "Y", True, False)
                              })
df_2.dtypes
df_2
# This can not be applied at the time the data is read in
df_2["Start_Date"] = pd.to_datetime(df_2[['Month', 'Day', 'Year']])
df_2
Explanation: Many of the examples shown above can be used when reading in data using dtypes or converters arguments
End of explanation
<END_TASK>