2017-09-07 3 views
0

Elaborate würde Ich mag die unten Pandas Datenrahmen zu transformieren:Wie Reihen in Pandas

dd = pd.DataFrame({ "zz":[1,3], "y": ["a","b"], "x": [[1,2],[1]]}) 

     x y z 
0 [1, 2] a 1 
1 [1] b 3 

in:

  x y z 
    0 1  a 1 
    1 1  b 3 
    2 2  a 1 

Wie Sie ist die erste Zeile in den Spalten X sehen erarbeitet in seine einzelne Elemente beim Wiederholen der anderen Spalten y, z. Kann ich das tun, ohne eine for-Schleife zu verwenden?

Antwort

2

Verwendung:

#get lengths of lists 
l = dd['x'].str.len() 

df = dd.loc[dd.index.repeat(l)].assign(x=np.concatenate(dd['x'])).reset_index(drop=True) 
print (df) 
    x y zz 
0 1 a 1 
1 2 a 1 
2 1 b 3 

Aber wenn Reihenfolge ist wichtig:

df1 = pd.DataFrame(dd['x'].values.tolist()) 
          .stack() 
          .sort_index(level=[1,0]) 
          .reset_index(name='x') 
print (df1) 
    level_0 level_1 x 
0  0  0 1.0 
1  1  0 1.0 
2  0  1 2.0 

df = df1.join(dd.drop('x',1), on='level_0').drop(['level_0','level_1'], 1) 
print (df) 
    x y zz 
0 1.0 a 1 
1 1.0 b 3 
2 2.0 a 1 
0

Mit join und stack Sie können

In [655]: dd.drop('x', 1).join(
      dd.apply(lambda x: pd.Series(x.x), axis=1) 
       .stack().reset_index(level=1, drop=True).to_frame('x')) 
Out[655]: 
    y z x 
0 a 1 1.0 
0 a 1 2.0 
1 b 3 1.0 

Einzelheiten

In [656]: dd.apply(lambda x: pd.Series(x.x), axis=1).stack().reset_index(level=1,drop=True) 
Out[656]: 
0 1.0 
0 2.0 
1 1.0 
dtype: float64 

In [657]: dd 
Out[657]: 
     x y z 
0 [1, 2] a 1 
1  [1] b 3 
0
new_dd = pd.DataFrame(dd.apply(lambda x: pd.Series(x['x']),axis=1).stack().reset_index(level=1, drop=True)) 

new_dd.columns = ['x'] 

new_dd.merge(dd[['y','zz']], left_index=True, right_index=True)