[英]how to use groupby to avoid loop in python
數據中有幾列,其中三列名為“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)
循環確實需要一些時間來刪除冗余行。 有更快的方法嗎?
如果數據結構與您描述的完全一致,則可以使用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
假設數據按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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.