如何过滤将行保留在 Pandas 列中特定单词列表之后的 DataFrame?

如何过滤在按日期排序的特定单词列表之后保留行的数据框?我有一个看起来像的 df


    Name    Date    Event   Col1

0   Sam 1/1/2020    Apple   Test1

1   Sam 1/2/2020    Apple   Test2

2   Sam 1/3/2020    BALL    Test1

3   Sam 1/3/2020    CAT Test2

4   Sam 1/5/2020    BALL    Test2

5   Sam 1/6/2020    Apple   Test3

6   Nick    1/5/2020    CAT Test3

7   Nick    1/6/2020    BALL    Test3

8   Nick    1/7/2020    Apple   Test3

9   Nick    1/8/2020    Apple   Test4

10  Cat 1/1/2020    Apple   Test1

11  Cat 1/2/2020    Bat Test2





 df=pd.DataFrame({'Name': {0: 'Sam',

  1: 'Sam',

  2: 'Sam',

  3: 'Sam',

  4: 'Sam',

  5: 'Sam',

  6: 'Nick',

  7: 'Nick',

  8: 'Nick',

  9: 'Nick',

  10: 'Cat',

  11: 'Cat '},

 'Date': {0: '1/1/2020',

  1: '1/2/2020',

  2: '1/3/2020',

  3: '1/3/2020',

  4: '1/5/2020',

  5: '1/6/2020',

  6: '1/5/2020',

  7: '1/6/2020',

  8: '1/7/2020',

  9: '1/8/2020',

  10: '1/1/2020',

  11: '1/2/2020'},

 'Event': {0: 'Apple',

  1: 'Apple',

  2: 'BALL',

  3: 'CAT',

  4: 'BALL',

  5: 'Apple',

  6: 'CAT',

  7: 'BALL',

  8: 'Apple',

  9: 'Apple',

  10: 'Apple',

  11: 'Bat'},

 'Col1': {0: 'Test1',

  1: 'Test2',

  2: 'Test1',

  3: 'Test2',

  4: 'Test2',

  5: 'Test3',

  6: 'Test3',

  7: 'Test3',

  8: 'Test3',

  9: 'Test4',

  10: 'Test1',

  11: 'Test2'}})

我想保留在我的活动中发生 BALL 或 CAT 的最早日期之后的行。因此,在我的示例中,我需要消除第 1、2 行和第 11 行,因为我们将 Apple 作为第一个事件。


我尝试使用


event_filter = ['BALL','CAT']

df = df.loc[df['Event'].isin(event_filter)]

我还尝试删除基于事件的子集,但它也删除了第 8 行。


任何帮助,将不胜感激。我期待的结果是:


    Name    Date    Event   Col1

0   Sam 1/3/2020    BALL    Test1

1   Sam 1/3/2020    CAT Test2

2   Sam 1/5/2020    BALL    Test2

3   Sam 1/6/2020    Apple   Test3

4   Nick    1/5/2020    CAT Test3

5   Nick    1/6/2020    BALL    Test3

6   Nick    1/7/2020    Apple   Test3

7   Nick    1/8/2020    Apple   Test4

8   Cat 1/2/2020    Bat Test2


哆啦的时光机
浏览 177回答 2
2回答

临摹微笑

这样的事情怎么样?另外,好像有错别字。最后一行是 Bat,这应该是 BALL 吗?(根据您的预期输出)lst = ['CAT', 'BALL']检查事件中是否存在列表的选定元素。存在则赋1,不存在则赋0。df['C'] = np.where(df['Event'].isin(lst), 1, 0)在此之后,我们可以对 C 列执行 cumsum 并过滤行。这可以通过在 Name 上使用 groupby 并在 c 列上执行 cumsum 并检查是否存在大于 0 的 cumsum 来完成。只有当该 groupby (Name) 的事件中存在列表的那些元素时,才会发生大于 0 的情况df = df.loc[df.groupby('Name')['C'].cumsum()>0].reset_index(drop=True)df.drop('C', 1, inplace=True)print (df)   Name      Date  Event   Col10   Sam  1/3/2020   BALL  Test11   Sam  1/3/2020    CAT  Test22   Sam  1/5/2020   BALL  Test23   Sam  1/6/2020  Apple  Test34  Nick  1/5/2020    CAT  Test35  Nick  1/6/2020   BALL  Test36  Nick  1/7/2020  Apple  Test37  Nick  1/8/2020  Apple  Test4

慕勒3428872

这有点难以理解(您是否将事件过滤器从 Bat 切换为 BALL?:D),而且您似乎正在尝试让每个人获得第一个事件?如果是这样,我认为您需要按名称拆分数据框,根据需要进行过滤,然后重新组合。这是第一次出现的小函数:def get_min_index(ser, event_filter):    in_event = ser.isin(event_filter)    return in_event.loc[in_event].index[0]然后假设您的 df 已经按照您的需要进行了排序。tdf_lst = []names = df['Name'].unique()for name in names:    tdf = df.loc[df['Name']==name, :] # filter for the individual name    min_idx = get_min_index(tdf['Event'], event_filter) # get the first index    tdf = tdf.loc[min_idx:,:] # select from the first index to the last    tdf_lst.append(tdf)    df_fltrd = pd.concat(tdf_lst)也许有一个更优雅的解决方案,但希望这就是您正在寻找的
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python