创建公共列并转换时间序列,如数据

时间:2019-07-30 07:10:23

标签: python python-3.x pandas list dataframe

我有一个Excel工作表,其中包含30多个工作表,用于不同的参数,例如BP,心率等。

其中一个数据框(df1-由一张excel创建)看起来如下所示

df1= pd.DataFrame({'person_id':[1,1,1,1,2,2,2,2,3,3,3,3,3,3],'level_1': ['H1Date','H1','H2Date','H2','H1Date','H1','H2Date','H2','H1Date','H1','H2Date','H2','H3Date','H3'],
               'values': ['2006-10-30 00:00:00','6.6','2006-08-30 00:00:00','4.6','2005-10-30 00:00:00','6.9','2016-11-30 00:00:00','6.6','2006-10-30 00:00:00','6.6','2006-11-30 00:00:00','8.6',
                       '2106-10-30 00:00:00','16.6']})

enter image description here

可以使用下面的代码生成另一张excel文件中的另一个数据框(df2)

df2= pd.DataFrame({'person_id':[1,1,1,1,2,2,2,2,3,3,3,3,3,3],'level_1': ['GluF1Date','GluF1','GluF2Date','GluF2','GluF1Date','GluF1','GluF2Date','GluF2','GluF1Date','GluF1','GluF2Date','GluF2','GluF3Date','GluF3'],
               'values': ['2006-10-30 00:00:00','6.6','2006-08-30 00:00:00','4.6','2005-10-30 00:00:00','6.9','2016-11-30 00:00:00','6.6','2006-10-30 00:00:00','6.6','2006-11-30 00:00:00','8.6',
                       '2106-10-30 00:00:00','16.6']})

类似地,有30多个这样的数据帧,它们的值具有相同的格式(日期和测量值),但列名(H1,GluF1,H1Date,H100,H100Date,GluF1Date,P1,PDate,UACRDate,UACR100等)不一样

基于SO搜索,我想做的事情如下所示

g = df1.level_1.str[-2:] # Extracting column names
    df1['lvl'] = df1.level_1.apply(lambda x: int(''.join(filter(str.isdigit, x)))) # Extracting level's number
    df1= df1.pivot_table(index=['person_id', 'lvl'], columns=g, values='values', aggfunc='first')
    final = df1.reset_index(level=1).drop(['lvl'], axis=1)

上面的代码给出了这样的预期输出

enter image description here

这不起作用,因为g不会对所有记录产生相同的字符串输出(列名)。如果子字符串提取得到相同的输出,我的代码将起作用,但是由于数据就像序列,所以我无法使其统一

我希望每个数据帧的输出如下所示。请注意,一个人可以拥有3条记录(H1..H3)/ 10条记录(H1..H10)/ 100条记录(例如:H1 ... H100)。都有可能。

enter image description here

更新的屏幕截图

enter image description here

2 个答案:

答案 0 :(得分:1)

在不使用列名的情况下合并所有偶数行和所有奇数行,然后根据需要命名列:

res = pd.concat([df2.iloc[0::2,0:3:2].reset_index(drop=True), df2.iloc[1::2,2].reset_index(drop=True)], axis=1)
res.columns = ['Person_ID', 'Date', 'Value']

输出:

   Person_ID                 Date Value
0          1  2006-10-30 00:00:00   6.6
1          1  2006-08-30 00:00:00   4.6
2          2  2005-10-30 00:00:00   6.9
3          2  2016-11-30 00:00:00   6.6
4          3  2006-10-30 00:00:00   6.6
5          3  2006-11-30 00:00:00   8.6
6          3  2106-10-30 00:00:00  16.6

答案 1 :(得分:1)

这是使用unstack()并作一些修改的一种方法:

使用,df1.groupby(['person_id',df1.level_1.str[:2]]).cumcount()

分配一个虚拟列

level_1更改为level_1=df1.level_1.str[:2]

将索引设置为['person_id','level_1','k']并在第三个索引上取消堆叠。

m=(df1.assign(k=df1.groupby(['person_id',df1.level_1.str[:2]]).cumcount()
        ,level_1=df1.level_1.str[:2]).
  set_index(['person_id','level_1','k']).unstack(2)).droplevel(1)
m.columns=['Date','Values']
print(m)

                         Date Values
person_id                            
1          2006-10-30 00:00:00    6.6
1          2006-08-30 00:00:00    4.6
2          2005-10-30 00:00:00    6.9
2          2016-11-30 00:00:00    6.6
3          2006-10-30 00:00:00    6.6
3          2006-11-30 00:00:00    8.6
3          2106-10-30 00:00:00   16.6