2017-11-17 128 views
1

我沒有什麼運氣來完成一項任務,我想要一個熊貓數據框的子集高達一個值,並按他們的ID分組。在實際的數據集,我有幾個列在 '身份證' 和 '狀態'子集熊貓數據框達到條件時第一次

之間。例如:

d = {'id': [1,1,1,1,1,1,1,2,2,2,2,2,2,2], 'status': [0,0,0,0,1,1,1,0,0,0,0,1,0,1]} 
df = pd.DataFrame(data=d) 

    id status 
0 1  0 
1 1  0 
2 1  0 
3 1  0 
4 1  1 
5 1  1 
6 1  1 
7 2  0 
8 2  0 
9 2  0 
10 2  0 
11 2  1 
12 2  0 
13 2  1 

所需的子集是:

id status 
0 1  0 
1 1  0 
2 1  0 
3 1  0 
4 1  1 
5 2  0 
6 2  0 
7 2  0 
8 2  0 
9 2  1 

回答

2

讓我們嘗試groupby + cumsum

df = df.groupby('id', group_keys=False)\ 
     .apply(lambda x: x[x.status.cumsum().cumsum().le(1)])\ 
     .reset_index(drop=1) 
df 

    id status 
0 1  0 
1 1  0 
2 1  0 
3 1  0 
4 1  1 
5 2  0 
6 2  0 
7 2  0 
8 2  0 
9 2  1 

下面是執行groupby創建蒙用作索引器替代:

df = df[df.status.eq(1).groupby(df.id)\ 
      .apply(lambda x: x.cumsum().cumsum().le(1))]\ 
      .reset_index(drop=1) 
df 

    id status 
0 1  0 
1 1  0 
2 1  0 
3 1  0 
4 1  1 
5 2  0 
6 2  0 
7 2  0 
8 2  0 
9 2  1 
+0

謝謝@COLDSPEED。你能解釋兩次使用.cumsum()。cumsum()嗎?我看到輸出的差異,但不完全理解它。 –

+0

@DarenEiri我不得不在你的MCVE上表揚你,因爲我意識到這是必要的。說'status'是'0 0 0 1 0 1'。我需要前4行,對嗎?第一個'cumsum'給出'0 0 0 1 1 2'。基於'> = 1'(或'le(1)')條件,它會給我前5行,而我想要4。第二個'cumsum'給我'0 0 0 1 2 4',現在'le(1)'只給出我想要的前4行。 –

+0

@COLDSPEED。謝謝你的解釋。我在無數次失敗的嘗試中使用了'cumsum'方法,但是使用'le(1)'的第二個'cumsum'則有所不同! –