Je cherche à transformer une cellule pandas contenant une liste en lignes pour chacune de ces valeurs.
Alors, prenez ceci:
Si je souhaite décompresser et empiler les valeurs dans la nearest_neighbors
colonne de sorte que chaque valeur soit une ligne dans chaque opponent
index, comment procéder au mieux? Existe-t-il des méthodes pandas destinées à des opérations comme celle-ci?
pd.DataFrame(df.nearest_neighbors.values.tolist())
pour décompresser cette colonne puis lapd.merge
coller avec les autres.values.tolist()
quoi que ce soit ici; la colonne est déjà une listeRéponses:
Dans le code ci-dessous, je réinitialise d'abord l'index pour faciliter l'itération des lignes.
Je crée une liste de listes où chaque élément de la liste externe est une ligne du DataFrame cible et chaque élément de la liste interne est l'une des colonnes. Cette liste imbriquée sera finalement concaténée pour créer le DataFrame souhaité.
J'utilise une
lambda
fonction avec une itération de liste pour créer une ligne pour chaque élément de l'nearest_neighbors
apparié avec lename
etopponent
.Enfin, je crée un nouveau DataFrame à partir de cette liste (en utilisant les noms de colonne d'origine et en définissant l'index sur
name
etopponent
).EDIT JUIN 2017
Une autre méthode est la suivante:
la source
apply(pd.Series)
est bien sur le plus petit des cadres, mais pour tous les cadres de taille raisonnable, vous devriez reconsidérer une solution plus performante. Voir Quand devrais-je utiliser pandas apply () dans mon code? (Une meilleure solution consiste à lister la colonne en premier.)explode()
méthode. J'ai ajouté une réponse avec un exemple utilisant la même configuration df qu'ici.Utilisez
apply(pd.Series)
etstack
, puisreset_index
etto_frame
Détails
la source
df.nearest_neighbors.apply(pd.Series)
est très étonnant pour moi;explode()
méthode:En dehors:
la source
Je pense que c'est une très bonne question, dans Hive, vous utiliseriez
EXPLODE
, je pense qu'il y a un cas à faire que Pandas devrait inclure cette fonctionnalité par défaut. J'éclaterais probablement la colonne de liste avec une compréhension de générateur imbriquée comme celle-ci:la source
La méthode la plus rapide que j'ai trouvée jusqu'à présent consiste à étendre le DataFrame avec
.iloc
et à attribuer à nouveau la colonne cible aplatie .Compte tenu de l'entrée habituelle (répliquée un peu):
Compte tenu des alternatives suggérées suivantes:
Je trouve que
extend_iloc()
c'est le plus rapide :la source
cols = [c for c in df.columns if c != col_target]
devrait être:cols = [i for i,c in enumerate(df.columns) if c != col_target]
Lesdf.iloc[ilocations, cols].copy()
erreurs si elles ne sont pas présentées avec l'index de la colonne.Solution alternative plus agréable avec apply (pd.Series):
la source
Similaire à la fonctionnalité EXPLODE de Hive:
la source
NameError: global name 'copy' is not defined
Donc toutes ces réponses sont bonnes mais je voulais quelque chose ^ vraiment simple ^ alors voici ma contribution:
C'est tout ... utilisez simplement ceci quand vous voulez une nouvelle série où les listes sont «éclatées». Voici un exemple où nous faisons value_counts () sur les choix de tacos :)
la source
Voici une optimisation potentielle pour des dataframes plus volumineux. Cela s'exécute plus rapidement lorsqu'il y a plusieurs valeurs égales dans le champ "éclaté". (Plus la trame de données est grande par rapport au nombre de valeurs uniques dans le champ, meilleures seront les performances de ce code.)
la source
Extension de la
.iloc
réponse d' Oleg pour aplatir automatiquement toutes les colonnes de liste:Cela suppose que chaque colonne de liste a la même longueur de liste.
la source
Au lieu d'utiliser apply (pd.Series), vous pouvez aplatir la colonne. Cela améliore les performances.
la source