Я очень новичок в ООП и хочу начать привычку писать модульный, многократно используемый код.Извините за стену кода и текста, просто пытаюсь дать как можно больше контекста и быть максимально понятным.
Я определил ряд функций, все они действуют на панде DataFrame, и я хочу создатькласс из этой серии функций.Я подумал, что было бы неплохо создать класс, потому что я буду использовать этот код на фреймах данных, которые довольно стандартны в будущем.
У меня двоякий вопрос: 1. Должен ли я использовать концепции ООП и дизайн дляэта проблема 2. Что, черт возьми, вызывает мой проклятый код?!
Заранее спасибо всем!
Ниже приведены функции, которые я определил:
def __describe(df, col):
df_desc = df[col].describe()
return df_desc
def __sort_by_character_study_day(df):
new_index_values = df.index.levels[0].str.split().str[-1].astype(int)
df.index = df.index.set_levels(new_index_values, level='study_day')
df = df.sort_index()
return df
def change_from_baseline(df, col):
df_sorted = sort_df(df = df, by = ["Animal_id", "ord"])
groupedf = grouper(df=df_sorted, by='Animal_id')
df_sorted['Change From Baseline'] = df_sorted[col] - groupedf[col].transform('first')
df_sorted['Percent Change From Baseline'] = (df_sorted['Change From Baseline'] / groupedf[col].transform('first')).round(4) * 100
return df_sorted
def grouper(df, by):
df = df.groupby(by)
return df
def sns_box_plot(df, col, y_lab):
plt.subplots(figsize=(12,8))
sns.set_style("whitegrid")
g = sns.boxplot(x="study_day", y = col, hue="group_c",
data = df, palette='rainbow',
hue_order=["Group 1", "Group 2", "Group 3"])
plt.ylabel(y_lab, fontsize=20)
plt.xlabel("Study Day", fontsize=20)
plt.tick_params('both', labelsize='14')
plt.show()
def sns_bar_plot(df, col, y_lab):
plt.subplots(figsize=(12,8))
sns.set_style("whitegrid")
g = sns.barplot(x="study_day", y = col, hue="group_c",
data = df, palette='rainbow')
plt.ylabel(y_lab, fontsize=20)
plt.xlabel("Study Day", fontsize=20)
plt.tick_params('both', labelsize='14')
plt.show()
def sort_df(df, by):
df = df.sort_values(by)
return df
def summary_stats(df, by, col):
dfgrouped = grouper(df, by)
df_desc = __describe(dfgrouped, col)
df_summ = pd.DataFrame()
df_summ["count"] = df_desc['count']
df_summ["mean"] = df_desc['mean'].round(2).astype(str)
df_summ["std"] = df_desc['std'].round(2).astype(str)
df_summ["25%"] = df_desc['25%'].round(2).astype(str)
df_summ["50%"] = df_desc['50%'].round(2).astype(str)
df_summ["75%"] = df_desc['75%'].round(2).astype(str)
df_summ["min"] = df_desc['min'].round(2).astype(str)
df_summ["max"] = df_desc['max'].round(2).astype(str)
return __sort_by_character_study_day(df_summ)
def summary_stat_formatted(df, by, col):
data_summ = summary_stats(df, by, col)
formatted_summ = pd.DataFrame()
formatted_summ["Number of Observations"] = data_summ['count'].astype(int)
formatted_summ["Mean (SD)"] = data_summ["mean"] +' (' + data_summ["std"] +')'
formatted_summ["Median (25th - 75th %ile)"] = data_summ["50%"] + ' (' + data_summ["25%"] +' ,' + data_summ["75%"] +')'
formatted_summ["Min, Max"] = data_summ["min"] +' ,' + data_summ["max"]
return formatted_summ
def write_to_excel(df, outfile, sheetname):
writer = pd.ExcelWriter(outfile, engine='xlsxwriter')
df.to_excel(writer, sheet_name=sheetname)
Когда я вызываю одну из функций, скажем:
summary_stats(df=bw, by= ["study_day", "group_c"], col='Body_Weight')
Все работает как положено, я получаю следующий вывод: 
Теперь, так как я будуиспользовать те же функции на почти идентичных фреймах данных (отличается только имя фрейма данных и столбца анализа), я подумал, что было бы неплохо создать класс (, пожалуйста, дайте мне знать, если это правильноподход ).Мой класс выглядит так:
class PreClinicalData(object):
def __init__(self, df):
self.df = df
def __describe(self, col):
df_desc = self.df[col].describe()
return df_desc
def __sort_by_character_study_day(self):
new_index_values = self.df.index.levels[0].str.split().str[-1].astype(int)
self.df.index = self.df.index.set_levels(new_index_values, level='study_day')
self.df = self.df.sort_index()
return self.df
def change_from_baseline(self, col):
df_sorted = self.sort_df(df = self.df, by = ["Animal_id", "ord"])
groupedf = self.grouper(df=df_sorted, by='Animal_id')
df_sorted['Change From Baseline'] = df_sorted[col] - groupedf[col].transform('first')
df_sorted['Percent Change From Baseline'] = (df_sorted['Change From Baseline'] / groupedf[col].transform('first')).round(4) * 100
return df_sorted
def summary_stats(self, by, col):
dfgrouped = self.grouper(df=self.df, by=by)
df_desc = self.__describe(dfgrouped, col=col)
df_summ = pd.DataFrame()
df_summ["count"] = df_desc['count']
df_summ["mean"] = df_desc['mean'].round(2).astype(str)
df_summ["std"] = df_desc['std'].round(2).astype(str)
df_summ["25%"] = df_desc['25%'].round(2).astype(str)
df_summ["50%"] = df_desc['50%'].round(2).astype(str)
df_summ["75%"] = df_desc['75%'].round(2).astype(str)
df_summ["min"] = df_desc['min'].round(2).astype(str)
df_summ["max"] = df_desc['max'].round(2).astype(str)
return self.__sort_by_character_study_day(df_summ)
def summary_stat_formatted(self, by, col):
data_summ = self.summary_stats(self, by, col)
formatted_summ = pd.DataFrame()
formatted_summ["Number of Observations"] = data_summ['count'].astype(int)
formatted_summ["Mean (SD)"] = data_summ["mean"] +' (' + data_summ["std"] +')'
formatted_summ["Median (25th - 75th %ile)"] = data_summ["50%"] + ' (' + data_summ["25%"] +' ,' + data_summ["75%"] +')'
formatted_summ["Min, Max"] = data_summ["min"] +' ,' + data_summ["max"]
return formatted_summ
def write_to_excel(self, outfile, sheetname):
writer = pd.ExcelWriter(outfile, engine='xlsxwriter')
self.df.to_excel(writer, sheet_name=sheetname)
def grouper(self, by):
return self.df.groupby(by)
def sns_box_plot(self, col, y_lab):
plt.subplots(figsize=(12,8))
sns.set_style("whitegrid")
g = sns.boxplot(x="study_day", y = col, hue="group_c",
data = self.df, palette='rainbow',
hue_order=["Group 1", "Group 2", "Group 3"])
plt.ylabel(y_lab, fontsize=20)
plt.xlabel("Study Day", fontsize=20)
plt.tick_params('both', labelsize='14')
plt.show()
def sns_bar_plot(self, col, y_lab):
plt.subplots(figsize=(12,8))
sns.set_style("whitegrid")
g = sns.barplot(x="study_day", y = col, hue="group_c",
data = self.df, palette='rainbow')
plt.ylabel(y_lab, fontsize=20)
plt.xlabel("Study Day", fontsize=20)
plt.tick_params('both', labelsize='14')
plt.show()
def sort_df(self, by):
return self.df.sort_values(by)
def summary_stats(self, by, col):
dfgrouped = self.grouper(self, by)
df_desc = self.__describe(dfgrouped, col)
df_summ = pd.DataFrame()
df_summ["count"] = df_desc['count']
df_summ["mean"] = df_desc['mean'].round(2).astype(str)
df_summ["std"] = df_desc['std'].round(2).astype(str)
df_summ["25%"] = df_desc['25%'].round(2).astype(str)
df_summ["50%"] = df_desc['50%'].round(2).astype(str)
df_summ["75%"] = df_desc['75%'].round(2).astype(str)
df_summ["min"] = df_desc['min'].round(2).astype(str)
df_summ["max"] = df_desc['max'].round(2).astype(str)
return self.__sort_by_character_study_day(df_summ)
def summary_stat_formatted(self, by, col):
data_summ = self.summary_stats(self, by, col)
formatted_summ = pd.DataFrame()
formatted_summ["Number of Observations"] = data_summ['count'].astype(int)
formatted_summ["Mean (SD)"] = data_summ["mean"] +' (' + data_summ["std"] +')'
formatted_summ["Median (25th - 75th %ile)"] = data_summ["50%"] + ' (' + data_summ["25%"] +' ,' + data_summ["75%"] +')'
formatted_summ["Min, Max"] = data_summ["min"] +' ,' + data_summ["max"]
return formatted_summ
def write_to_excel(self, outfile, sheetname):
writer = pd.ExcelWriter(outfile, engine='xlsxwriter')
self.df.to_excel(writer, sheet_name=sheetname)
Я могу создать экземпляр класса следующим образом:
bodyweight = PreClinicalData(chickv_data['bodyweight'])
И я могу вызвать DataFrame и использовать метод head()
просто отлично.:
bodyweight.df.head()
Теперь, когда я вызываю тот же метод, как показано выше ... я получаю следующее:
bodyweight.summary_stats(by = ["study_day", "group_c"], col = "Body_Weight")
, что приводит к следующей ошибке:

Понятия не имею, откуда берутся эти три предполагаемых аргумента ?!