数据中有几列,其中三列名为“candidate_id”,“enddate”,“TitleLevel”。
在同一个id中,如果enddate相同,我将删除较低级别的记录。
例如,给定:
candidate_id startdate enddate TitleLevel
1 2012.1.1 2013.5.1 2
1 2011.1.1 2013.5.1 4
1 2008.12.1 2010.1.1 3
2 2010.10.1 2012.12.1 2
我想要的是:
candidate_id startdate enddate TitleLevel
1 2011.1.1 2013.5.1 4
1 2008.12.1 2010.1.1 3
2 2010.10.1 2012.12.1 2
我将删除candidate_id=1
,enddate=2013.5.1
和titlelevel=2
。
我想出了一个循环。
for i in range(nrow-2,-1, -1):
if (JobData['enddate'][i] == JobData['enddate'][i+1]
and JobData['candidate_id'][i] == JobData['candidate_id'][i+1]
and pd.notnull(JobData['enddate'][i]):
if JobData['TitleLevel'][i] > JobData['TitleLevel'][i+1]:
JobData= JobData.drop(i+1)
else:
JobData= JobData.drop(i)
循环确实需要一些时间来删除冗余行。有更快的方法吗?
答案 0 :(得分:2)
如果数据结构与您描述的完全一致,则可以使用groupby
/ max
:
>>> df
candidate_id enddate TitleLevel
0 1 2013.5.1 2
1 1 2013.5.1 4
2 1 2010.1.1 3
3 2 2012.12.1 2
>>> df.groupby(['candidate_id','enddate']).max().reset_index()
candidate_id enddate TitleLevel
0 1 2010.1.1 3
1 1 2013.5.1 4
2 2 2012.12.1 2
此处groupby将行分为candidate_id
和enddate
,max()
评估每个组中的最大TitleLevel
。结果与删除所有其他值的行相同。
如果您有更多列,
>>> df
candidate_id enddate TitleLevel other_column
0 1 2013.5.1 2 foo
1 1 2013.5.1 4 bar
2 1 2010.1.1 3 foobar
3 2 2012.12.1 2 barfoo
您可以获取具有最大值的行的idex,如果必须保留行顺序,则不进行排序:
>>> idx = df.groupby(['candidate_id','enddate'], sort=False)['TitleLevel'].agg(lambda x: x.idxmax())
并使用ix
过滤所需的行:
>>> df.ix[idx]
candidate_id enddate TitleLevel other_column
1 1 2013.5.1 4 bar
2 1 2010.1.1 3 foobar
3 2 2012.12.1 2 barfoo
答案 1 :(得分:1)
假设数据按startdate排序(至少在每个组中),您可以使用groupby last:
In [11]: df.groupby(['candidate_id', 'enddate'], as_index=False).last()
Out[11]:
candidate_id enddate startdate TitleLevel
0 1 2010.1.1 2008.12.1 3
1 1 2013.5.1 2011.1.1 4
2 2 2012.12.1 2010.10.1 2