python:pandas

Ceci est une ancienne révision du document !


Pandas

Le haut du dataframe :

df.head()

Le bas du dataframe :

df.tail()

Les colonnes dans un dataframe :

df.columns

Afficher tout le dataframe (source) :

print(df.to_markdown())  # il faut installer le paquet tabulate / python3-tabulate

ou bien :

pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
pd.set_option("display.width", None)

Pour afficher le dataframe en arrondissant :

print(df.round(2))

Avoir le nom des colonnes, lorsque la ligne qui les contient est considérée comme un commentaire:

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:]))

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.

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"]

Pour filtrer suivant si un élément est dans un ensemble (source) :

df = df[~df["Name"].isin(["a", "b", "c", "d"])]

Pour filtrer les valeurs None (source) :

df = df[df["Column"].isnull()]

Pour filtrer avec une fonction :

df_all = df[df["Parameter filename"].apply(lambda x: not x.startswith("a"))]

Supprimer les lignes avec des données manquantes

df.dropna()

On peut préciser dans quelles colonnes regarder s'il y des valeurs nulles :

df.dropna(subset=['Name'])

Changer les valeurs de données filtrées

Source

df.loc[df["Column A"]=="foo", "Column B"] = "bar"

Source

df['name'] = df['name'].apply(lambda s: s.replace("_STARPU_", "").replace("FUT_", ""))

Source

pandas.concat([s1, s2], axis=1).min(axis=1)
to_plot = df.sort_values(by=['name'])

S'il y a plusieurs niveaux de colonnes, il faut utiliser des tuples : by=[('Percentage', 'mean')].

ascending=False pour avoir un tri décroissant.

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])

On peut agréger sur plusieurs colonnes :

df.groupby(['n', 'm'])

Pour récupérer les valeurs des indexes (les valeurs sur lesquelles se font l'agrégation) :

# 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

Pour n'avoir qu'un niveau d'en-tête (source) :

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]

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 :

df.group("column").first()

Déciles

Source

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'])

Grouper en fusionnant les contenus des cellules

Source

# 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()

Pour concaténer des dataframes (source):

result = pd.concat([df1, df2])

Pour concaténer les colonnes :

df = pd.concat([df_a, df_b], axis=1, join="inner")

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.

Pour changer la colonne qui sert d'index

df.set_index("colonne", inplace=True)

Il possible de fournir une liste de colonnes.

# 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)

Supprimer la dernière colonne:

df.drop(df.columns[len(df.columns)-1], axis=1, inplace=True)
df_starts.rename(columns={"Time start": "Time"}, inplace=True)

Source

Si les valeurs de la colonne Configuration sont de la forme baseline.C.openmpi.linear.1 :

df[['Type', 'Size', 'MPI', 'Coll', 'Iter']] = df["Configuration"].str.split('.', expand=True)

Obtenir les valeurs uniques d'une colonne :

print(df["Comm ID"].sort_values().unique()

Obtenir les valeurs uniques d'une colonne et le nombre d’occurrences :

print(df[["WorkerId"]].value_counts())

Obtenir les couples uniques de deux colonnes :

threads = final_df[["Thread", "Core"]].value_counts().reset_index(name='count')
threads.drop(columns=["count"], inplace=True)

On peut aussi simplement utiliser (source) :

df[["Operation", "Datasize"]].drop_duplicates()

S'il n'a que deux colonnes, Thread et Core:

threads.set_index("Thread", inplace=True)
binding_thread_to_core = threads.to_dict()['Core']

Itérer sur les lignes d'un dataframe

for index, row in df.iterrows():
    print(row['column_a'])

Récupérer la valeur d'une cellule en particulier

value = df.at[0, "P"] # [numéro de ligne, nom de colonne]

Convertir en dictionnaire une unique ligne

assert(len(row) == 1)
row = row.squeeze().to_dict()

Sorte de transposées

Avec le dataframe suivant :

Rang Operation Valeur
0    A         12
0    B         13
1    A         14
1    B         15

Alors le code

df.pivot(index="Rang", columns="Operation", values="Valeur")

donnera le dataframe suivant :

Rang A  B
0    12 13
1    14 15

Pour connaître quelle est la proportion de valeurs qui sont inférieures à x (source) :

(df < x).astype(int).mean()
  • python/pandas.1693505799.txt.gz
  • Dernière modification : 2023/08/31 20:16
  • de phsw