在Python中将数据框从垂直调整为水平

时间:2018-07-31 17:10:11

标签: python pandas dataframe data-analysis

我有一个数据库中的数据样本,我想在python中将其从垂直调整为水平,以进行进一步的数据分析。 数据框如下所示:

ID  measured_at  weight 
aa  2017-11-04   78.1
bb  2018-04-08   74.2
bb  2018-04-16   73.2
bb  2018-04-28   72.1
cc  2018-03-02   90.2
cc  2018-03-20   88.9

我希望它看起来像这样:

id  date1       weight1  date2       weight2  date3       weight3
aa  2017-11-04  78.1     NA          NA       NA          NA
bb  2018-04-08  74.2     2018-04-16  73.2     2018-04-28  72.1
cc  2018-03-02  90.2     2018-03-20  88.9     NA          NA

某些ID的测量值超过3,因此需要为同一ID上的每个新测量值生成新的日期和权重列。

这怎么办?

3 个答案:

答案 0 :(得分:0)

您可以将GroupBylist一起使用两次,然后再使用pd.concat

我将重命名列和将索引提升到列作为练习。

g = df.groupby('ID')
df_dates = pd.DataFrame(g['measured_at'].apply(list).values.tolist(), index=g.groups)
df_weights = pd.DataFrame(g['weight'].apply(list).values.tolist(), index=g.groups)

df_dates.columns = df_dates.columns * 2
df_weights.columns = df_weights.columns * 2 + 1

res = pd.concat([df_dates, df_weights], axis=1).sort_index(1)

print(res)

             0     1           2     3           4     5
aa  2017-11-04  78.1        None   NaN        None   NaN
bb  2018-04-08  74.2  2018-04-16  73.2  2018-04-28  72.1
cc  2018-03-02  90.2  2018-03-20  88.9        None   NaN

答案 1 :(得分:0)

IIUC使用cumcount创建帮助键。

df['helpkey']=df.groupby('ID').cumcount()+1
newdf=df.set_index(['ID','helpkey']).unstack().sort_index(level=1,axis=1)
newdf.columns=newdf.columns.map('{0[0]}_{0[1]}'.format)
newdf
Out[608]: 
   measured_at_1  weight_1 measured_at_2  weight_2 measured_at_3  weight_3
ID                                                                        
aa    2017-11-04      78.1          None       NaN          None       NaN
bb    2018-04-08      74.2    2018-04-16      73.2    2018-04-28      72.1
cc    2018-03-02      90.2    2018-03-20      88.9          None       NaN

答案 2 :(得分:0)

groupbynth一起使用:

d2 = df.groupby('ID')
new_df = pd.DataFrame()
for i in range(len(d2)):
    new_df = pd.concat([new_df, d2.nth(i).add_suffix(i+1)], axis=1) 

给出

   measured_at1  weight1 measured_at2  weight2 measured_at3  weight3
aa   2017-11-04     78.1          NaN      NaN          NaN      NaN
bb   2018-04-08     74.2   2018-04-16     73.2   2018-04-28     72.1
cc   2018-03-02     90.2   2018-03-20     88.9          NaN      NaN