2016-06-22 2 views
1

J'ai une série avec des index en double que je voudrais convertir en un DataFrame multi-colonnes.Pandas duplique les index à dataframe

In [60]: np.random.seed(123456) 

In [61]: b=pd.Series(np.random.random(30), index=range(6)*5) 
In [62]: b 
Out[62]: 
0 0.126970 
1 0.966718 
2 0.260476 
3 0.897237 
4 0.376750 
5 0.336222 
0 0.451376 
1 0.840255 
2 0.123102 
3 0.543026 
4 0.373012 
5 0.447997 
0 0.129441 
1 0.859879 
2 0.820388 
3 0.352054 
4 0.228887 
5 0.776784 
0 0.594784 
1 0.137554 
2 0.852900 
3 0.235507 
4 0.146227 
5 0.589869 
0 0.574012 
1 0.061270 
2 0.590426 
3 0.245350 
4 0.340445 
5 0.984729 
dtype: float64 

J'ai besoin de transformer cela en une trame de données avec plusieurs colonnes comme ceci:

In [70]: np.random.seed(123456) 

In [71]: pd.DataFrame(np.random.random((5,6))).transpose() 
Out[71]: 
      0   1   2   3   4 
0 0.126970 0.451376 0.129441 0.594784 0.574012 
1 0.966718 0.840255 0.859879 0.137554 0.061270 
2 0.260476 0.123102 0.820388 0.852900 0.590426 
3 0.897237 0.543026 0.352054 0.235507 0.245350 
4 0.376750 0.373012 0.228887 0.146227 0.340445 
5 0.336222 0.447997 0.776784 0.589869 0.984729 

J'ai vérifié pivot et groupBy mais ne pouvait pas comprendre comment les amener à travailler pour ça.

Répondre

2

Si les valeurs 0 de l'indice peuvent être des bords des groupes, vous pouvez d'abord créer DataFrame de Serie, puis groups par cumsum et dernier pivot:

df = pd.DataFrame({'a':b}) 
df['g'] = (df.index == 0).cumsum() 
print (df) 
      a g 
0 0.126970 1 
1 0.966718 1 
2 0.260476 1 
3 0.897237 1 
4 0.376750 1 
5 0.336222 1 
0 0.451376 2 
1 0.840255 2 
2 0.123102 2 
3 0.543026 2 
4 0.373012 2 
5 0.447997 2 
0 0.129441 3 
1 0.859879 3 
2 0.820388 3 
3 0.352054 3 
4 0.228887 3 
5 0.776784 3 
0 0.594784 4 
1 0.137554 4 
2 0.852900 4 
3 0.235507 4 
4 0.146227 4 
5 0.589869 4 
0 0.574012 5 
1 0.061270 5 
2 0.590426 5 
3 0.245350 5 
4 0.340445 5 
5 0.984729 5 
print (pd.pivot(index=df.index, columns=df.g, values=df.a)) 
g   1   2   3   4   5 
0 0.126970 0.451376 0.129441 0.594784 0.574012 
1 0.966718 0.840255 0.859879 0.137554 0.061270 
2 0.260476 0.123102 0.820388 0.852900 0.590426 
3 0.897237 0.543026 0.352054 0.235507 0.245350 
4 0.376750 0.373012 0.228887 0.146227 0.340445 
5 0.336222 0.447997 0.776784 0.589869 0.984729 

Une autre solution plus générale avec cumcount :

df = pd.DataFrame({'a':b}) 

df['g'] = df.groupby(level=0)['a'].cumcount() + 1 

print (pd.pivot(index=df.index, columns=df.g, values=df.a)) 

g   1   2   3   4   5 
0 0.126970 0.451376 0.129441 0.594784 0.574012 
1 0.966718 0.840255 0.859879 0.137554 0.061270 
2 0.260476 0.123102 0.820388 0.852900 0.590426 
3 0.897237 0.543026 0.352054 0.235507 0.245350 
4 0.376750 0.373012 0.228887 0.146227 0.340445 
5 0.336222 0.447997 0.776784 0.589869 0.984729 
+0

Votre deuxième solution permet n'importe quelle valeur de départ, non codée en dur à 0? – Scimonster

+0

Vous pouvez ajouter '1' à' g', voir modifier. – jezrael

+0

Je voulais dire pour les index dans 'b'. Un peu de test a montré que c'est effectivement le cas. – Scimonster