Python 如何根据条件从dataframe中删除行

Python 如何根据条件从dataframe中删除行,python,pandas,Python,Pandas,我有以下带有(“ID”、“月份”和“状态”)的数据框。状态是关于“搅动”=1和“不搅动”=2。我想删除除第一次出现之外已经搅动的ID的所有行。例如: 数据帧 ID Month Status 2310 201708 2 2310 201709 2 2310 201710 1 2310 201711 1 2310 201712 1 2310 201801 1 2311

我有以下带有(“ID”、“月份”和“状态”)的数据框。状态是关于“搅动”=1和“不搅动”=2。我想删除除第一次出现之外已经搅动的ID的所有行。例如:

数据帧

    ID      Month   Status
    2310    201708  2
    2310    201709  2
    2310    201710  1
    2310    201711  1
    2310    201712  1
    2310    201801  1
    2311    201704  2
    2311    201705  2
    2311    201706  2
    2311    201707  2
    2311    201708  2
    2311    201709  2
    2311    201710  1
    2311    201711  1
    2311    201712  1
    2312    201708  2
    2312    201709  2
    2312    201710  2
    2312    201711  1
    2312    201712  1
    2312    201801  1
删除后,我应该有以下数据帧

    ID      Month   Status
    2310    201708  2
    2310    201709  2
    2310    201710  1

    2311    201704  2
    2311    201705  2
    2311    201706  2
    2311    201707  2
    2311    201708  2
    2311    201709  2
    2311    201710  1

    2312    201708  2
    2312    201709  2
    2312    201710  2
    2312    201711  1
我尝试了以下方法-首先查找每个客户ID的最小日期,状态=1

    df1=df[df.Status==1].groupby('ID')['Month'].min()
然后,我必须删除状态1大于月份最小值的每个ID的所有行。

如果您熟悉获取最近一个月元素的索引,您可以尝试:

# find minimum months
min_df = df.groupby(['ID','Status'])['Month'].idxmin().reset_index(drop=True)
# find indices of status 2 rows
df2 = df[df['Status'].eq(2)].index.to_series()
# append indices together
idx_df = min_df.append(df2).drop_duplicates()
# filter indices
df_new = df.iloc[idx_df].sort_index()

更新

或者,您可以考虑使用:


更新2

但是,如果您只是想删除最早月份行之后的所有状态1行,那么您可以简单地
排序\u值
转换

df = df.sort_values(by=['ID','Month']).reset_index(drop=True) 
df = df[df.groupby('ID')['Status'].transform(lambda x: ~(x.duplicated() & (x == 1)))]


IIUC,您可以使用
groupby
transform
以及布尔逻辑,然后使用布尔索引:

df[df.groupby('ID')['Status'].transform(lambda x: ~(x.duplicated() & (x == 1)))]
输出:

      ID   Month  Status
0   2310  201708       2
1   2310  201709       2
2   2310  201710       1
6   2311  201704       2
7   2311  201705       2
8   2311  201706       2
9   2311  201707       2
10  2311  201708       2
11  2311  201709       2
12  2311  201710       1
15  2312  201708       2
16  2312  201709       2
17  2312  201710       2
18  2312  201711       1

为什么以后当状态变为
1
时,你会得到
2311
的结果,这不应该是droppedI必须保留所有行直到第一次变为1。所以我保留ID值为2的所有行,以及状态变为1时的第一行。你能用这个逻辑更新你的帖子吗?请在中分享一些数据这是一种让其他人更容易测试解决方案的方法。它在实际数据帧上不起作用。状态为1的行仍然存在。您可以提供关于其余状态为1的行的任何信息吗?在您的示例中,ID和月份已经排序。如果它们没有在实际数据帧中排序,您可能无法收到预期的输出。就是这样!谢谢。同时,我发现了另一个关于客户流失和非客户流失状态的问题。情况1。客户处于非活动状态(状态=1),然后变为活动状态(状态=2)。如果在状态2情况2之前,我必须删除每个状态为1的客户的所有行。在观察期间,该客户仅处于状态=1。因此,如果在观察期间没有其他状态,我必须删除每个状态为1的客户的所有行tnx,dkhara,你是对的。你解决了我的问题。我打开了新的附加问题“根据groupby条件删除行”完成。您是否也可以看到第二个问题?可能您可以找到答案
df = df.sort_values(by=['ID','Month']).reset_index(drop=True) 
df = df[df.groupby('ID')['Status'].transform(lambda x: ~(x.duplicated() & (x == 1)))]
print(df)                                                              
      ID   Month  Status
0   2310  201708       2
1   2310  201709       2
2   2310  201710       1
6   2311  201704       2
7   2311  201705       2
8   2311  201706       2
9   2311  201707       2
10  2311  201708       2
11  2311  201709       2
12  2311  201710       1
15  2312  201708       2
16  2312  201709       2
17  2312  201710       2
18  2312  201711       1
df[df.groupby('ID')['Status'].transform(lambda x: ~(x.duplicated() & (x == 1)))]
      ID   Month  Status
0   2310  201708       2
1   2310  201709       2
2   2310  201710       1
6   2311  201704       2
7   2311  201705       2
8   2311  201706       2
9   2311  201707       2
10  2311  201708       2
11  2311  201709       2
12  2311  201710       1
15  2312  201708       2
16  2312  201709       2
17  2312  201710       2
18  2312  201711       1