[docs]@dataclassclassGrapheriser:location:str="location"date:str="date"date_ref:datetime=datetime(2020,1,21)fillna:bool=Falsefillna_0:bool=Truepivot_column:str=Nonepivot_values:str=Nonesuffixes:list=Nonefunction_input:Callable=lambdax:xfunction_output:Callable=lambdax:xcolumns_non_fillna_0:list=field(default_factory=lambda:[])@propertydefcolumns_metadata(self)->list:return["Country","Year"]@propertydefmetric2suffix(self)->dict:iflen(self.pivot_values_list)==len(self.suffixes_list):returndict(zip(self.pivot_values_list,self.suffixes_list))else:raiseValueError(f"`suffixes` and `pivot_values` should be lists of the same length")@propertydefpivot_values_list(self)->list:ifnotisinstance(self.pivot_values,list):return[self.pivot_values]returnself.pivot_values@propertydefsuffixes_list(self)->list:suffizes=self.suffixesifnotisinstance(self.suffixes,list):suffizes=[self.suffixes]return[""ifsisNoneelsesforsinsuffizes]@propertydefdo_pivot(self):returnself.pivot_columnisnotNoneandself.pivot_valuesisnotNone
[docs]defpipe_pivot(self,df:pd.DataFrame)->pd.DataFrame:"""Pivot values of columns of interest."""ifself.do_pivot:returndf.pivot(index=[self.location,self.date],columns=self.pivot_column,values=self.pivot_values_list,).reset_index()returndf
[docs]defpipe_metadata_columns(self,df:pd.DataFrame)->pd.DataFrame:"""Rename columns and convert date to Year grapher metric."""df=(df.rename(columns={self.location:"Country",}).assign(date=(df[self.date]-self.date_ref).dt.days).rename(columns={"date":"Year"})).copy()returndf
[docs]defpipe_normalize_columns(self,df):"""Normalize column names. If columns are multiindex (of length 2), use first and second positions to create new column name. This only applies if pivot has been done, i.e. `pivot_column` and `pivot_values` are not None. """def_normalize_column(column):iflen(column)!=2:raiseValueError("Column is expected to have length 2")ifcolumn[1]:column_new=f"{column[1]}{self.metric2suffix.get(column[0],'')}"else:column_new=column[0]returncolumn_newifself.do_pivot:df.columns=[_normalize_column(xx)forxxindf.columns]returndf
[docs]defpipe_order_columns(self,df:pd.DataFrame)->pd.DataFrame:"""Re-order the columns of the dataframe. First columns are [Country, Year] """col_order=self.columns_metadata+self.columns_data(df)df=df[col_order].sort_values(col_order)returndf