Skip to content

Commit 5489cb7

Browse files
authored
Merge pull request #10 from dmorton714/historical_dashboard
Data cleaning for enrollment data set, data manipulation for: most common pathways taken and completion rates, example use Jupyter nb
2 parents 24ea8e7 + 8f9f01c commit 5489cb7

5 files changed

Lines changed: 429 additions & 0 deletions

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Personal
2+
Data/
3+
Tests/
4+
tester_2.ipynb
5+
16
# Byte-compiled / optimized / DLL files
27
__pycache__/
38
*.py[codz]

cleaning_enrollments_data.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import pandas as pd
2+
import numpy as np
3+
4+
class EnrollmentsCleaning:
5+
def __init__(self, raw_data):
6+
self.raw_data = raw_data
7+
8+
def Drop_columns(self, df):
9+
COLUMNS_TO_DROP = ['Full Name']
10+
result = df.drop(columns=COLUMNS_TO_DROP)
11+
return result
12+
13+
def Fix_nan_values(self, df):
14+
# Fix NaN values
15+
NAN_VALUE_SUBSTITUTE = 'NA'
16+
columns_to_fix = {
17+
'Projected Start Date': NAN_VALUE_SUBSTITUTE, 'Actual Start Date': NAN_VALUE_SUBSTITUTE, 'Projected End Date': NAN_VALUE_SUBSTITUTE,
18+
'Actual End Date': NAN_VALUE_SUBSTITUTE, 'Outcome': NAN_VALUE_SUBSTITUTE
19+
}
20+
# 'ATP Cohort' NA will handle in a separed function
21+
for column, substitute_value in columns_to_fix.items():
22+
df[column] = df[column].fillna(substitute_value)
23+
24+
return df
25+
26+
def Rename_values(self, df):
27+
# Fix change name Data Analitics 2 to Data Analysis 2 for consistency
28+
df.loc[df['Service'] == 'Data Analytics 2', 'Service'] = 'Data Analysis 2'
29+
return df
30+
31+
def Delete_values(self, df):
32+
# Delete values not needed
33+
# 'Referral to External Service', 'Supportive Services Referral', are deleted because dont have a "Projected Start Date"
34+
values_not_needed = {
35+
'Service': ['Software Development 1', 'Software Development 2', 'Web Development 1', 'Web Development 2', 'Data Analysis 1','Data Analysis 2', 'Referral to External Service', 'Supportive Services Referral']
36+
}
37+
for column, value in values_not_needed.items():
38+
df = df[~df[column].isin(value)]
39+
return df
40+
41+
def Set_data_types(self, df):
42+
# DataTypes
43+
column_datatype: dict = {'Auto Id': str, 'KY Region': str, 'Assessment ID': str, 'EnrollmentId': str,
44+
'Enrollment Service Name': str, 'Service': str, 'Projected Start Date': str,
45+
'Actual Start Date': str, 'Projected End Date': str, 'Actual End Date': str, 'Outcome': str,
46+
'ATP Cohort': 'datetime64[ns]'}
47+
# TODO: 'Projected Start Date', 'Actual Start Date', 'Projected End Date', 'Actual End Date' are all datetime types but have a value fix of NA
48+
49+
for column, type in column_datatype.items():
50+
df[column] = df[column].astype(type)
51+
return df
52+
53+
def Find_cohort(self, id: str, projected_start_date: str, cohort_to_find: str, df_to_clean: pd.DataFrame):
54+
## Q: What to do with Service: ['Referral to External Service', 'Supportive Services Referral']
55+
## TODO: Clean the NaTType before this function runs
56+
if pd.isna(cohort_to_find):
57+
student_df = df_to_clean[df_to_clean['Auto Id'] == id]
58+
# remove ATP Cohort NA values, it can be more than one
59+
student_df: pd.DataFrame = student_df[~student_df['ATP Cohort'].isna()]
60+
cohorts_participaded = student_df['ATP Cohort'].astype('datetime64[ns]').unique()
61+
62+
# print(cohorts_participaded)
63+
if len(cohorts_participaded) == 1:
64+
return cohorts_participaded[0]
65+
else:
66+
# cohorts_participaded.append(pd.to_datetime(projected_start_date))
67+
stimated_module_date = np.datetime64(projected_start_date)
68+
cohorts_participaded = np.append(cohorts_participaded, stimated_module_date)
69+
cohorts_participaded.sort()
70+
previus_date = cohorts_participaded[0]
71+
for cohort in cohorts_participaded:
72+
if stimated_module_date == cohort:
73+
return previus_date
74+
else:
75+
return np.datetime64(cohort_to_find)
76+
77+
def Get_clean_data(self):
78+
df = self.raw_data
79+
df = self.Drop_columns(df)
80+
df = self.Fix_nan_values(df)
81+
df = self.Rename_values(df)
82+
df = self.Delete_values(df)
83+
df = self.Set_data_types(df)
84+
df['ATP Cohort'] = df.apply(lambda row: self.Find_cohort(row['Auto Id'], row['Projected Start Date'], row['ATP Cohort'], df), axis=1)
85+
return df

completion_rate_data.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import pandas as pd
2+
3+
class Completion_rate_data:
4+
def __init__(self, data):
5+
self.data = data
6+
self.__pathways = [
7+
'Web Development M1',
8+
'Web Development M2',
9+
'Web Development M3',
10+
'Web Development M4',
11+
'Data Analysis M1',
12+
'Data Analysis M2',
13+
'Data Analysis M3',
14+
'Data Analysis M4',
15+
'Software Development M1',
16+
'Software Development M2',
17+
'Software Development M3',
18+
'Software Development M4',
19+
'Quality Assurance M1',
20+
'Quality Assurance M2',
21+
'Quality Assurance M3',
22+
'Quality Assurance M4',
23+
'User Experience M1',
24+
'User Experience M2',
25+
'User Experience M3',
26+
'User Experience M4',
27+
]
28+
29+
# Not the best Pandas way to do it:
30+
def Get_completion_percentages(self, cohort: str = 'All cohorts') -> pd.DataFrame:
31+
32+
33+
if cohort == 'All cohorts':
34+
data = self.data
35+
else:
36+
data = self.data[self.data['ATP Cohort'] == pd.Timestamp(cohort)]
37+
38+
completion_dictionary = {}
39+
40+
for path in self.__pathways:
41+
outcome = data[data['Service'] == path]['Outcome'].value_counts(normalize=True).reset_index()
42+
completion_dictionary[path] = {row.Outcome: row.proportion for row in outcome.itertuples(index=True)}
43+
44+
result_df = pd.DataFrame(completion_dictionary).transpose().fillna(0).rename_axis('Module').reset_index()
45+
46+
result_df['Pathway'] = result_df['Module'].apply(lambda x: x[:x.rfind(' ')]) # intended to be able to sort by pathway
47+
return result_df
48+
# TODO: Add test
49+
50+
def Get_pathways_name(self, df: pd.DataFrame) -> list:
51+
return list(df['Pathway'].unique())
52+

most_common_pathways_taken_data.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import pandas as pd
2+
3+
class Most_common_pathways_taken_data:
4+
def __init__(self, data):
5+
self.data = data
6+
self.__starter_pathways = [
7+
'Web Development M1',
8+
'Data Analysis M1',
9+
'Software Development M1',
10+
'Quality Assurance M1',
11+
'User Experience M1',
12+
]
13+
self.starter_only_df = self.Get_starting_pathways()
14+
15+
def Get_starting_pathways(self):
16+
"""
17+
Returns a pandas.DataFrame were all the services are the biginning paths
18+
19+
Args:
20+
df: pandas.DataFrame
21+
22+
Return:
23+
pandas.DataFrame
24+
"""
25+
mask_starter_pathways = self.data['Service'].isin(self.__starter_pathways)
26+
return self.data[mask_starter_pathways]
27+
28+
def Get_cohorts_list(self):
29+
df = self.starter_only_df
30+
cohorts = list(pd.to_datetime(df['ATP Cohort'][df['ATP Cohort'] != 'NA']).sort_values(ascending=True).astype(str).unique())
31+
cohorts.insert(0, 'All cohorts')
32+
return cohorts
33+
34+
def Get_data_by_cohort(self, cohort: str = 'All cohorts') -> pd.DataFrame:
35+
df = self.starter_only_df
36+
if cohort == 'All cohorts':
37+
result = df.value_counts('Service').reset_index()
38+
else:
39+
result = df[df['ATP Cohort'] == str(pd.to_datetime(cohort))].value_counts('Service').reset_index()
40+
41+
return result

0 commit comments

Comments
 (0)