Afficher la pageAnciennes révisionsLiens de retourHaut de page Cette page est en lecture seule. Vous pouvez afficher le texte source, mais ne pourrez pas le modifier. Contactez votre administrateur si vous pensez qu'il s'agit d'une erreur. ====== Pandas ====== * [[https://berthub.eu/articles/posts/from-gnuplot-to-matplotlib-pandas/]] ==== Informations sur un dataframe ==== Le haut du dataframe : <code python> df.head() </code> Le bas du dataframe : <code python> df.tail() </code> Les colonnes dans un dataframe : <code python> df.columns </code> Afficher tout le dataframe ([[https://www.geeksforgeeks.org/how-to-print-an-entire-pandas-dataframe-in-python/|source]]) : <code python> print(df.to_markdown()) # il faut installer le paquet tabulate / python3-tabulate </code> ou bien : <code python> pd.set_option("display.max_columns", None) pd.set_option("display.max_rows", None) pd.set_option("display.width", None) </code> Pour afficher le dataframe en arrondissant : <code python> print(df.round(2)) </code> ==== Lire des fichiers ==== * [[https://www.statology.org/pandas-read-text-file/]] * https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html Avoir le nom des colonnes, lorsque la ligne qui les contient est considérée comme un commentaire: <code python> h = pd.read_csv(f, skiprows=6, nrows=1, delim_whitespace=True, header=None) df = pd.read_csv(f, delim_whitespace=True, comment="#", header=None, names=list(h.loc[0,1:])) </code> Si les deux premières lignes servent d'en-tête: ''header=[0, 1]''; on peut ensuite accéder aux colonnes avec ''df[("level0", "level1")]''. On peut préciser le séparateur avec le paramètre ''sep''. Le paramètre ''usecols'' prend une liste de noms ou index de colonnes à conserver dans le dataframe. ==== Filtrer les données ==== <code python> to_plot = data[f][(data[f]['n.nodes']==max_nb_nodes) & (data[f]['length']>=1024)] cholesky = df[~(df['Function']=="FxT")] fxt = df[df['Function']=="FxT"] </code> Pour filtrer suivant si un élément est dans un ensemble ([[https://stackoverflow.com/questions/19960077/how-to-filter-pandas-dataframe-using-in-and-not-in-like-in-sql|source]]) : <code python> df = df[~df["Name"].isin(["a", "b", "c", "d"])] </code> Pour filtrer les valeurs ''None'' ([[https://stackoverflow.com/questions/45117272/pandas-filtering-none-values|source]]) : <code python> df = df[df["Column"].isnull()] </code> Pour filtrer avec une fonction : <code python> df_all = df[df["Parameter filename"].apply(lambda x: not x.startswith("a"))] </code> === Supprimer les lignes avec des données manquantes === * https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.dropna.html <code python> df.dropna() </code> On peut préciser dans quelles colonnes regarder s'il y des valeurs nulles : <code python> df.dropna(subset=['Name']) </code> === Changer les valeurs de données filtrées === [[https://stackoverflow.com/questions/38876816/change-value-of-a-dataframe-column-based-on-a-filter|Source]] <code python> df.loc[df["Column A"]=="foo", "Column B"] = "bar" </code> ==== Appliquer une fonction sur une colonne === [[https://stackoverflow.com/questions/42529454/using-map-for-columns-in-a-pandas-dataframe|Source]] <code python> df['name'] = df['name'].apply(lambda s: s.replace("_STARPU_", "").replace("FUT_", "")) </code> ==== Minimum ligne par ligne de deux colonnes ==== [[https://stackoverflow.com/questions/16989946/creating-an-element-wise-minimum-series-from-two-other-series-in-python-pandas|Source]] <code python> pandas.concat([s1, s2], axis=1).min(axis=1) </code> ==== Trier ==== <code python> to_plot = df.sort_values(by=['name']) </code> S'il y a plusieurs niveaux de colonnes, il faut utiliser des tuples : ''by=[('Percentage', 'mean')]''. ''ascending=False'' pour avoir un tri décroissant. ==== Agréger ==== <code python> stats = df.groupby('n').agg({"gflops": ["median", "min", "max"]}) print(stats['gflops']['median']) # S'il n'y a qu'une seule valeur: print(stats['gflops']['median'].values[0]) </code> On peut agréger sur plusieurs colonnes : <code python> df.groupby(['n', 'm']) </code> Pour récupérer les valeurs des indexes (les valeurs sur lesquelles se font l'agrégation) : <code python> # agrégation sur une valeur : s.index # agrégation sur plusieurs valeurs : s.index.get_level_index(0) # première valeur s.index.get_level_index(1) # deuxième valeur </code> Pour n'avoir qu'un niveau d'en-tête ([[https://stackoverflow.com/questions/14507794/how-to-flatten-a-hierarchical-index-in-columns/55757002|source]]) : <code python> df = df.groupby(["Parameter filename", "Comm size", "Msg size"]).agg({"Collective duration": ["max"]}).reset_index() df.columns = [i for i, _ in df.columns] # ou : df.columns = [' '.join(col).strip() for col in df.columns.values] </code> Liste des fonctions d’agrégation possibles: [[https://cmdlinetips.com/2019/10/pandas-groupby-13-functions-to-aggregate/]] Obtenir la première ligne de chaque groupe : <code python> df.group("column").first() </code> === Déciles === [[https://stackoverflow.com/a/54593214|Source]] <code python> def percentile(n): def percentile_(x): return x.quantile(n) percentile_.__name__ = 'percentile_{:2.0f}'.format(n*100) return percentile_ stats = df.groupby('n').agg({"gflops": ["median", percentile(0.1)]}) print(stats['gflops']['percentile_10']) </code> === Grouper en fusionnant les contenus des cellules === [[https://stackoverflow.com/questions/36392735/how-to-combine-multiple-rows-into-a-single-row-with-pandas|Source]] <code python> # On groupe par le contenu de la colonne A, puis les différents contenus des cellules dans la colonne B de chaque groupe sont concaténés dans une seule cellule, ce qui donne une ligne par groupe : df.groupby("Column A")["Column B"].apply(" ".join).reset_index() </code> ==== Concaténer ==== Pour concaténer des dataframes ([[https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html#__do_not_save__|source]]): <code python> result = pd.concat([df1, df2]) </code> Pour concaténer les colonnes : <code python> df = pd.concat([df_a, df_b], axis=1, join="inner") </code> Il faut être sûr que les indexes soient les mêmes dans les deux dataframes. L'utilisation de ''join="inner"'' permet de ne pas garder les lignes avec des indexes qui ne correspondent pas dans les deux dataframes. ==== Changer la colonne d'index ==== Pour changer la colonne qui sert d'index <code python> df.set_index("colonne", inplace=True) </code> Il possible de fournir une liste de colonnes. ==== Supprimer des colonnes ==== <code python> # UPI2 est une sous-colonne de la colonne "System": df.drop(columns=["System"], level=0, inplace=True) df.drop(columns=["UPI2"], level=1, inplace=True) </code> Supprimer la dernière colonne: <code python> df.drop(df.columns[len(df.columns)-1], axis=1, inplace=True) </code> ==== Renommer des colonnes ==== <code python> df_starts.rename(columns={"Time start": "Time"}, inplace=True) </code> Pour des colonnes qui n'avaient initialement pas de nom : <code python> df.columns = ["A", "B", "C"] </code> ==== Éclater une colonne textuelle en plusieurs colonnes ==== [[https://stackoverflow.com/questions/14745022/how-to-split-a-dataframe-string-column-into-two-columns|Source]] Si les valeurs de la colonne ''Configuration'' sont de la forme ''baseline.C.openmpi.linear.1'' : <code python> df[['Type', 'Size', 'MPI', 'Coll', 'Iter']] = df["Configuration"].str.split('.', expand=True) </code> ==== Valeurs uniques ==== Obtenir les valeurs uniques d'une colonne : <code python> print(df["Comm ID"].sort_values().unique() </code> Obtenir les valeurs uniques d'une colonne et le nombre d’occurrences : <code python> print(df[["WorkerId"]].value_counts()) </code> Obtenir les couples uniques de deux colonnes : <code python> threads = final_df[["Thread", "Core"]].value_counts().reset_index(name='count') threads.drop(columns=["count"], inplace=True) </code> On peut aussi simplement utiliser ([[https://stackoverflow.com/questions/47364539/get-unique-pairs-of-columns-of-a-pandas-dataframe|source]]) : <code python> df[["Operation", "Datasize"]].drop_duplicates() </code> ==== Convertir un dataframe en dictionnaire ==== S'il n'a que deux colonnes, ''Thread'' et ''Core'': <code python> threads.set_index("Thread", inplace=True) binding_thread_to_core = threads.to_dict()['Core'] </code> ==== Récupérer les données d'un dataframe ==== === Itérer sur les lignes d'un dataframe === <code python> for index, row in df.iterrows(): print(row['column_a']) </code> === Récupérer la valeur d'une cellule en particulier === <code python> value = df.at[0, "P"] # [numéro de ligne, nom de colonne] </code> === Convertir en dictionnaire une unique ligne === <code python> assert(len(row) == 1) row = row.squeeze().to_dict() </code> ==== Transformations sur les dataframes ==== === Sorte de transposées === Avec le dataframe suivant : <code> Rang Operation Valeur 0 A 12 0 B 13 1 A 14 1 B 15 </code> Alors le code <code python> df.pivot(index="Rang", columns="Operation", values="Valeur") </code> donnera le dataframe suivant : <code> Rang A B 0 12 13 1 14 15 </code> ==== Fonction inverse d'un percentile ==== Pour connaître quelle est la proportion de valeurs qui sont inférieures à ''x'' ([[https://stackoverflow.com/questions/26489134/whats-the-inverse-of-the-quantile-function-on-a-pandas-series|source]]) : <code python> (df < x).astype(int).mean() </code> python/pandas.txt Dernière modification : 2023/10/30 12:26de phsw