Python 3.x 如何基于另一行更新数据帧?
我有一个测量学生成绩的数据框Python 3.x 如何基于另一行更新数据帧?,python-3.x,pandas,Python 3.x,Pandas,我有一个测量学生成绩的数据框student,如下所示: ID TestDate PerformanceStatus (PS) 1 15/03/2016 0 1 01/04/2016 2 1 05/05/2016 1 1 07/06/2016 1 2 15/03/2016 0 2 01/04/2016 2 2 05/05/2016 1 2 07/06/2016 3 2 23/08/2016 1 我想更新我的表,使其具有一个新列Prev
student
,如下所示:
ID TestDate PerformanceStatus (PS)
1 15/03/2016 0
1 01/04/2016 2
1 05/05/2016 1
1 07/06/2016 1
2 15/03/2016 0
2 01/04/2016 2
2 05/05/2016 1
2 07/06/2016 3
2 23/08/2016 1
我想更新我的表,使其具有一个新列PreviousPerformanceStatus。
此先前的performanceStatus是根据监控的performanceStatus计算的,如下所示:
注意:如果在测试日期之前没有记录performanceStatus,我想将PreviousPerformanceStatus=performanceStatus设置为
ID TestDate PS PreviousPerformanceStatus
1 15/03/2016 0 0
1 01/04/2016 2 0
1 05/05/2016 1 2
1 07/06/2016 1 1
2 15/03/2016 0 0
2 01/04/2016 2 0
2 05/05/2016 1 2
2 07/06/2016 3 1
2 23/08/2016 1 3
我可以用SQL语句来实现这一点,但是如何用pandas更新我的数据帧呢。
谢谢
例如:
(对于ID=1的情况)先前的PerformanceStatus是基于“更早”测试日期的PerformanceStatus计算的,因此当TestDate=01/04/2016时,我想使用TestDate=15/03/2016的数据。但是,如果我找不到任何以前的数据,我将使用PerformanceStatus中的值默认先前的PerformanceStatus,并在'ID'
上执行groupby
,然后使用和:
如果事先知道数据帧将正确排序,则可以跳过日期转换和排序
结果输出:
ID TestDate PS PrevPS
0 1 2016-03-15 0 0
1 1 2016-04-01 2 0
2 1 2016-05-05 1 2
3 1 2016-06-07 1 1
4 2 2016-03-15 0 0
5 2 2016-04-01 2 0
6 2 2016-05-05 1 2
7 2 2016-06-07 3 1
8 2 2016-08-23 1 3
在'ID'
上执行分组,并使用和:
如果事先知道数据帧将正确排序,则可以跳过日期转换和排序
结果输出:
ID TestDate PS PrevPS
0 1 2016-03-15 0 0
1 1 2016-04-01 2 0
2 1 2016-05-05 1 2
3 1 2016-06-07 1 1
4 2 2016-03-15 0 0
5 2 2016-04-01 2 0
6 2 2016-05-05 1 2
7 2 2016-06-07 3 1
8 2 2016-08-23 1 3
为什么要使用bfill
?下一行也会这样做,例如df['PrevPS']=df['PS'].shift();df['PrevPS']=df['PrevPS'].fillna(0).astype(int)
@discort:为了说明“如果在测试日期之前没有记录performanceStatus,我想使PreviousPerformanceStatus=performanceStatus”的要求。单独使用shift
将在第一个位置引入NaN
。你不能仅仅用零填充,因为我认为不能保证第一个状态为零;示例数据中正好是这样。@discort:如果我正确阅读了问题,您需要执行groupby
,因为移位是在'ID'
级别进行的,而不是在数据帧上全局进行的。例如,对于您发布的代码,ID 2的“Previous”列的第一个条目将为1,而不是示例输出中显示的0。您能解释这一行吗df['PrevPS']=df.groupby('ID')['PS'].apply(lambda-grp:grp.shift().bfill()).astype(int)
为什么要使用bfill
?接下来的几行也会这样做,例如df['PrevPS']=df['PS'].shift();df['PrevPS']=df['PrevPS'].fillna(0).astype(int)
@discort:为了说明“如果在测试日期之前没有记录performanceStatus,我想使PreviousPerformanceStatus=performanceStatus”的要求。单独使用shift
将在第一个位置引入NaN
。你不能仅仅用零填充,因为我认为不能保证第一个状态为零;示例数据中正好是这样。@discort:如果我正确阅读了问题,您需要执行groupby
,因为移位是在'ID'
级别进行的,而不是在数据帧上全局进行的。例如,对于您发布的代码,ID 2的“Previous”列的第一个条目将为1,而不是示例输出中显示的0。您能解释这一行吗df['PrevPS']=df.groupby('ID')['PS'].apply(lambda-grp:grp.shift().bfill()).astype(int)