我有以下数据框:
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] 删除。
我来说两句