J'ai le DataFrame suivant où l'une des colonnes est un objet (cellule de type liste):
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})
df
Out[458]:
A B
0 1 [1, 2]
1 2 [1, 2]
Ma sortie attendue est:
A B
0 1 1
1 1 2
3 2 1
4 2 2
Que dois-je faire pour y parvenir?
Question connexe
Bonne question et réponse mais ne gérez qu'une seule colonne avec liste (Dans ma réponse, la fonction self-def fonctionnera pour plusieurs colonnes, la réponse acceptée est également d'utiliser le plus de temps apply
, ce qui n'est pas recommandé, vérifiez plus d'informations Quand devrais-je vouloir utiliser pandas apply () dans mon code? )
Réponses:
Je sais que les
object
colonnestype
rendent les données difficiles à convertir avec unepandas
fonction. Lorsque j'ai reçu des données comme celles-ci, la première chose qui m'est venue à l'esprit a été d '«aplatir» ou de désnoisonner les colonnes.J'utilise
pandas
et despython
fonctions pour ce type de question. Si vous vous inquiétez de la vitesse des solutions ci-dessus, consultez la réponse de user3483203 , car il utilisenumpy
et la plupart du tempsnumpy
est plus rapide. Je recommandeCpython
etnumba
si la vitesse compte.Méthode 0 [pandas> = 0.25]
À partir de pandas 0.25 , si vous n'avez besoin d'exploser qu'une colonne, vous pouvez utiliser la
pandas.DataFrame.explode
fonction:Étant donné un dataframe avec un vide
list
ou unNaN
dans la colonne. Une liste vide ne causera pas de problème, mais unNaN
devra être rempli avec unlist
Méthode 1
apply + pd.Series
(facile à comprendre mais en termes de performances déconseillée.)Méthode 2
En utilisant
repeat
avec leDataFrame
constructeur, recréez votre dataframe (bon pour les performances, pas bon pour plusieurs colonnes)Par
exemple, la méthode 2.1 en plus de A, nous avons A.1 ..... An Si nous utilisons toujours la méthode ( Méthode 2 ) ci-dessus, il nous est difficile de recréer les colonnes une par une.
Solution:
join
oumerge
avec laindex
suite 'unnest' les colonnes simplesSi vous avez besoin que l'ordre des colonnes soit exactement le même qu'avant, ajoutez
reindex
à la fin.Méthode 3
recréer le
list
Si plus de deux colonnes, utilisez
Méthode 4 en
utilisant
reindex
ouloc
Méthode 5
lorsque la liste ne contient que des valeurs uniques:
Méthode 6
utilisant
numpy
pour de hautes performances:Méthode 7
utilisant la fonction de base
itertools
cycle
etchain
: Solution python pure juste pour le plaisirGénéralisation à plusieurs colonnes
Fonction self-def:
Désincorporation par colonne
Toute la méthode ci-dessus parle du désemboîtement vertical et de l'explosion.Si vous avez besoin de dépenser la liste horizontalement , vérifiez avec le
pd.DataFrame
constructeurFonction mise à jour
Sortie de test
la source
Option 1
Si toutes les sous-listes de l'autre colonne ont la même longueur, cela
numpy
peut être une option efficace ici:Option 2
Si les sous-listes ont une longueur différente, vous avez besoin d'une étape supplémentaire:
Option 3
J'ai essayé de généraliser cela pour travailler à aplatir les
N
colonnes et lesM
colonnes de tuiles , je travaillerai plus tard pour le rendre plus efficace:Les fonctions
Timings
Performance
la source
df.explode
méthode.L'éclatement d'une colonne de type liste a été considérablement simplifié dans pandas 0.25 avec l'ajout de la
explode()
méthode:En dehors:
la source
Une alternative consiste à appliquer la recette du meshgrid sur les lignes des colonnes pour annuler l'imbrication:
Production
la source
Mes 5 cents:
et encore 5
les deux aboutissant au même
la source
Parce que normalement, la longueur des sous-listes est différente et que la jointure / fusion est beaucoup plus coûteuse en calcul. J'ai retesté la méthode pour des sous-listes de longueurs différentes et des colonnes plus normales.
MultiIndex devrait également être un moyen plus simple d'écrire et a presque les mêmes performances que numpy way.
Étonnamment, dans ma manière de comprendre la mise en œuvre a les meilleures performances.
Performance
Temps relatif de chaque méthode
la source
J'ai un peu généralisé le problème pour qu'il s'applique à plus de colonnes.
Résumé de ce que fait ma solution:
Exemple complet:
L'explosion proprement dite est réalisée en 3 lignes. Le reste est cosmétique (explosion multi colonnes, manipulation de chaînes au lieu de listes dans la colonne explosion, ...).
Crédits à la réponse de WeNYoBen
la source
Configuration du problème
Supposons qu'il y ait plusieurs colonnes contenant des objets de différentes longueurs
Lorsque les longueurs sont les mêmes, il est facile pour nous de supposer que les différents éléments coïncident et doivent être «zippés» ensemble.
Cependant, l'hypothèse est remise en question lorsque nous voyons des objets de différentes longueurs, si nous «compressons», si oui, comment gérons-nous l'excès dans l'un des objets. OU , peut-être voulons-nous le produit de tous les objets. Cela deviendra vite grand, mais c'est peut-être ce que l'on souhaite.
OU
La fonction
Cette fonction gère gracieusement
zip
ou enproduct
fonction d'un paramètre et suppose enzip
fonction de la longueur de l'objet le plus long aveczip_longest
Zippé
Produit
Nouvelle configuration
Varier un peu l'exemple
Zippé
Produit
la source
Quelque chose d'assez déconseillé (au moins fonctionne dans ce cas):
concat
+sort_index
+iter
+apply
+next
.Maintenant:
Est:
Si vous vous souciez de l'index:
Maintenant:
Est:
la source
Des opinions sur cette méthode auxquelles j'ai pensé? ou est-ce que faire à la fois concat et fondre est considéré comme trop "cher"?
la source
J'ai un autre bon moyen de résoudre ce problème lorsque vous avez plus d'une colonne à exploser.
Je veux faire exploser les colonnes B et C. D'abord, j'explose B, deuxième C. Puis je laisse tomber B et C du df original. Après cela, je ferai une jointure d'index sur les 3 dfs.
la source
la source
la source
Dans mon cas, avec plus d'une colonne à exploser et avec des longueurs de variables pour les tableaux qui doivent être non imbriqués.
J'ai fini par appliquer la nouvelle
explode
fonction pandas 0.25 deux fois, puis en supprimant les doublons générés et cela fait le travail!la source