Python - Pandas数据帧列交换

时间:2016-12-15 05:40:58

标签: python pandas dataframe

我有一个如下所示的数据框:

  |    A     |     B     |     C     |     D
0 |  a |  b  |  c  |  d  |  e  |  f  |  g  |  h
1 |  a |  b  |  c  |  d  |  e  |  f  | NaN | NaN
2 |  a |  b  | NaN | NaN |  e  |  f  | NaN | NaN
3 |  a |  b  | NaN | NaN | NaN | NaN | NaN | NaN

我希望将其更改为:

    OBJ   VAL1   VAL2
0    A     a      b
1    A     a      b
2    A     a      b
3    A     a      b
4    A     a      b
5    A     a      b
6    B     c      d
7    B     c      d
8    C     e      f
9    C     e      f
10   C     e      f
11   D     g      h

因此多索引也将转换为列。

有什么帮助吗?

是否有任何好的教程可以解释那些东西,所以我能够做到这一点而不仅仅是尝试和错误?

谢谢

修改: 我的第一个原始数据框如下所示:

      A       B       C       D
0   (a,b)   (c,d)   (e,f)   (g,h)
1   (a,b)   (c,d)   (e,f)    NaN
2   (a,b)    NaN    (e,f)    NaN
3   (a,b)    NaN     NaN     NaN

因此在每个单元格中都有一个元组。

1 个答案:

答案 0 :(得分:2)

您可以先使用DataFrame.from_records,然后使用reset_index加倍,并在必要时使用sort_values对所有列进行排序:

df = pd.DataFrame({"A": [('a','b'),('a','b'),('a','b'),('a','b')], 
                   'B': [('c','d'),('c','d'), np.nan,np.nan], 
                   'C':[('e','f'),('e','f'),('e','f'),np.nan],
                   'D':[('g','h'),np.nan,np.nan,np.nan]})
print (df)
        A       B       C       D
0  (a, b)  (c, d)  (e, f)  (g, h)
1  (a, b)  (c, d)  (e, f)     NaN
2  (a, b)     NaN  (e, f)     NaN
3  (a, b)     NaN     NaN     NaN

stacked = df.stack()
df1 = pd.DataFrame.from_records(stacked.tolist(), index = stacked.index)
        .reset_index(level=0, drop=True)
        .reset_index()
        .sort_values(['index',0,1])
df1.columns = ['OBJ','VAL1','VAL2']
print (df1)
  OBJ VAL1 VAL2
0   A    a    b
4   A    a    b
7   A    a    b
9   A    a    b
1   B    c    d
5   B    c    d
2   C    e    f
6   C    e    f
8   C    e    f
3   D    g    h

如果您的DataFrame列中包含MultiIndex,则首先需要stack

stacked = df.stack()
df1 = pd.DataFrame.from_records(stacked.tolist(), index = stacked.index) \
        .unstack(1) \
        .swaplevel(0, 1, 1) \
        .sort_index(axis=1) \
        .replace({None:np.nan})

print (df1)
   A       B         C         D     
   0  1    0    1    0    1    0    1
0  a  b    c    d    e    f    g    h
1  a  b    c    d    e    f  NaN  NaN
2  a  b  NaN  NaN    e    f  NaN  NaN
3  a  b  NaN  NaN  NaN  NaN  NaN  NaN

df2 = df1.stack(0)
         .reset_index(level=0, drop=True)
         .reset_index()
         .sort_values(['index',0,1])

df2.columns = ['OBJ','VAL1','VAL2']
print (df2)
  OBJ VAL1 VAL2
0   A    a    b
4   A    a    b
7   A    a    b
9   A    a    b
1   B    c    d
5   B    c    d
2   C    e    f
6   C    e    f
8   C    e    f
3   D    g    h