2 votes

Diviser les en-têtes de colonnes et dupliquer les valeurs des lignes dans un Dataframe Pandas

Dans l'exemple df ci-dessous, j'essaie de trouver un moyen de diviser les en-têtes de colonnes ('1;2', '4', '5;6') sur la base du ';' existant et de dupliquer les valeurs des lignes dans ces colonnes divisées. (Mon df actuel provient d'un fichier csv importé, donc j'ai généralement environ 50-80 en-têtes de colonnes qui ont besoin d'être scindées).

Voici mon code avec le résultat

 import pandas as pd
 import numpy as np  
 #

 data = np.array([['Market','Product Code','1;2','4','5;6'],
            ['Total Customers',123,1,500,400],
            ['Total Customers',123,2,400,320],
            ['Major Customer 1',123,1,100,220],
            ['Major Customer 1',123,2,230,230],
            ['Major Customer 2',123,1,130,30],
            ['Major Customer 2',123,2,20,10],
            ['Total Customers',456,1,500,400],
            ['Total Customers',456,2,400,320],
            ['Major Customer 1',456,1,100,220],
            ['Major Customer 1',456,2,230,230],
            ['Major Customer 2',456,1,130,30],
            ['Major Customer 2',456,2,20,10]])

  df =pd.DataFrame(data)
  df.columns = df.iloc[0]
  df = df.reindex(df.index.drop(0))
  print (df)
0             Market Product Code 1;2    4  5;6
1    Total Customers          123   1  500  400
2    Total Customers          123   2  400  320
3   Major Customer 1          123   1  100  220
4   Major Customer 1          123   2  230  230
5   Major Customer 2          123   1  130   30
6   Major Customer 2          123   2   20   10
7    Total Customers          456   1  500  400
8    Total Customers          456   2  400  320
9   Major Customer 1          456   1  100  220
10  Major Customer 1          456   2  230  230
11  Major Customer 2          456   1  130   30
12  Major Customer 2          456   2   20   10

Voici le résultat que je souhaite obtenir

 0             Market Product Code   1   2      4      5    6
 1    Total Customers          123   1   1     500    400  400
 2    Total Customers          123   2   2     400    320  320
 3   Major Customer 1          123   1   1     100    220  220
 4   Major Customer 1          123   2   2     230    230  230
 5   Major Customer 2          123   1   1     130    30   30
 6   Major Customer 2          123   2   2     20     10   10
 7    Total Customers          456   1   1     500    400  400
 8    Total Customers          456   2   2     400    320  320
 9   Major Customer 1          456   1   1     100    220  220
10  Major Customer 1           456   2   2     230    230  230
11  Major Customer 2           456   1   1     130    30   30
12  Major Customer 2           456   2   2     20     10   10

Idéalement, j'aimerais effectuer cette tâche au niveau "read_csv". Qu'en pensez-vous ?

1voto

W-B Points 94428

Essayer reindex avec repeat

s=df.columns.str.split(';')
df=df.reindex(columns=df.columns.repeat(s.str.len()))
df.columns=sum(s.tolist(),[])
df
Out[247]: 
              Market Product Code  1  2    4    5    6
1    Total Customers          123  1  1  500  400  400
2    Total Customers          123  2  2  400  320  320
3   Major Customer 1          123  1  1  100  220  220
4   Major Customer 1          123  2  2  230  230  230
5   Major Customer 2          123  1  1  130   30   30
6   Major Customer 2          123  2  2   20   10   10
7    Total Customers          456  1  1  500  400  400
8    Total Customers          456  2  2  400  320  320
9   Major Customer 1          456  1  1  100  220  220
10  Major Customer 1          456  2  2  230  230  230
11  Major Customer 2          456  1  1  130   30   30
12  Major Customer 2          456  2  2   20   10   10

1voto

Allen Points 8723

Vous pouvez diviser les colonnes avec ';' et ensuite reconstruire un df :

pd.DataFrame({c:df[t] for t in df.columns for c in t.split(';')})
Out[157]: 
    1  2    4    5    6            Market Product Code
1   1  1  500  400  400   Total Customers          123
2   2  2  400  320  320   Total Customers          123
3   1  1  100  220  220  Major Customer 1          123
4   2  2  230  230  230  Major Customer 1          123
5   1  1  130   30   30  Major Customer 2          123
6   2  2   20   10   10  Major Customer 2          123
7   1  1  500  400  400   Total Customers          456
8   2  2  400  320  320   Total Customers          456
9   1  1  100  220  220  Major Customer 1          456
10  2  2  230  230  230  Major Customer 1          456
11  1  1  130   30   30  Major Customer 2          456
12  2  2   20   10   10  Major Customer 2          456

Ou si vous souhaitez réserver une commande de colonne :

pd.concat([df[t].to_frame(c) for t in df.columns for c in t.split(';')],1)
Out[167]: 
              Market Product Code  1  2    4    5    6
1    Total Customers          123  1  1  500  400  400
2    Total Customers          123  2  2  400  320  320
3   Major Customer 1          123  1  1  100  220  220
4   Major Customer 1          123  2  2  230  230  230
5   Major Customer 2          123  1  1  130   30   30
6   Major Customer 2          123  2  2   20   10   10
7    Total Customers          456  1  1  500  400  400
8    Total Customers          456  2  2  400  320  320
9   Major Customer 1          456  1  1  100  220  220
10  Major Customer 1          456  2  2  230  230  230
11  Major Customer 2          456  1  1  130   30   30
12  Major Customer 2          456  2  2   20   10   10

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