0
votes

Pandas: transposez les colonnes (b, c, d) regroupées par colonne a comme index

J'ai un dataframe:

    file          
0         x     1  2  3
1  file1  y     10 20 30
2         ynorm 2  4  6
3         x     1  2  4
4  file2  y     10 20 40
5         ynorm 2  4  8

Je veux l'imprimer pour que:

    Le fichier
  • est l'index principal
  • x, y, z sont le sous-index

pour qu'il ressemble à ceci:

import pandas as pd 
import numpy as np 
data = pd.DataFrame({'file':['file1','file1','file1','file2','file2','file2' ], 'x': [1,2,3,1,2,4], 'y': [10,20,30,10, 20, 40], 'norm_y': [2,4,6,2,4,8]})

print (data)

out: 
    file  x   y  norm_y
0  file1  1  10       2
1  file1  2  20       4
2  file1  3  30       6
3  file2  1  10       2
4  file2  2  20       4
5  file2  4  40       8

Je pense que la réponse va être quelque chose comme:

  • définir l'index de ligne: data.set_index (['file'])
  • transposer les colonnes x, y, ynorm


1 commentaires

Il y a beaucoup de réponses correctes ci-dessous, ce serait bien de voir les temps d'exécution sur tous si quelqu'un veut essayer.


5 Réponses :


3
votes

Il s'agit à la base d'un problème de pivot , mais pas vraiment simple.


key            0   1   2
file
file1 x        1   2   3
      y       10  20  30
      norm_y   2   4   6
file2 x        1   2   4
      y       10  20  40
      norm_y   2   4   8

df.assign(
  key=df.groupby('file').cumcount()).set_index(['file', 'key']).stack().unstack('key')


0 commentaires

2
votes

Vous pouvez faire:

col            1   2   3
file                    
file1 norm_y   2   4   6
      x        1   2   3
      y       10  20  30
file2 norm_y   2   4   8
      x        1   2   4
      y       10  20  40

Sortie:

df['col' ] = df.groupby('file').cumcount()+1
df.pivot_table(index='file', columns='col').stack(level=0)


0 commentaires

1
votes

Jouer avec numpy remodèle

               2   3   4
0     1                 
file1 norm_y   2   4   6
      x        1   2   3
      y       10  20  30
file2 norm_y   2   4   8
      x        1   2   4
      y       10  20  40

fil, var, val = df.melt('file').values.T

new = pd.DataFrame(np.hstack([fil.reshape(-1,3)[:, 0].reshape(-1,1), 
                              var.reshape(-1,3)[:, 0].reshape(-1,1), 
                              val.reshape(-1,3)]))\
        .set_index([0,1])\
        .sort_index()


0 commentaires

3
votes

vous avez juste besoin d'un peu d'imagination:

file          file2  file2  file2
file                             
file1 x           1      2      3
      y          10     20     30
      norm_y      2      4      6
file2 x           1      2      4
      y          10     20     40
      norm_y      2      4      8

Sortie:

data.set_index('file').groupby(level=0).apply(lambda x: x.T)


1 commentaires

Vote positif car il semble plus rapide que les autres réponses!



0
votes

Essayez ceci.

(
    pd.melt(data, id_vars='file', value_vars=['x', 'y', 'norm_y']) #Unstacks the data
    .groupby(['file', 'variable'])['value'] #restacks with file and variable as index
    .aggregate(lambda x: tuple(x)) #splits out values in to a column
    .apply(pd.Series) #turns them into separate columns
)


0 commentaires