Jade Burgin
clean up file
ea0ca9b
Raw
History Blame Contribute Delete
6.75 kB
import numpy as np
import pandas as pd
class EncoderInterface:
def __init__(self, df, ref_col) -> None:
self.df = df
self.ref_col = ref_col
def encode(self):
pass
class AgeEncoder(EncoderInterface):
def __init__(self, df, ref_col) -> None:
super().__init__(df, ref_col)
def encode(self):
"""
"""
# initialize df with 0s-80s for age
age_labels = ["a0", "a10", "a20", "a30", "a40", "a50", "a60", "a70", "a80"]
# Define the age category ranges and corresponding labels
age_ranges = [0, 10, 20, 30, 40, 50, 60, 70, 80,90]
# Use pd.cut to assign age categories based on the specified ranges and labels
age_category = pd.cut(self.df[self.ref_col], bins=age_ranges, labels=age_labels, right=False)
for each in age_labels:
self.df[each] = np.where(age_category == each, 1, 0)
return self.df
class SmokingStatusEncoder(EncoderInterface):
def __init__(self, df, ref_col) -> None:
super().__init__(df, ref_col)
def encode(self):
cats = ["ss_1", "ss_2","ss_3", "ss_4"]
vals = ["smokes","never smoked", "formerly smoked", "Unknown"]
col_dict = {key:val for key,val in zip(cats,vals)}
for each in col_dict.keys():
self.df[each] = np.where(self.df[self.ref_col] == col_dict.get(each), 1, 0)
return self.df
#for gender marriage and residence - try to subclass (since they all behave the same)
class MarriageEncoder(EncoderInterface):
def __init__(self, df, ref_col) -> None:
super().__init__(df, ref_col)
def encode(self):
self.df["c_ever_married"] = np.where(self.df[self.ref_col] == "Yes", 1, 0)
return self.df
class HypertensionEncoder(EncoderInterface):
def __init__(self, df, ref_col) -> None:
super().__init__(df, ref_col)
def encode(self):
self.df["hypertension"] = np.where(self.df[self.ref_col] == "Yes", 1, 0)
return self.df
class HeartDiseaseEncoder(EncoderInterface):
def __init__(self, df, ref_col) -> None:
super().__init__(df, ref_col)
def encode(self):
self.df["heart_disease"] = np.where(self.df[self.ref_col] == "Yes", 1, 0)
class GenderEncoder(EncoderInterface):
def __init__(self, df, ref_col) -> None:
super().__init__(df, ref_col)
def encode(self):
self.df["is_male"] = np.where(self.df[self.ref_col] == "Male", 1, 0)
return self.df
class ResidenceEncoder(EncoderInterface):
def __init__(self, df, ref_col) -> None:
super().__init__(df, ref_col)
def encode(self):
self.df["live_urban"] = np.where(self.df[self.ref_col] == "Urban", 1, 0)
return self.df
class ChildBMIEncoder(EncoderInterface):
"""
Input:
weight_unit: lbs or kg
height_unit: (ft, in) or m
bmi_table: df reference table
data_table: df table with BMI to be converted
age: float or int
height: (int,int) or int
weight: float or int
"gender": "Male" or "Female"
Output:
df with encoded BMI categories
"""
def __init__(self, bmi_table, data_table):
self.bmi_table = bmi_table
self.data_table = data_table
def encode(self):
# Define a function to calculate Z
# Create an empty list to store Z values
bmi_buckets = []
# Iterate through each row in the data_table
for _, row in self.data_table.iterrows():
gender = 1 if row['gender'] == "Male" else 2
age = row["age"]
bmi = row['bmi']
# convert ages below 20 to age in months
age_in_months = age * 12
age = age_in_months + 0.5
# Get the relevant row from the bmi_table
lookup_row = self._get_row(gender, age)
bucket = self._bucket_child_bmi(bmi, lookup_row)
bmi_buckets.append(bucket)
# Add Z_values to the data_table and return as a new dataframe
self.data_table['bmi_buckets'] = bmi_buckets
return self.data_table
def _bucket_child_bmi(self, bmi, lookup_row):
c_under = bmi < lookup_row["P5"].item()
c_healthy = lookup_row["P5"].item() <= bmi < lookup_row["P85"].item()
c_over = lookup_row["P85"].item() <= bmi < lookup_row["P95"].item()
if c_under:
bmi_bucket = "under weight"
elif c_healthy:
bmi_bucket = "healthy weight"
elif c_over:
bmi_bucket = "over weight"
else:
bmi_bucket = "obese"
return bmi_bucket
def _get_row(self, gender, age):
"""
Used to lookup rows in bmi table.
Output:
Single row df.
"""
try:
age_mask = self.bmi_table["Agemos"] == age
gender_mask = self.bmi_table["Sex"] == gender
lookup_row = self.bmi_table[age_mask & gender_mask]
return lookup_row
except:
print("bmi_table dtypes should be int() or float()")
class AdultBMIEncoder(EncoderInterface):
"""
Input:
bmi_table: df reference table
data_table: df table with BMI to be converted
Output:
df with encoded BMI categories
"""
def __init__(self, data_table):
self.data_table = data_table
def encode(self):
# Create an empty list to store Z values
bmi_buckets = []
# Iterate through each row in the data_table
for _ , row in self.data_table.iterrows():
bmi = row['bmi']
bucket = self._bucket_adult_bmi(bmi)
bmi_buckets.append(bucket)
# # Add Z_values to the data_table and return as a new dataframe
self.data_table['bmi_buckets'] = bmi_buckets
return self.data_table
def _bucket_adult_bmi(self, bmi):
if bmi < 18.5:
bmi_bucket = "under weight"
elif 18.5 <= bmi <= 24.9:
bmi_bucket = "healthy weight"
elif 25.0 <= bmi <= 29.9:
bmi_bucket = "over weight"
else:
bmi_bucket = "obese"
return bmi_bucket
def one_hot_enc_bmi(df,ref_col):
cats = ["bmi_under", "bmi_healthy", "bmi_over", "bmi_obese"]
vals = ["under weight", "healthy weight", "over weight", "obese"]
col_dict = {key:val for key,val in zip(cats,vals)}
for each in col_dict.keys():
df[each] = np.where(df[ref_col] == col_dict.get(each), 1, 0)