J'ai un Dataframe appelé df_base
qui ressemble à ceci. Comme vous pouvez le voir, il existe une colonne intitulée Sex
qui est masculin
ou féminin
. Je veux mapper ces valeurs à 0 et 1, respectivement.
+---------+---------+ | Old Sex | New Sex | +---------+---------+ | male | 0 | | female | 1 | | female | 1 | | female | 1 | | male | 0 | +---------+---------+
Il y a quelques méthodes que j'ai vues sur StackOverflow mais je me demande quelle est la plus efficace pour effectuer le mappage suivant:
+---+-------------+----------+--------+---------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ | | PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | +---+-------------+----------+--------+---------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ | 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | NaN | S | | 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | | 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | NaN | S | | 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S | | 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | NaN | S | +---+-------------+----------+--------+---------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+
J'utilise ceci:
df_base ['Sex']. replace (['male', 'female '], [0,1], inplace = True)
... mais je ne peux pas m'empêcher de penser que c'est un peu de mauvaise qualité. Existe-t-il une meilleure façon de le faire? Il y a aussi l'utilisation de .loc
mais qui boucle autour des lignes du Dataframe, est donc moins efficace, non?
3 Réponses :
Je pense que voici une utilisation meilleure / plus rapide carte par dictionnaire si seuls homme
et femme
existent dans la colonne Sex
:
perfplot.show( setup=make_df, kernels=[ma, rep1, nwhere, mask1, mask2], n_range=[2**k for k in range(2, 18)], logx=True, logy=True, equality_check=False, # rows may appear in different order xlabel='len(df)')
Une autre solution que vous pouvez utiliser avec np.where
:
Juste un exemple de DataFrame:
>>> df['new_Sex'] = np.where(df['Sex'] != 'male', 1, 0) >>> df Sex new_Sex 0 male 0 1 female 1 2 female 1 3 female 1 4 male 0
Sur la base de la condition, créez une nouvelle colonne new_Sex
>>> df['new_Sex'] = np.where(df['Sex'] == 'male', 0, 1) >>> df Sex new_Sex 0 male 0 1 female 1 2 female 1 3 female 1 4 male 0
OR:
>>> df Sex 0 male 1 female 2 female 3 female 4 male
Mon instinct aurait suggéré d'utiliser .map ()
, mais j'ai fait une comparaison entre votre solution et la carte, basée sur une base de données avec 1500 valeurs masculines / féminines aléatoires.
%timeit df_base['Sex_new'] = (df_base['Sex'] == 'female').astype(int) 1000 loops, best of 3: 388 µs per loop
Modifié Basé sur le commentaire de Coldspeeds, et parce que le réaffecter est une meilleure comparaison avec les autres:
%timeit df_base['Sex_new'] = np.where(df_base['Sex'] == 'male', 0, 1) 1000 loops, best of 3: 331 µs per loop
Donc en fait plus lent .map ()
...!
Donc, sur la base de cet exemple, votre solution 'de mauvaise qualité' semble plus rapide que .map ()
...
Edit[
La solution de pygo:
%timeit df_base['Sex_new'] = df_base['Sex'].replace(['male','female'],[0,1]) 1000 loops, best of 3: 968 µs per loop
Tellement plus vite! p >
La solution de Jezrael avec .astype(int)
:
%timeit df_base['Sex_new'] = df_base['Sex'].map({'male': 0,'female': 1}) 1000 loops, best of 3: 653 µs per loop
Donc aussi plus rapide que .map ()
et .replace ()
.
Qu'en est-il de la comparaison de df ['Old_Sex'] = np.where (df ['Sex'] == 'male', 0, 1)
?
Et vérifiez ceci pour map / replace
comparaison
Oui, la solution avec numpy sera plus rapide.
Ou df_base ['Sex'] = (df_base ['Sex']. Values == 'female'). Astype (int)
Notez que df_base ['Sex']. Replace (['male', 'female'], [0,1], inplace = True)
ne fonctionnera pas car inplace = True code> on Series with replace a toujours été problématique. Attribuez-le à nouveau.
Merci pour les timings, mais j'obtiens autre chose, replace
est plus lent pour moi, vérifiez ma réponse. Quel est votre code pour tester les performances?
@jezrael: C'est aussi pour moi si je le réaffecte. Voir la modification (je l'ai déjà publiée en bas, mais je l'ai rendue plus visible maintenant). J'aime vraiment votre intrigue des différentes options!
@NielsHenkens - Oui, je l'aime aussi, je l'apprends de unutbu :)
J'ai popularisé perfplot
dans cette réponse que j'ai écrite récemment
@jezrael ces intrigues de perf sont très belles, je vais essayer de l'apprendre :-)
@coldspeed, le post est vraiment sympa, mais quelle méthode utilisez-vous pour tracer les graphiques perfplot?
@pygo oui, faites défiler vers le bas de l'article, j'y ai ajouté tous les extraits de code.
Pourquoi ne vois-je pas de personnes suggérant des doublons alors que la question est en fait un double?
@coldspeed, je n'ai jamais entendu parler de ce fil. Donc, je ne pouvais pas le diffuser en tant que dups.
@pygo Je n'ai rien contre les gens qui suggèrent des dupes, mais je n'aime pas les doubles standards. Je le vois partout, et plus pour certains utilisateurs que pour d'autres.
@coldspeed - Oui, la solution standard est replace / map, mais si OP a besoin de performances, il existe également une autre solution, donc pas de fermeture par dupe de ma part.
@jezrael Chaque question peut être laissée ouverte avec ce raisonnement. Je suis sûr que vous avez déjà utilisé le même raisonnement pour répondre à des questions similaires, alors trouvez-en une et marquez-la comme dupe. Ou ajoutez une réponse à la cible de dupe. Vous obtiendrez ainsi beaucoup plus de représentants que de répondre à des questions comme celle-ci encore et encore.
@coldspeed - oui, mais voici seulement 2 valeurs dans la colonne
Sex
, donc ce n'est qu'un cas spécial, donc pas possible d'ajouter une réponse à dupe - c'est une bonne solution générale pour remplacer de nombreuses valeurs ... Parce que seulement 2 valeurs de remplacement est une solution plus rapide possible.