611 votes

Comment faire pivoter un cadre de données

  • Qu'est-ce que le pivot ?
  • Comment puis-je pivoter ?
  • C'est un pivot ?
  • Du format long au format large ?

J'ai vu beaucoup de questions portant sur les tableaux croisés dynamiques. Même si elles ne savent pas qu'elles portent sur les tableaux croisés dynamiques, c'est généralement le cas. Il est pratiquement impossible d'écrire une question et une réponse canoniques qui englobent tous les aspects des tableaux croisés dynamiques.....

... Mais je vais tenter le coup.


Le problème des questions et réponses existantes est que, souvent, la question est centrée sur une nuance que le PO a du mal à généraliser afin d'utiliser un certain nombre de bonnes réponses existantes. Cependant, aucune de ces réponses ne tente de donner une explication complète (parce que c'est une tâche ardue).

Regardez quelques exemples de mon recherche google

  1. Comment faire pivoter un dataframe dans Pandas ?
    • Bonne question et bonne réponse. Mais la réponse ne répond qu'à la question spécifique avec peu d'explications.
  2. Tableau croisé dynamique pandas vers cadre de données
    • Dans cette question, l'OP s'intéresse à la sortie du pivot. C'est-à-dire l'aspect des colonnes. Le PO voulait que cela ressemble à R. Ce n'est pas très utile pour les utilisateurs de pandas.
  3. pandas fait pivoter un cadre de données et duplique les lignes
    • Une autre bonne question, mais la réponse se concentre sur une méthode, à savoir pd.DataFrame.pivot

Donc quand quelqu'un cherche pivot ils obtiennent des résultats sporadiques qui ne vont probablement pas répondre à leur question spécifique.


Configuration

Vous remarquerez peut-être que j'ai nommé mes colonnes et les valeurs de colonnes pertinentes de manière ostensible pour correspondre à la façon dont je vais pivoter dans les réponses ci-dessous. Prêtez-y attention afin de vous familiariser avec les noms des colonnes et leur emplacement pour obtenir les résultats que vous recherchez.

import numpy as np
import pandas as pd
from numpy.core.defchararray import add

np.random.seed([3,1415])
n = 20

cols = np.array(['key', 'row', 'item', 'col'])
arr1 = (np.random.randint(5, size=(n, 4)) // [2, 1, 2, 1]).astype(str)

df = pd.DataFrame(
    add(cols, arr1), columns=cols
).join(
    pd.DataFrame(np.random.rand(n, 2).round(2)).add_prefix('val')
)
print(df)

     key   row   item   col  val0  val1
0   key0  row3  item1  col3  0.81  0.04
1   key1  row2  item1  col2  0.44  0.07
2   key1  row0  item1  col0  0.77  0.01
3   key0  row4  item0  col2  0.15  0.59
4   key1  row0  item2  col1  0.81  0.64
5   key1  row2  item2  col4  0.13  0.88
6   key2  row4  item1  col3  0.88  0.39
7   key1  row4  item1  col1  0.10  0.07
8   key1  row0  item2  col4  0.65  0.02
9   key1  row2  item0  col2  0.35  0.61
10  key2  row0  item2  col1  0.40  0.85
11  key2  row4  item1  col2  0.64  0.25
12  key0  row2  item2  col3  0.50  0.44
13  key0  row4  item1  col4  0.24  0.46
14  key1  row3  item2  col3  0.28  0.11
15  key0  row3  item1  col1  0.31  0.23
16  key0  row0  item2  col3  0.86  0.01
17  key0  row4  item0  col3  0.64  0.21
18  key2  row2  item2  col0  0.13  0.45
19  key0  row2  item0  col4  0.37  0.70

Question(s)

  1. Pourquoi est-ce que j'ai ValueError: Index contains duplicate entries, cannot reshape

  2. Comment puis-je pivoter df de sorte que le col sont des colonnes, row sont l'indice et la moyenne de val0 sont les valeurs ?

    col   col0   col1   col2   col3  col4
    row                                  
    row0  0.77  0.605    NaN  0.860  0.65
    row2  0.13    NaN  0.395  0.500  0.25
    row3   NaN  0.310    NaN  0.545   NaN
    row4   NaN  0.100  0.395  0.760  0.24
  3. Comment puis-je pivoter df de sorte que le col sont des colonnes, row Les valeurs sont l'indice, la moyenne de val0 sont les valeurs, et les valeurs manquantes sont 0 ?

    col   col0   col1   col2   col3  col4
    row                                  
    row0  0.77  0.605  0.000  0.860  0.65
    row2  0.13  0.000  0.395  0.500  0.25
    row3  0.00  0.310  0.000  0.545  0.00
    row4  0.00  0.100  0.395  0.760  0.24
  4. Je peux avoir autre chose que mean comme peut-être sum ?

    col   col0  col1  col2  col3  col4
    row                               
    row0  0.77  1.21  0.00  0.86  0.65
    row2  0.13  0.00  0.79  0.50  0.50
    row3  0.00  0.31  0.00  1.09  0.00
    row4  0.00  0.10  0.79  1.52  0.24
  5. Puis-je faire plus d'une agrégation à la fois ?

           sum                          mean                           
    col   col0  col1  col2  col3  col4  col0   col1   col2   col3  col4
    row                                                                
    row0  0.77  1.21  0.00  0.86  0.65  0.77  0.605  0.000  0.860  0.65
    row2  0.13  0.00  0.79  0.50  0.50  0.13  0.000  0.395  0.500  0.25
    row3  0.00  0.31  0.00  1.09  0.00  0.00  0.310  0.000  0.545  0.00
    row4  0.00  0.10  0.79  1.52  0.24  0.00  0.100  0.395  0.760  0.24
  6. Puis-je agréger sur plusieurs colonnes de valeurs ?

          val0                             val1                          
    col   col0   col1   col2   col3  col4  col0   col1  col2   col3  col4
    row                                                                  
    row0  0.77  0.605  0.000  0.860  0.65  0.01  0.745  0.00  0.010  0.02
    row2  0.13  0.000  0.395  0.500  0.25  0.45  0.000  0.34  0.440  0.79
    row3  0.00  0.310  0.000  0.545  0.00  0.00  0.230  0.00  0.075  0.00
    row4  0.00  0.100  0.395  0.760  0.24  0.00  0.070  0.42  0.300  0.46
  7. Peut-on subdiviser par plusieurs colonnes ?

    item item0             item1                         item2                   
    col   col2  col3  col4  col0  col1  col2  col3  col4  col0   col1  col3  col4
    row                                                                          
    row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.605  0.86  0.65
    row2  0.35  0.00  0.37  0.00  0.00  0.44  0.00  0.00  0.13  0.000  0.50  0.13
    row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.000  0.28  0.00
    row4  0.15  0.64  0.00  0.00  0.10  0.64  0.88  0.24  0.00  0.000  0.00  0.00
  8. Ou

    item      item0             item1                         item2                  
    col        col2  col3  col4  col0  col1  col2  col3  col4  col0  col1  col3  col4
    key  row                                                                         
    key0 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.86  0.00
         row2  0.00  0.00  0.37  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.50  0.00
         row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.00  0.00  0.00
         row4  0.15  0.64  0.00  0.00  0.00  0.00  0.00  0.24  0.00  0.00  0.00  0.00
    key1 row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.81  0.00  0.65
         row2  0.35  0.00  0.00  0.00  0.00  0.44  0.00  0.00  0.00  0.00  0.00  0.13
         row3  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.28  0.00
         row4  0.00  0.00  0.00  0.00  0.10  0.00  0.00  0.00  0.00  0.00  0.00  0.00
    key2 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.40  0.00  0.00
         row2  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.13  0.00  0.00  0.00
         row4  0.00  0.00  0.00  0.00  0.00  0.64  0.88  0.00  0.00  0.00  0.00  0.00
  9. Puis-je agréger la fréquence à laquelle la colonne et les lignes apparaissent ensemble, c'est-à-dire faire un "tableau croisé" ?

    col   col0  col1  col2  col3  col4
    row                               
    row0     1     2     0     1     1
    row2     1     0     2     1     2
    row3     0     1     0     2     0
    row4     0     1     2     2     1
  10. Comment convertir un DataFrame de long en large en pivotant sur seulement deux colonnes ? Étant donné,

    np.random.seed([3, 1415])
    df2 = pd.DataFrame({'A': list('aaaabbbc'), 'B': np.random.choice(15, 8)})        
    df2        
       A   B
    0  a   0
    1  a  11
    2  a   2
    3  a  11
    4  b  10
    5  b  10
    6  b  14
    7  c   7

    Le résultat attendu devrait ressembler à quelque chose comme

          a     b    c
    0   0.0  10.0  7.0
    1  11.0  10.0  NaN
    2   2.0  14.0  NaN
    3  11.0   NaN  NaN
  11. Comment puis-je aplatir l'index multiple en index simple après pivot

    De

       1  2   
       1  1  2        
    a  2  1  1
    b  2  1  0
    c  1  0  0

    A

       1|1  2|1  2|2               
    a    2    1    1
    b    2    1    0
    c    1    0    0

463voto

piRSquared Points 159

Nous commençons par répondre à la première question :

Question 1

Pourquoi est-ce que j'ai ValueError: Index contains duplicate entries, cannot reshape

Cela se produit parce que pandas tente de réindexer soit une columns ou index avec des entrées dupliquées. Il existe différentes méthodes permettant d'effectuer un pivot. Certaines d'entre elles ne sont pas bien adaptées lorsqu'il y a des doublons dans les clés sur lesquelles on demande de pivoter. Par exemple. Considérons pd.DataFrame.pivot . Je sais qu'il y a des entrées en double qui partagent la même row et col valeurs :

df.duplicated(['row', 'col']).any()

True

Donc quand je pivot en utilisant

df.pivot(index='row', columns='col', values='val0')

Je reçois l'erreur mentionnée ci-dessus. En fait, j'obtiens la même erreur lorsque j'essaie d'effectuer la même tâche avec :

df.set_index(['row', 'col'])['val0'].unstack()

Voici une liste d'idiomes que l'on peut utiliser pour pivoter

  1. pd.DataFrame.groupby + pd.DataFrame.unstack
    • Bonne approche générale pour faire à peu près n'importe quel type de pivot.
    • Vous spécifiez toutes les colonnes qui constitueront les niveaux de lignes et de colonnes pivotées dans un groupe par. Vous sélectionnez ensuite les colonnes restantes que vous souhaitez agréger et la ou les fonctions que vous souhaitez utiliser pour effectuer l'agrégation. Enfin, vous devez unstack les niveaux que vous souhaitez voir figurer dans l'index de la colonne.
  2. pd.DataFrame.pivot_table
    • Une version glorifiée de groupby avec une API plus intuitive. Pour beaucoup de gens, c'est l'approche préférée. Et c'est l'approche prévue par les développeurs.
    • Spécifiez le niveau des lignes, les niveaux des colonnes, les valeurs à agréger et la ou les fonctions pour effectuer les agrégations.
  3. pd.DataFrame.set_index + pd.DataFrame.unstack
    • Pratique et intuitif pour certains (moi y compris). Ne peut pas gérer les clés groupées en double.
    • Semblable à la groupby paradigme, nous spécifions toutes les colonnes qui seront éventuellement des niveaux de lignes ou de colonnes et nous les définissons comme étant l'index. Ensuite, nous unstack les niveaux que nous voulons dans les colonnes. Si les niveaux d'index restants ou les niveaux de colonne ne sont pas uniques, cette méthode échouera.
  4. pd.DataFrame.pivot
    • Très similaire à set_index en ce sens qu'il partage la limitation des clés dupliquées. L'API est également très limitée. Elle ne prend que des valeurs scalaires pour index , columns , values .
    • Semblable à la pivot_table en ce sens que nous sélectionnons les lignes, les colonnes et les valeurs sur lesquelles nous voulons pivoter. Cependant, nous ne pouvons pas agréger et si les lignes ou les colonnes ne sont pas uniques, cette méthode échouera.
  5. pd.crosstab
    • Il s'agit d'une version spécialisée de pivot_table et dans sa forme la plus pure, c'est la manière la plus intuitive d'effectuer plusieurs tâches.
  6. pd.factorize + np.bincount
    • Il s'agit d'une technique très avancée, très obscure mais très rapide. Elle ne peut pas être utilisée en toutes circonstances, mais lorsqu'elle peut l'être et que vous êtes à l'aise pour l'utiliser, vous récolterez les fruits de vos performances.
  7. pd.get_dummies + pd.DataFrame.dot
    • Je l'utilise pour effectuer des tableaux croisés astucieux.

Exemples

Ce que je vais faire pour chaque réponse et question suivante est de répondre en utilisant pd.DataFrame.pivot_table . Ensuite, je proposerai des alternatives pour effectuer la même tâche.

Question 3

Comment puis-je pivoter df de sorte que le col sont des colonnes, row Les valeurs sont l'indice, la moyenne de val0 sont les valeurs, et les valeurs manquantes sont 0 ?

  • pd.DataFrame.pivot_table

    • fill_value n'est pas défini par défaut. J'ai tendance à le définir de manière appropriée. Dans ce cas, je l'ai fixé à 0 . Remarquez que j'ai sauté question 2 car c'est la même chose que cette réponse, sans l'élément fill_value
    • aggfunc='mean' est la valeur par défaut et je n'ai pas eu besoin de la définir. Je l'ai inclus pour être explicite.

      df.pivot_table(
          values='val0', index='row', columns='col',
          fill_value=0, aggfunc='mean')
      
      col   col0   col1   col2   col3  col4
      row                                  
      row0  0.77  0.605  0.000  0.860  0.65
      row2  0.13  0.000  0.395  0.500  0.25
      row3  0.00  0.310  0.000  0.545  0.00
      row4  0.00  0.100  0.395  0.760  0.24
  • pd.DataFrame.groupby

    df.groupby(['row', 'col'])['val0'].mean().unstack(fill_value=0)
  • pd.crosstab

    pd.crosstab(
        index=df['row'], columns=df['col'],
        values=df['val0'], aggfunc='mean').fillna(0)

Question 4

Je peux avoir autre chose que mean comme peut-être sum ?

  • pd.DataFrame.pivot_table

    df.pivot_table(
        values='val0', index='row', columns='col',
        fill_value=0, aggfunc='sum')
    
    col   col0  col1  col2  col3  col4
    row                               
    row0  0.77  1.21  0.00  0.86  0.65
    row2  0.13  0.00  0.79  0.50  0.50
    row3  0.00  0.31  0.00  1.09  0.00
    row4  0.00  0.10  0.79  1.52  0.24
  • pd.DataFrame.groupby

    df.groupby(['row', 'col'])['val0'].sum().unstack(fill_value=0)
  • pd.crosstab

    pd.crosstab(
        index=df['row'], columns=df['col'],
        values=df['val0'], aggfunc='sum').fillna(0)

Question 5

Puis-je faire plus d'une agrégation à la fois ?

Notez que pour pivot_table et cross_tab J'avais besoin de passer une liste d'appelants. D'un autre côté, groupby.agg est capable de prendre des cordes pour un nombre limité de fonctions spéciales. groupby.agg aurait également pris les mêmes appelables que nous avons passés aux autres, mais il est souvent plus efficace d'exploiter les noms de fonctions de la chaîne de caractères car il y a des gains d'efficacité à faire.

  • pd.DataFrame.pivot_table

    df.pivot_table(
        values='val0', index='row', columns='col',
        fill_value=0, aggfunc=[np.size, np.mean])
    
         size                      mean                           
    col  col0 col1 col2 col3 col4  col0   col1   col2   col3  col4
    row                                                           
    row0    1    2    0    1    1  0.77  0.605  0.000  0.860  0.65
    row2    1    0    2    1    2  0.13  0.000  0.395  0.500  0.25
    row3    0    1    0    2    0  0.00  0.310  0.000  0.545  0.00
    row4    0    1    2    2    1  0.00  0.100  0.395  0.760  0.24
  • pd.DataFrame.groupby

    df.groupby(['row', 'col'])['val0'].agg(['size', 'mean']).unstack(fill_value=0)
  • pd.crosstab

    pd.crosstab(
        index=df['row'], columns=df['col'],
        values=df['val0'], aggfunc=[np.size, np.mean]).fillna(0, downcast='infer')

Question 6

Puis-je agréger sur plusieurs colonnes de valeurs ?

  • pd.DataFrame.pivot_table nous passons values=['val0', 'val1'] mais nous aurions pu laisser ça complètement de côté

    df.pivot_table(
        values=['val0', 'val1'], index='row', columns='col',
        fill_value=0, aggfunc='mean')
    
          val0                             val1                          
    col   col0   col1   col2   col3  col4  col0   col1  col2   col3  col4
    row                                                                  
    row0  0.77  0.605  0.000  0.860  0.65  0.01  0.745  0.00  0.010  0.02
    row2  0.13  0.000  0.395  0.500  0.25  0.45  0.000  0.34  0.440  0.79
    row3  0.00  0.310  0.000  0.545  0.00  0.00  0.230  0.00  0.075  0.00
    row4  0.00  0.100  0.395  0.760  0.24  0.00  0.070  0.42  0.300  0.46
  • pd.DataFrame.groupby

    df.groupby(['row', 'col'])['val0', 'val1'].mean().unstack(fill_value=0)

Question 7

Peut-on subdiviser par plusieurs colonnes ?

  • pd.DataFrame.pivot_table

    df.pivot_table(
        values='val0', index='row', columns=['item', 'col'],
        fill_value=0, aggfunc='mean')
    
    item item0             item1                         item2                   
    col   col2  col3  col4  col0  col1  col2  col3  col4  col0   col1  col3  col4
    row                                                                          
    row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.605  0.86  0.65
    row2  0.35  0.00  0.37  0.00  0.00  0.44  0.00  0.00  0.13  0.000  0.50  0.13
    row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.000  0.28  0.00
    row4  0.15  0.64  0.00  0.00  0.10  0.64  0.88  0.24  0.00  0.000  0.00  0.00
  • pd.DataFrame.groupby

    df.groupby(
        ['row', 'item', 'col']
    )['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)

Question 8

Peut-on subdiviser par plusieurs colonnes ?

  • pd.DataFrame.pivot_table

    df.pivot_table(
        values='val0', index=['key', 'row'], columns=['item', 'col'],
        fill_value=0, aggfunc='mean')
    
    item      item0             item1                         item2                  
    col        col2  col3  col4  col0  col1  col2  col3  col4  col0  col1  col3  col4
    key  row                                                                         
    key0 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.86  0.00
         row2  0.00  0.00  0.37  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.50  0.00
         row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.00  0.00  0.00
         row4  0.15  0.64  0.00  0.00  0.00  0.00  0.00  0.24  0.00  0.00  0.00  0.00
    key1 row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.81  0.00  0.65
         row2  0.35  0.00  0.00  0.00  0.00  0.44  0.00  0.00  0.00  0.00  0.00  0.13
         row3  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.28  0.00
         row4  0.00  0.00  0.00  0.00  0.10  0.00  0.00  0.00  0.00  0.00  0.00  0.00
    key2 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.40  0.00  0.00
         row2  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.13  0.00  0.00  0.00
         row4  0.00  0.00  0.00  0.00  0.00  0.64  0.88  0.00  0.00  0.00  0.00  0.00
  • pd.DataFrame.groupby

    df.groupby(
        ['key', 'row', 'item', 'col']
    )['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
  • pd.DataFrame.set_index car l'ensemble des clés est unique pour les lignes et les colonnes.

    df.set_index(
        ['key', 'row', 'item', 'col']
    )['val0'].unstack(['item', 'col']).fillna(0).sort_index(1)

Question 9

Puis-je agréger la fréquence à laquelle la colonne et les lignes apparaissent ensemble, c'est-à-dire faire un "tableau croisé" ?

  • pd.DataFrame.pivot_table

    df.pivot_table(index='row', columns='col', fill_value=0, aggfunc='size')
    
        col   col0  col1  col2  col3  col4
    row                               
    row0     1     2     0     1     1
    row2     1     0     2     1     2
    row3     0     1     0     2     0
    row4     0     1     2     2     1
  • pd.DataFrame.groupby

    df.groupby(['row', 'col'])['val0'].size().unstack(fill_value=0)
  • pd.cross_tab

    pd.crosstab(df['row'], df['col'])
  • pd.factorize + np.bincount

    # get integer factorization `i` and unique values `r`
    # for column `'row'`
    i, r = pd.factorize(df['row'].values)
    # get integer factorization `j` and unique values `c`
    # for column `'col'`
    j, c = pd.factorize(df['col'].values)
    # `n` will be the number of rows
    # `m` will be the number of columns
    n, m = r.size, c.size
    # `i * m + j` is a clever way of counting the 
    # factorization bins assuming a flat array of length
    # `n * m`.  Which is why we subsequently reshape as `(n, m)`
    b = np.bincount(i * m + j, minlength=n * m).reshape(n, m)
    # BTW, whenever I read this, I think 'Bean, Rice, and Cheese'
    pd.DataFrame(b, r, c)
    
          col3  col2  col0  col1  col4
    row3     2     0     0     1     0
    row2     1     2     1     0     2
    row0     1     0     1     2     1
    row4     2     2     0     1     1
  • pd.get_dummies

    pd.get_dummies(df['row']).T.dot(pd.get_dummies(df['col']))
    
          col0  col1  col2  col3  col4
    row0     1     2     0     1     1
    row2     1     0     2     1     2
    row3     0     1     0     2     0
    row4     0     1     2     2     1

Question 10

Comment puis-je convertir un DataFrame de long en large en pivotant sur UN SEUL deux colonnes ?

La première étape consiste à attribuer un numéro à chaque ligne - ce numéro sera l'index de ligne de cette valeur dans le résultat pivoté. Cette opération est réalisée à l'aide de GroupBy.cumcount :

df2.insert(0, 'count', df.groupby('A').cumcount())
df2

   count  A   B
0      0  a   0
1      1  a  11
2      2  a   2
3      3  a  11
4      0  b  10
5      1  b  10
6      2  b  14
7      0  c   7

Question 11

Comment puis-je aplatir l'index multiple en index simple après pivot

Si columns type object avec la chaîne join

df.columns = df.columns.map('|'.join)

sinon format

df.columns = df.columns.map('{0[0]}|{0[1]}'.format)

53 votes

Pourriez-vous envisager d'étendre documents officiels ?

0 votes

Que s'est-il passé avec la réponse à la question n°10 ? J'ai obtenu KeyError: 'A' . Y a-t-il d'autres réponses ?

0 votes

@MonicaHeddneck Je vais le revoir et le mettre à jour si nécessaire. Cependant, 'A' suppose qu'il existe une colonne 'A' dans votre cadre de données pour regrouper par.

24voto

Ch3steR Points 15182

Pour prolonger La réponse de @piRSquared une autre version de Question 10

Question 10.1

DataFrame :

d = data = {'A': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 3, 6: 5},
 'B': {0: 'a', 1: 'b', 2: 'c', 3: 'a', 4: 'b', 5: 'a', 6: 'c'}}
df = pd.DataFrame(d)

   A  B
0  1  a
1  1  b
2  1  c
3  2  a
4  2  b
5  3  a
6  5  c

Sortie :

   0     1     2
A
1  a     b     c
2  a     b  None
3  a  None  None
5  c  None  None

Utilisation de df.groupby y pd.Series.tolist

t = df.groupby('A')['B'].apply(list)
out = pd.DataFrame(t.tolist(),index=t.index)
out
   0     1     2
A
1  a     b     c
2  a     b  None
3  a  None  None
5  c  None  None

Ou Une bien meilleure alternative utilisant pd.pivot_table avec df.squeeze.

t = df.pivot_table(index='A',values='B',aggfunc=list).squeeze()
out = pd.DataFrame(t.tolist(),index=t.index)

16voto

Mykola Zotko Points 1929

Pour mieux comprendre comment pivot vous pouvez regarder les exemple de la documentation de Pandas :

enter image description here

df = pd.DataFrame({
    'foo': ['one', 'one', 'one', 'two', 'two', 'two'],
    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
    'baz': [1, 2, 3, 4, 5, 6],
    'zoo': ['x', 'y', 'z', 'q', 'w', 't']
})

Tableau d'entrée :

   foo bar  baz zoo
0  one   A    1   x
1  one   B    2   y
2  one   C    3   z
3  two   A    4   q
4  two   B    5   w
5  two   C    6   t

Pivot :

pd.pivot(
    data=df,        
    index='foo',    # Column to use to make new frame’s index. If None, uses existing index.
    columns='bar',  # Column to use to make new frame’s columns.
    values='baz'    # Column(s) to use for populating new frame’s values.
)

Tableau de sortie :

bar  A  B  C
foo         
one  1  2  3
two  4  5  6

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