Maison > Périphériques technologiques > IA > Deux bons conseils pour améliorer l'efficacité de votre code Pandas

Deux bons conseils pour améliorer l'efficacité de votre code Pandas

王林
Libérer: 2024-01-18 20:12:05
avant
1085 Les gens l'ont consulté

Si vous avez déjà utilisé Pandas avec des données tabulaires, vous connaissez peut-être le processus d'importation des données, de nettoyage et de transformation, puis de leur utilisation comme entrée dans le modèle. Cependant, lorsque vous devez faire évoluer et mettre votre code en production, votre pipeline Pandas commencera très probablement à planter et à fonctionner lentement. Dans cet article, je partagerai 2 conseils pour vous aider à accélérer l'exécution du code Pandas, à améliorer l'efficacité du traitement des données et à éviter les pièges courants.

Deux bons conseils pour améliorer lefficacité de votre code Pandas

Astuce 1 : Opérations de vectorisation

Dans Pandas, les opérations de vectorisation sont un outil efficace qui peut traiter les colonnes de l'ensemble du bloc de données de manière plus concise sans boucler ligne par ligne.

Comment ça marche ?

La diffusion est un élément clé de la manipulation vectorisée, permettant de manipuler intuitivement des objets de formes différentes.

eg1 : Un tableau a avec 3 éléments est multiplié par un scalaire b, ce qui donne un tableau de même forme que Source.

Deux bons conseils pour améliorer lefficacité de votre code Pandas

eg2 : Lors de l'opération d'addition, ajoutez le tableau a avec la forme (4,1) et le tableau b avec la forme (3,). Le résultat sera un tableau avec la forme (4,3).

Deux bons conseils pour améliorer lefficacité de votre code Pandas

De nombreux articles ont abordé ce sujet, notamment dans le domaine de l'apprentissage profond où les multiplications matricielles à grande échelle sont courantes. Cet article présentera deux brefs exemples.

Tout d’abord, disons que vous souhaitez compter le nombre de fois qu’un entier donné apparaît dans une colonne. Voici 2 méthodes possibles.

"""计算DataFrame X 中 "column_1" 列中等于目标值 target 的元素个数。参数:X: DataFrame,包含要计算的列 "column_1"。target: int,目标值。返回值:int,等于目标值 target 的元素个数。"""# 使用循环计数def count_loop(X, target: int) -> int:return sum(x == target for x in X["column_1"])# 使用矢量化操作计数def count_vectorized(X, target: int) -> int:return (X["column_1"] == target).sum()
Copier après la connexion

Supposons maintenant que vous ayez un DataFrame avec une colonne de date et que vous souhaitiez le décaler d'un nombre de jours donné. Le calcul utilisant des opérations vectorisées est le suivant :

def offset_loop(X, days: int) -> pd.DataFrame:d = pd.Timedelta(days=days)X["column_const"] = [x + d for x in X["column_10"]]return Xdef offset_vectorized(X, days: int) -> pd.DataFrame:X["column_const"] = X["column_10"] + pd.Timedelta(days=days)return X
Copier après la connexion

Astuce 2 : Itérer

"boucle for"

La première et la plus intuitive façon d'itérer est d'utiliser une boucle for Python.

def loop(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:res = []i_remove_col = df.columns.get_loc(remove_col)i_words_to_remove_col = df.columns.get_loc(words_to_remove_col)for i_row in range(df.shape[0]):res.append(remove_words(df.iat[i_row, i_remove_col], df.iat[i_row, i_words_to_remove_col]))return result
Copier après la connexion

「apply」

def apply(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:return df.apply(func=lambda x: remove_words(x[remove_col], x[words_to_remove_col]), axis=1).tolist()
Copier après la connexion

À chaque itération de df.apply, la fonction appelable fournie obtient une série dont l'index est df.columns et dont les valeurs sont des lignes. Cela signifie que les pandas doivent générer la séquence dans chaque boucle, ce qui coûte cher. Pour réduire les coûts, il est préférable d'appeler apply sur un sous-ensemble de df que vous savez que vous utiliserez, comme ceci :

def apply_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:return df[[remove_col, words_to_remove_col]].apply(func=lambda x: remove_words(x[remove_col], x[words_to_remove_col]), axis=1)
Copier après la connexion

「Combinaison de listes + itertuples」

Il est définitivement préférable d'itérer en utilisant des itertuples combinés avec des listes. itertuples génère des tuples (nommés) avec des données de ligne.

def itertuples_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:return [remove_words(x[0], x[1])for x in df[[remove_col, words_to_remove_col]].itertuples(index=False, name=None)]
Copier après la connexion

「Combinaison liste + zip」

zip accepte un objet itérable et génère un tuple, où le i-ième tuple contient tous les i-ième éléments de l'objet itérable donné dans l'ordre.

def zip_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:return [remove_words(x, y) for x, y in zip(df[remove_col], df[words_to_remove_col])]
Copier après la connexion

「Combinaison liste + to_dict」

def to_dict_only_used_columns(df: pd.DataFrame) -> list[str]:return [remove_words(row[remove_col], row[words_to_remove_col])for row in df[[remove_col, words_to_remove_col]].to_dict(orient="records")]
Copier après la connexion

「Caching」

En plus des techniques itératives dont nous avons parlé, deux autres méthodes peuvent aider à améliorer les performances du code : la mise en cache et la parallélisation. La mise en cache est particulièrement utile si vous appelez plusieurs fois une fonction pandas avec les mêmes paramètres. Par exemple, si remove_words est appliqué à un ensemble de données comportant de nombreuses valeurs en double, vous pouvez utiliser functools.lru_cache pour stocker les résultats de la fonction et éviter de les recalculer à chaque fois. Pour utiliser lru_cache, ajoutez simplement le décorateur @lru_cache à la déclaration de remove_words, puis appliquez la fonction à votre ensemble de données en utilisant votre méthode d'itération préférée. Cela peut améliorer considérablement la vitesse et l’efficacité de votre code. Prenons le code suivant comme exemple :

@lru_cachedef remove_words(...):... # Same implementation as beforedef zip_only_used_cols_cached(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:return [remove_words(x, y) for x, y in zip(df[remove_col], df[words_to_remove_col])]
Copier après la connexion

L'ajout de ce décorateur génère une fonction qui "se souvient" de la sortie de l'entrée précédemment rencontrée, éliminant ainsi le besoin de réexécuter tout le code.

"Parallélisation"

Le dernier atout est d'utiliser pandarallel pour paralléliser nos appels de fonction sur plusieurs blocs df indépendants. L'outil est facile à utiliser : il vous suffit de l'importer et de l'initialiser, puis de remplacer tous les .applys par .parallel_applys.

from pandarallel import pandarallelpandarallel.initialize(nb_workers=min(os.cpu_count(), 12))def parapply_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:return df[[remove_col, words_to_remove_col]].parallel_apply(lambda x: remove_words(x[remove_col], x[words_to_remove_col]), axis=1)
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:51cto.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal