我試圖找出一個代碼,如果 'STATUS' == 0,則洗掉相同 'SCU_KEY' 的所有行。所以你會看到 SCU_KEY -> 5 的狀態為 0,所以我想洗掉所有SCU_KEY 的包含 5。這是一個示例資料幀和所需的輸出。
資料框:
df = pd.DataFrame({'SCU_KEY': [3, 3, 3, 5, 5, 5, 5, 5, 16, 16, 16],
'STATUS' : [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]})
期望的輸出:
df_2 = pd.DataFrame({'SCU_KEY': [3, 3, 3, 16, 16, 16],
'STATUS' : [1, 1, 1, 1, 1, 1]})
uj5u.com熱心網友回復:
使用groupby filter
# filter out all 'SCU_KEY' groups
# that have at least one 'STATUS' == 0
df2 = df.groupby('SCU_KEY').filter(lambda g: ~g['STATUS'].eq(0).any())
編輯 - 性能測驗
雖然我發現這個解決方案在某種程度上更慣用,但如果您的 DataFrame 很大,Corralien 的解決方案會更快。
設定
n = 500_000
max_groups = 20
df1 = pd.DataFrame({
'SCU_KEY': rng.integers(max_groups, size=n),
'STATUS': rng.integers(2, size=n)
})
結果
以下是比較結果
# Corralien's
>>> %timeit df1[~df1['SCU_KEY'].isin(df1.loc[df1['STATUS'] == 0, 'SCU_KEY'])]
15.2 ms ± 1.51 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
# My solution
>>> %timeit df1.groupby('SCU_KEY').filter(lambda g: ~g['STATUS'].eq(0).any())
59.4 ms ± 9.84 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Solution suggested by wwnde (see comments)
>>> %timeit df1[df1.groupby('SCU_KEY')['STATUS'].transform(lambda x: (x!=0).all())]
210 ms ± 12.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
uj5u.com熱心網友回復:
使用第一個過濾器查找 STATUS 等于 0 的 SCU_KEY,然后檢查 SCU_KEY 不等于您的第一個過濾器的所有行。
>>> df[~df['SCU_KEY'].isin(df.loc[df['STATUS'] == 0, 'SCU_KEY'])]
SCU_KEY STATUS
0 3 1
1 3 1
2 3 1
8 16 1
9 16 1
10 16 1
第一個過濾器:
>>> df.loc[df['STATUS'] == 0, 'SCU_KEY']
5 5
Name: SCU_KEY, dtype: int64
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/350810.html
