繁体   English   中英

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

[英]How can I filter a DataFrame that keeps the rows after a specific list of words in a columns in 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 的最早日期之后的行。 因此,在我的示例中,我需要消除第 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

有点难以理解(您是否将事件过滤器从 Bat 切换为 BALL?:D),并且您似乎正在尝试每人获取第一个事件?

如果是这样,我认为您需要按名称拆分 dataframe,根据需要过滤然后重新组合。

这是第一次出现的小 function:

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)

也许有一个更优雅的解决方案,但希望这就是您正在寻找的

这样的事情怎么样? 另外,好像有错别字。 最后一行是蝙蝠,这应该是球吗? (根据您的预期 output )

lst = ['CAT', 'BALL']

检查事件中是否存在列表的选定元素。 如果存在,给它1 如果不存在,给它0。

df['C'] = np.where(df['Event'].isin(lst), 1, 0)

在此之后,我们可以对 C 列进行 cumsum 并过滤行。 这可以通过在名称上使用 groupby 并对列 c 执行 cumsum 并检查是否存在大于 0 的 cumsum 来完成。大于 0 仅在该事件中存在该 groupby (名称)的列表元素时发生

df = df.loc[df.groupby('Name')['C'].cumsum()>0].reset_index(drop=True)
df.drop('C', 1, inplace=True)
print (df)

   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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM