熊猫柱的有条件回填

用户名

我有以下数据框:

     DATE       ID      STATUS
0  2014-01-01   1  INPROGRESS
1  2013-03-01   1       ENDED
2  2015-05-01   2  INPROGRESS
3  2012-05-01   1     STARTED
4  2011-05-01   2     STARTED
5  2011-03-01   3     STARTED
6  2011-04-01   3       ENDED
7  2011-06-01   3  INPROGRESS
8  2011-09-01   3     STARTED

这里是构建它的代码:

>>> df1 = pd.DataFrame(columns=["DATE", "ID", "STATUS"])
>>> df1["DATE"] = ['2014-01-01', '2013-03-01', '2015-05-01', '2012-05-01', '2011-05-01', '2011-03-01', '2011-04-01', '2011-06-01', '2011-09-01']
>>> df1["ID"] = [1,1,2,1,2,3,3,3,3]
>>> df1["STATUS"] = ['INPROGRESS', 'ENDED', 'INPROGRESS', 'STARTED', 'STARTED', 'STARTED','ENDED', 'INPROGRESS', 'STARTED']

对于每个ID组,状态列表示一个任务,该任务可以是:

已开始,正在进行或已结束

在此精确的时间顺序中(STARTED不应在ENDED之后等。)。

通过按ID分组并按日期排序,我得到ID 3:

df1.sort_values('DATE')[df1['ID']==3]

     DATE        ID      STATUS
 5  2011-03-01   3     STARTED
 6  2011-04-01   3       ENDED
 7  2011-06-01   3  INPROGRESS
 8  2011-09-01   3     STARTED

否,我不需要“修复”状态列即可根据上一个状态遵循上述定义的顺序对于ID 3,最后一个状态已启动,因此应将所有内容回填到启动状态,如下所示:

     DATE        ID      STATUS
 5  2011-03-01   3     STARTED
 6  2011-04-01   3     STARTED
 7  2011-06-01   3     STARTED
 8  2011-09-01   3     STARTED

对于ID 1:

df1.sort_values('DATE')[df1['ID']==1]
     DATE  ID      STATUS
3  2012-05-01   1     STARTED
1  2013-03-01   1       ENDED
0  2014-01-01   1  INPROGRESS

我最终将拥有最后两个状态“正在进行”,而将第一个状态保留为“已开始”,例如:

df1.sort_values('DATE')[df1['ID']==1]
     DATE  ID      STATUS
3  2012-05-01   1     STARTED
1  2013-03-01   1  INPROGRESS
0  2014-01-01   1  INPROGRESS

ID 2具有正确的顺序。

知道如何使用熊猫吗?我正在尝试按ID进行分组,并且正在考虑根据上次状态进行回填,但是我不知道如何在适当的时候停止回填。

谢谢!

臀部

一种经典的方法是忘记状态标签,而不是将它们视为严格递增的数字,例如开始1,进行中2和结束3。有了这样的列,您现在可以检查每组这些数字的单调性,然后回填直到看到单调的破坏。

准备您的数据框:

keymapping = {'STARTED':0, 'INPROGRESS':1, 'ENDED':2}
df['STATUS_ID'] = df.STATUS.map(keymapping)
df.set_index(['ID', 'DATE'], inplace=True)
df.sort_index(inplace=True)

现在,按ID分组并用于transform获取散布在整个索引中的每个分组的最后一个值,以便您可以将其作为新列分配给数据框:

df['STATUS_LAST'] = df.groupby(level=0, as_index=False).STATUS_ID.transform('last')

df
Out[63]: 
                   STATUS  STATUS_ID  STATUS_LAST
ID DATE                                          
1  2012-05-01     STARTED          0            1
   2013-03-01       ENDED          2            1
   2014-01-01  INPROGRESS          1            1
2  2011-05-01     STARTED          0            1
   2015-05-01  INPROGRESS          1            1
3  2011-03-01     STARTED          0            0
   2011-04-01       ENDED          2            0
   2011-06-01  INPROGRESS          1            0
   2011-09-01     STARTED          0            0

最后,通过使用STATUS_ID对过去的递增单调性来应用回填,即,STATUS_ID当if小于或等于时,的每个值均有效STATUS_LAST

df.STATUS_ID = df.STATUS_ID.where(df.STATUS_ID <= df.STATUS_LAST, df.STATUS_LAST)
df.STATUS_ID
Out[65]: 
ID  DATE      
1   2012-05-01    0
    2013-03-01    1
    2014-01-01    1
2   2011-05-01    0
    2015-05-01    1
3   2011-03-01    0
    2011-04-01    0
    2011-06-01    0
    2011-09-01    0

将其反向映射到标签,并将其分配给STATUS

df.STATUS_ID.map({v:k for k,v in keymapping.items()})
Out[66]: 
ID  DATE      
1   2012-05-01       STARTED
    2013-03-01    INPROGRESS
    2014-01-01    INPROGRESS
2   2011-05-01       STARTED
    2015-05-01    INPROGRESS
3   2011-03-01       STARTED
    2011-04-01       STARTED
    2011-06-01       STARTED
    2011-09-01       STARTED
Name: STATUS_ID, dtype: object

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章