旋转两列数据帧

act*_*nda 5 python pandas

我有一个数据帧 untidy

  attribute value
0       age    49
1       sex     M
2    height   176
3       age    27
4       sex     F
5    height   172
Run Code Online (Sandbox Code Playgroud)

其中'attribute'列中的值定期重复.期望的输出是tidy

  age sex height
0  49   M    176
1  27   F    172
Run Code Online (Sandbox Code Playgroud)

(行和列顺序或其他标签无关紧要,我可以自己清理它.)

实例化代码:

untidy = pd.DataFrame([['age', 49],['sex', 'M'],['height', 176],['age', 27],['sex', 'F'],['height', 172]], columns=['attribute', 'value'])
tidy = pd.DataFrame([[49, 'M', 176], [27, 'F', 172]], columns=['age', 'sex', 'height']) 
Run Code Online (Sandbox Code Playgroud)

尝试

这看起来像一个简单的数据透视操作,但我的初始方法引入了NaN值:

>>> untidy.pivot(columns='attribute', values='value')                                                                                                       
attribute  age height  sex
0           49    NaN  NaN
1          NaN    NaN    M
2          NaN    176  NaN
3           27    NaN  NaN
4          NaN    NaN    F
5          NaN    172  NaN
Run Code Online (Sandbox Code Playgroud)

一些混乱的尝试来解决这个问题:

>>> untidy.pivot(columns='attribute', values='value').apply(lambda c: c.dropna().reset_index(drop=True))
attribute age height sex
0          49    176   M
1          27    172   F
Run Code Online (Sandbox Code Playgroud)


>>> untidy.set_index([untidy.index//untidy['attribute'].nunique(), 'attribute']).unstack('attribute')
          value           
attribute   age height sex
0            49    176   M
1            27    172   F
Run Code Online (Sandbox Code Playgroud)

这样做的惯用方法是什么?

jez*_*ael 3

使用pandas.pivotwithGroupBy.cumcount作为新索引值和rename_axis删除列名称:

df = pd.pivot(index=untidy.groupby('attribute').cumcount(),
              columns=untidy['attribute'], 
              values=untidy['value']).rename_axis(None, axis=1) 
print (df)
  age height sex
0  49    176   M
1  27    172   F
Run Code Online (Sandbox Code Playgroud)

另一个解决方案:

df = (untidy.set_index([untidy.groupby('attribute').cumcount(), 'attribute'])['value']
            .unstack()
            .rename_axis(None, axis=1))
Run Code Online (Sandbox Code Playgroud)