Source code for pydiana.tools.dataframe_manip

import pandas as pd
import numpy as np
import warnings

[docs] def find_row(df,index): """ Function for finding the row that has the content of 'index' as index (used mainly for non-numerical indexes Parameters ---------- df : pandas dataframe index : index content to be found Returns ------- Row number or None if failed """ if isinstance(index,int): if index<len(df): return index indexlist = np.array(df.index) i = np.where(indexlist==index)[0] if len(i)>1: warnings.warn("Multiple matches found") return None if len(i)<1: warnings.warn("No matches found") return None return i[0]
[docs] def dataframe_insert(df1,df2,row=0): """ Function for inserting a pandas dataframe in another dataframe at a certain row Parameters ---------- df1 : dataframe to be inserted df2 : dataframe that hosts the insertions row : index of the row of insertion Returns ------- Modified dataframe or None if failed """ row = find_row(df1,row) return pd.concat((df1[:row],df2,df1[row:]))
[docs] def pandas_row_swap(df,i,j): """ Function for easy pandas dataframe row swapping Parameters ---------- df : pandas dataframe i : first index to swap (either int to indicate row or elemend of the index column) j : second index to swap (either int to indicate row or elemend of the index column) Returns ------- Modified Dataframe or None if failed """ i = find_row(df,i) j = find_row(df,j) if i>len(df) or j >len(df): warnings.warn("Indexes out of range") return None if i==j: return df i,j=(min((i,j)),max((i,j))) first_part = np.arange(0,i,dtype=int) middle_part = np.arange(i+1,j,dtype=int) second_part = np.arange(j+1,len(df),dtype=int) neworder = np.concatenate((first_part,[j],middle_part,[i],second_part)) indexlist = np.array(df.index) return df.reindex(indexlist[neworder])
[docs] def multi_display(df, *args, **kwargs): """ Display one or more pandas data frames (usefull because display(list) is not implemented Parameters ---------- df : single/list/dict of Pandas data frame to be printed *args, **kwargs : additional parameters for display function Returns ---------- None """ if isinstance(df, pd.DataFrame): display(df, *args, **kwargs) elif isinstance(df,list) : for a in df: if isinstance(a, pd.DataFrame): display(a, *args, **kwargs) elif isinstance(df,dict) : for a in df: if isinstance(df[a], pd.DataFrame): print(a) display(df[a], *args, **kwargs) else : raise TypeError("TypeError: no DataFrame passed to the function") return None
[docs] def extract_fit_dataframe_columns(fit_res, *labels2extract, points2skip:dict=None, getError:bool=True,output_col_names=None,compress:bool=False): """ Extract gaussians fit results into a Pandas dataframe (both values and errors by default); first label2extract determines the order of points2skip (for example put "Mean" first if you want to use it as reference) Parameters ---------- fit_res (dict) : dict of Pandas dataframes containing fit results labels2extract : str or list of str (for example "Mean" and/or "StdDev") points2skip (dict) : dictionary with the same keys as fit_res containing a list with the index of the points to be skipped getError (bool) : extract or not the error associated with all labels2extract output_col_names : new names to be given to output dataframe. If None the default names are given, if list the names are substituted in order as present in the dataframe. If dict then it is a 1 to 1 mapping of the column names. If less names are provided then only the specified columns will be overwritten. Returns ---------- result : Pandas dataframe with labels2extract as columns (with errors or not) """ #check if labels2extract is a string or a list of strings if isinstance(labels2extract,str) : vars2get = [labels2extract] elif isinstance(labels2extract,tuple) : if all([isinstance(a,str) for a in labels2extract]) : vars2get = labels2extract else : raise TypeError("Not all labels2extract given are strings, aborting...") else : raise TypeError("Not a string or a list of strings is given as labels2extract, aborting...") if not isinstance(fit_res,dict): fit_res = {'total_res':fit_res} #define a 2D array useful for local data management result = {k : pd.DataFrame() for k in fit_res} manager = {k:{var : [] for var in vars2get} for k in fit_res} for k in fit_res: gaus = fit_res[k] # gaus is a pandas dataframe gaus = gaus.reset_index() for var in vars2get: indexes = [i for i,s in enumerate(gaus['Variables'].tolist()) if var in s] manager[k][var] = gaus.iloc[indexes] col2drop =[c for c in list(manager[k][var].columns) if c not in ['Values','Errors']] renames ={'Values':var,'Errors':'err_'+var} if not getError: col2drop.append('Errors') renames ={'Values':var} manager[k][var] = manager[k][var].drop(columns=col2drop) manager[k][var] = manager[k][var].rename(columns=renames) manager[k][var].reset_index(inplace=True,drop=True) df = pd.DataFrame() for var in manager[k]: for cc in manager[k][var].columns: df[cc] = manager[k][var][cc] manager[k] = df manager[k] = manager[k].sort_values(vars2get[0], ignore_index=True) # skip points if it's not None if points2skip is not None: [manager[k].drop(points2skip[k],inplace=True) for k in points2skip] if output_col_names is not None: if isinstance(output_col_names,list): cc = list(manager[k].columns) output_col_names = {cc[i]:output_col_names[i] for i in range(min((len(cc),len(output_col_names))))} for k in manager: manager[k]= manager[k].rename(columns=output_col_names) if 'total_res' in list(manager.keys()): manager = manager['total_res'] if compress and isinstance(manager,dict): res= pd.DataFrame() for cc in manager: tmp = manager[cc] tmp['Labels'] = [cc]*len(tmp) res = pd.concat([res,tmp]) manager = res.set_index('Labels') return manager