我有以下資料框:
id outcome
0 3 no
1 3 no
2 3 no
3 3 yes
4 3 no
5 5 no
6 5 no
7 5 yes
8 5 no
9 5 yes
10 6 no
11 6 no
12 6 yes
13 6 no
14 6 no
我想洗掉noa 之前序列開頭的結果yes,并保留所有其他no結果,因此輸出資料幀如下所示:
id outcome
3 3 yes
4 3 no
7 5 yes
8 5 no
9 5 yes
12 6 yes
13 6 no
14 6 no
目前我已經嘗試過這個:
df = pd.DataFrame(data={
'id': [3, 3, 3, 3, 3, 5, 5, 5, 5, 6, 6, 6, 6, 6],
'outcome': ['no', 'no', 'no', 'yes', 'no', 'no', 'no', 'yes', 'yes', 'no', 'no', 'yes', 'no', 'no']
})
df = df[df.groupby('id').outcome.transform(lambda x: x.ne('no'))]
但是,這只是洗掉了所有no結果。
我知道然后我需要獲取這些行的索引并將它們從資料框中洗掉。有什么建議?
uj5u.com熱心網友回復:
使用groupbywithcumsum在開頭用 0 標記所有“否”:
df['no_group'] = df.groupby('id')['outcome'].apply(lambda x: x.eq('yes').cumsum())
現在,要洗掉的“否”數是:
num_no_to_remove = (df['no_group'] == 0).sum()
并且可以通過過濾獲得想要的資料幀:
df.loc[df['no_group'] > 0].drop(columns=['no_group'])
結果:
id outcome
3 3 yes
4 3 no
7 5 yes
8 5 no
9 5 yes
12 6 yes
13 6 no
14 6 no
uj5u.com熱心網友回復:
為了僅保留no每個組的最后一個值和所有yes值,此代碼將起作用:
df = df[(df.replace({'no': np.nan, 'yes': 1}).groupby('id')['outcome'].bfill() != 1) | (df['outcome'] == 'yes')]
輸出:
>>> df
id outcome
3 3 yes
4 3 no
5 3 no
8 5 yes
9 5 yes
12 6 yes
(在原版中df,我no在 group 末尾添加了第二個3以確保它no在末尾適用于 multiple )。
基本上代碼的作用是
- 在這種情況下
yes用任意值 (1)替換值 no用 NaN替換值(這很重要!)- 按 ID 對行進行分組
- 對于每個組,將最后一個非 NaN 行之前的所有 NaN 行替換為最后一個非 NaN 行的值。由于
yes的是1和no的為NaN,這將導致一切除最后no的基團的與任意數目被替換(1) - 創建一個選擇
no每個組的所有最后一個值的掩碼 - 創建選擇所有
yes值的第二個掩碼 - 使用這兩個掩碼組合回傳、所有
yes值以及no位于組末尾的所有值。
對于開始時關于no's計數的問題,我認為您應該為此提出一個新問題,因為這是一個必須以不同方式解決的不同問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/358214.html
上一篇:SerilogElasticSearch接收器不發送“訊息”欄位
下一篇:匹配資料框中的列并分解串列
