python - 我如何计算每小时的值并将上一小时和下一小时显示到数据框中具有最高值的那一小时?
问题描述
这是我的数据的一小部分样本,包含在更大的 pandas df 中:
Year Month Day Hour errors
0 2018 10 15 23 149
1 2016 9 21 14 114
2 2018 10 14 23 106
3 2016 5 19 14 100
4 2018 10 19 9 85
5 2017 6 15 10 79
6 2017 6 15 13 76
7 2017 6 15 9 71
8 2016 9 21 15 70
9 2016 9 13 14 65
10 2018 10 14 22 64
11 2019 3 27 16 62
12 2018 10 16 0 60
13 2016 5 19 15 59
14 2018 5 30 9 58
15 2017 6 15 12 52
16 2018 6 15 14 51
17 2016 9 19 16 51
18 2016 9 20 13 51
19 2016 9 21 16 48
20 2018 10 22 12 48
此数据按年月日和小时显示错误数。我知道如何找到每小时最多的错误并对其进行排序,这不是问题。我需要做的是显示错误数量最多的小时数(以及它们各自的月、年和日),但还要显示前一个小时,以及错误数最多的那个小时的下一个小时。我还需要按降序显示此表。
这是我想要的输出的一个例子,但数据不是真实的,我在伪造它,因为我不知道数据的真实值,但提供一个说明性的例子很有用:
Year Month Day Hour errors
0 2018 10 15 21 120 # Previous hour
1 2018 10 15 22 150 # Hour of the same year, month and day with the biggest number of errors
2 2018 10 15 23 130 # Next hour
3 2016 7 29 16 40 # Previous hour
4 2016 7 29 17 90 # Hour of the same year, month and day with the biggest number of errors
5 2016 7 29 18 20 # Next hour
其余的数据依此类推。这个想法很简单,但我不知道如何组织数据框中的行以这种方式显示。有人可以帮我吗?
非常感谢您提前
解决方案
假设我们有以下测试数据:
Year Month Day Hour errors
0 2016 5 19 14 51
1 2016 5 19 15 52
2 2016 5 19 16 100
3 2016 5 19 17 54
4 2016 5 19 18 55
5 2016 5 20 8 41
6 2016 5 20 9 42
7 2016 5 20 10 200
8 2016 5 20 11 43
9 2016 5 20 12 44
我们附加一个辅助列maxerr
,用 1 标记每天最大错误的行:
df['maxerr'] = None
df.iloc[df.groupby(['Year', 'Month', 'Day']).errors.idxmax().values,-1] = 1
然后我们将这个标记向上和向下传播一行:
df['maxerr'] = df['maxerr'].ffill(limit=1).bfill(limit=1)
在删除所有剩余的(未标记的)行和我们的辅助列之后
df.dropna().drop(columns='maxerr')
我们得到:
Year Month Day Hour errors
1 2016 5 19 15 52
2 2016 5 19 16 100
3 2016 5 19 17 54
6 2016 5 20 9 42
7 2016 5 20 10 200
8 2016 5 20 11 43
(如果原始数据不应该按时间排序,我们必须先按 排序df = df.sort_values(['Year', 'Month', 'Day', 'Hour'])
)
根据以下评论中给出的附加要求进行更新:
为了仅包括与最大错误小时数直接相邻的小时数,我们临时创建一个日期时间索引并将其上采样为小时数。在对数据帧进行上采样后,我们丢弃该索引并像以前一样继续。唯一的区别是,由于插入了 NaN,所有列都转换为浮点数,我们通过 撤消astype(int)
。
df = df.set_index(pd.to_datetime(df[['Year', 'Month', 'Day', 'Hour']]))
df = df.resample('1H').asfreq()
df = df.reset_index(drop=True)
df['maxerr'] = None
df.iloc[df.groupby(['Year', 'Month', 'Day']).errors.idxmax().values,-1] = 1
df['maxerr'] = df['maxerr'].ffill(limit=1).bfill(limit=1)
df = df.dropna().drop(columns='maxerr').astype(int)
有了这些测试数据:
Year Month Day Hour errors
0 2016 5 19 14 51
1 2016 5 19 15 52
2 2016 5 19 16 100
3 2016 5 19 17 54
4 2016 5 19 18 55
5 2016 5 20 8 41
6 2016 5 20 9 42
7 2016 5 20 10 200
8 2016 5 20 12 44
9 2016 5 20 23 45
10 2016 5 21 0 300
11 2016 5 21 1 46
我们得到:
Year Month Day Hour errors
1 2016 5 19 15 52
2 2016 5 19 16 100
3 2016 5 19 17 54
19 2016 5 20 9 42
20 2016 5 20 10 200
33 2016 5 20 23 45
34 2016 5 21 0 300
35 2016 5 21 1 46
我们看到第 8 行不包括在内,因为它的第 12 小时不直接在第 7 行中的第 10 小时之后。此外,前一天的第 9 行包含在第 10 行中的 0 小时的最大值。
基于下面评论中给出的附加要求的第二次更新:为了仅当 prev 和 next 都存在时才包含最大错误行以及 prev 和 next 行,并且如果 prev 或 next 缺失则不包含任何内容,我们插入代码第一次更新/行之前的以下行:ffill
bfill
df['maxerr'] = df.maxerr + df.errors.shift(-1) + df.errors.shift(1)
如果 prev ( shift(1)
) 或 next ( shift(-1
)) 缺失,它们会传播NaN
到 maxerr。在像之前一样填充和删除NaN
s 之后,我们在示例中得到:
Year Month Day Hour errors
1 2016 5 19 15 52
2 2016 5 19 16 100
3 2016 5 19 17 54
33 2016 5 20 23 45
34 2016 5 21 0 300
35 2016 5 21 1 46
在这里,排除了 10 小时的最大错误行以及 9 小时的前一行,因为 11 小时(天 = 20)没有行。
推荐阅读
- java - 尝试使用 github 操作(maven)部署到 github 包时出现错误代码 400
- user-interface - 有没有办法在从 Firestore 生成的幻灯片/卡片上个性化 UI?扑
- bind - bind() 适用于 ipv6 无线适配器接口,但不适用于 ipv6 以太网(错误 10049)
- c# - 我应该使用 23:59:59 还是 00:00:00 表示 24 小时制的 12 AM?
- c# - 为什么在游戏通过exe构建文件运行时更改分辨率时一切都太模糊并且ui没有响应?
- reporting-services - 将度量值和计算列从 Tableau 迁移到 PowerBi
- c++ - 访问多层结构会导致错误
- sql - 加入时间间隔之间的事件并获得最佳时差?
- sql-server - 获取 ID 的 EF Core 差异会导致出现问题,而不是触发器和 Scope_Identity
- arduino - LoRa MBED 和 Arduino 库不兼容