3 votes

Accéder au cadre de données précédent lors de l'enchaînement de méthodes pandas

Enchaînement de méthodes est un moyen connu d'améliorer la lisibilité du code et est souvent désigné comme une API fluide [ 1 , 2 ]. Pandas supporte cette approche car plusieurs appels de méthodes peuvent être enchaînés comme :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd

d = {'col1': [1, 2, 3, 4], 'col2': [5, np.nan, 7, 8], 'col3': [9, 10, 11, np.nan], 'col4': [np.nan, np.nan, np.nan, np.nan]}

df = (
    pd
    .DataFrame(d)
    .set_index('col1')
    .drop(labels='col3', axis=1)
)

print(df)

Comment puis-je utiliser le chaînage de méthodes si j'ai besoin d'accéder aux attributs du DataFrame renvoyé par l'appel de fonction précédent ? Pour être plus précis, j'ai besoin d'appeler .dropna() sur un sous-ensemble de colonnes. Comme le DataFrame est généré à partir de pd.concat() les noms exacts des colonnes ne sont pas connus a priori. C'est pourquoi j'utilise actuellement une approche en deux étapes comme celle-ci :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd

d_1 = {'col1': [1, 2, 3, 4], 'col2': [5, np.nan, 7, 8], 'col3': [9, 10, 11, np.nan], 'col4': [np.nan, np.nan, np.nan, np.nan]}
d_2 = {'col10': [10, 20, 30, 40], 'col20': [50, np.nan, 70, 80], 'col30': [90, 100, 110, np.nan]}

df_1 = pd.DataFrame(d_1)
df_2 = pd.DataFrame(d_2)

df = pd.concat([df_1, df_2], axis=1)
print(df)

dropped = df.dropna(how='any', subset=[c for c in df.columns if c != 'col4'])
print(dropped)

Existe-t-il une méthode plus élégante basée sur le chaînage de méthodes ? .dropna() peuvent certainement être enchaînées, mais je n'ai pas trouvé de moyen d'accéder aux noms des colonnes du DataFrame résultant de la précédente méthode pd.concat() . J'imagine quelque chose comme

# pseudo-code
dropped = (
    pd
    .concat([df_1, df_2], axis=1)
    .dropna(how='any', subset=<access columns of dataframe returned from previous concat and ignore desired column>)
)
print(dropped)

mais n'a pas trouvé de solution. L'efficacité de la mémoire pourrait être améliorée en utilisant .dropna() avec le inplace=True pour réaffecter la variable sur place. Toutefois, la lisibilité de l'enchaînement des méthodes n'est pas améliorée.

2voto

mozway Points 233

Utilice pipe :

dropped = (
    pd
    .concat([df_1, df_2], axis=1)
    .pipe(lambda d: d.dropna(how='any',
                             subset=[c for c in d.columns if c != 'col4']))
)

de la production :

   col1  col2  col3  col4  col10  col20  col30
0     1   5.0   9.0   NaN     10   50.0   90.0
2     3   7.0  11.0   NaN     30   70.0  110.0

NB. syntaxe alternative pour le dropna :

lambda d: d.dropna(how='any', subset=d.columns.difference(['col4']))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X