python 查找Dataframe中的最后n组行

30byixjq  于 2023-02-07  发布在  Python
关注(0)|答案(3)|浏览(123)

我有一个包含测试数据的大型 Dataframe (1m+行)。在不同时间拍摄了"事件"的快照,每个快照最多向 Dataframe 添加三行。例如,在以下摘录中,事件At223的第一个快照拍摄于2016年3月18日18:10:45,第二个快照拍摄于2016年3月21日10:14:28,等等。
我想过滤 Dataframe ,以便它只返回每个参考的最后n个快照。参考是唯一的,而事件可以重复。
我是Pandas的新手,但尝试过sort_values,groupby和tail的各种组合,但都不能得到想要的结果。

df = df.sort_values(['Ref', 'Time']).groupby(['Time', 'Ref', 'TestId']).tail(3)

有谁能建议一下怎么做吗?在下面的结果示例中,n = 3,所以它显示了每个参考的最后三个快照。
提取物:
| 时间|参考|事件|结束时间|测试ID|测试名称|结果|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 2016年3月18日18时10分45秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年3月18日18时10分45秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个||
| 2016年3月18日18时10分45秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年3月21日10时14分28秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年3月21日10时14分28秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四个|
| 2016年3月21日10时14分28秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年3月21日12时44分34秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年3月21日12时44分34秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四、五|
| 2016年3月21日12时44分34秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年3月21日13时05分16秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年3月21日13时05分16秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四、五|
| 2016年3月21日13时05分16秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年3月21日13时14分22秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年3月21日13时14分22秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四、五|
| 2016年3月21日13时14分22秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年4月1日10:37:43|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年4月1日10:37:43|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四、五|
| 2016年4月1日10:37:43|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年3月18日18时12分12秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星28|八个|七|
| 2016年3月18日18时12分12秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星1212772|九|一点五八|
| 2016年3月18日18时12分12秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星588|十个|四、四|
| 2016年3月21日13时03分48秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星28|八个|七、二|
| 2016年3月21日13时03分48秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星1212772|九|一点五八|
| 2016年3月21日13时03分48秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星588|十个|四、四|
| 2016年3月21日13时19分15秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星28|八个|七、二|
| 2016年3月21日13时19分15秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星1212772|九|一点五八|
| 2016年3月21日13时19分15秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星588|十个|四、五|
| 2016年4月1日12:48:13|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星28|八个|七、二|
| 2016年4月1日12:48:13|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星1212772|九|一点五九|
| 2016年4月1日12:48:13|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星588|十个|四、五|
预期结果:
| 时间|参考|事件|结束时间|测试ID|测试名称|结果|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 2016年3月21日13时05分16秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年3月21日13时05分16秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四、五|
| 2016年3月21日13时05分16秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年3月21日13时14分22秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年3月21日13时14分22秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四、五|
| 2016年3月21日13时14分22秒|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年4月1日10:37:43|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星28212|一个||
| 2016年4月1日10:37:43|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星466299|两个|四、五|
| 2016年4月1日10:37:43|一、一二三七一七九八五|阿223|2016年1月4日16:00|小行星588|三个||
| 2016年3月21日13时03分48秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星28|八个|七、二|
| 2016年3月21日13时03分48秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星1212772|九|一点五八|
| 2016年3月21日13时03分48秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星588|十个|四、四|
| 2016年3月21日13时19分15秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星28|八个|七、二|
| 2016年3月21日13时19分15秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星1212772|九|一点五八|
| 2016年3月21日13时19分15秒|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星588|十个|四、五|
| 2016年4月1日12:48:13|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星28|八个|七、二|
| 2016年4月1日12:48:13|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星1212772|九|一点五九|

| 2016年4月1日12:48:13|一、一二三七一九五一二|溴十二烷|2016年3月4日16:00|小行星588|十个|四、五|

j2qf4p5b

j2qf4p5b1#

你可以循环遍历每一个唯一的事件,并从每个事件中获取前n个事件,然后将结果连接在一起:

n = 3
event_dfs = []
for event in df['Event'].unique():
   sub_df = df.loc[df['Event'] == event]
   max_times = sub_df['Time'].nlargest(n=n)
   event_dfs.append(sub_df.loc[sub_df['Time'].isin(max_times)])

result = pd.concat(event_dfs)
xytpbqjk

xytpbqjk2#

分解日期并保留n个最高值(假设您的 Dataframe 已按时间排序)

# Number of snapshot you want to keep
n = 3 

# Create a boolean mask
m = (df.assign(val=pd.factorize(df['Time'])[0])
       .groupby('Ref')['val']
       .transform(lambda x: x.max() - x < n))

out = df[m]

输出:

>>> out
                   Time       Ref  Event           EndTime   TestId TestNames  Result
9   21/03/2016 13:05:16  1.123718  At223  01/04/2016 16:00    28212       One     NaN
10  21/03/2016 13:05:16  1.123718  At223  01/04/2016 16:00   466299       Two    4.50
11  21/03/2016 13:05:16  1.123718  At223  01/04/2016 16:00    58805     Three     NaN
12  21/03/2016 13:14:22  1.123718  At223  01/04/2016 16:00    28212       One     NaN
13  21/03/2016 13:14:22  1.123718  At223  01/04/2016 16:00   466299       Two    4.50
14  21/03/2016 13:14:22  1.123718  At223  01/04/2016 16:00    58805     Three     NaN
15  01/04/2016 10:37:43  1.123718  At223  01/04/2016 16:00    28212       One     NaN
16  01/04/2016 10:37:43  1.123718  At223  01/04/2016 16:00   466299       Two    4.50
17  01/04/2016 10:37:43  1.123718  At223  01/04/2016 16:00    58805     Three     NaN
21  21/03/2016 13:03:48  1.123720   Br12  03/04/2016 16:00    28214     Eight    7.20
22  21/03/2016 13:03:48  1.123720   Br12  03/04/2016 16:00  1212772      Nine    1.58
23  21/03/2016 13:03:48  1.123720   Br12  03/04/2016 16:00    58805       Ten    4.40
24  21/03/2016 13:19:15  1.123720   Br12  03/04/2016 16:00    28214     Eight    7.20
25  21/03/2016 13:19:15  1.123720   Br12  03/04/2016 16:00  1212772      Nine    1.58
26  21/03/2016 13:19:15  1.123720   Br12  03/04/2016 16:00    58805       Ten    4.50
27  01/04/2016 12:48:13  1.123720   Br12  03/04/2016 16:00    28214     Eight    7.20
28  01/04/2016 12:48:13  1.123720   Br12  03/04/2016 16:00  1212772      Nine    1.59
29  01/04/2016 12:48:13  1.123720   Br12  03/04/2016 16:00    58805       Ten    4.50
gorkyyrv

gorkyyrv3#

可以在groupby之后使用apply
并创建一个函数,仅处理具有单个Ref的 Dataframe

def extract_n_last_times(n: int):
    def extract_last_times(group: pd.DataFrame):
        times = group.sort_values("Time")["Time"].unique()
        return group[group["Time"].isin(times[-n:])]
    return extract_last_times

df.sort_values(["Ref", "Time"]).groupby("Ref", group_keys=False).apply(extract_n_last_times(n=3))

相关问题