[英]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.