Pandas 按主机名分组。按小时计算的会话平均值(在主机上)
Pandas Grouping by Hostname. Average of Sessions(on host) by Hour
数据框看起来像这样。
datetime hostname sessions
0 2020-10-27 00:00:05 server001 22
1 2020-10-27 00:00:10 server001 25
2 2020-10-27 00:00:15 server001 21
3 2020-10-27 01:00:05 server001 30
4 2020-10-27 01:00:10 server001 30
5 2020-10-27 01:00:15 server001 35
6 2020-10-27 00:00:05 server002 15
7 2020-10-27 00:00:10 server002 10
8 2020-10-27 00:00:15 server002 11
9 2020-10-27 01:00:05 server002 19
10 2020-10-27 01:00:10 server002 22
11 2020-10-27 01:00:15 server002 18
我正在尝试按单个主机名显示每小时的平均会话数。
所以我会得到这样的东西。
datetime hostname sessions
0 2020-10-27 00:00:00 server001 23
1 2020-10-27 01:00:00 server001 32
2 2020-10-27 00:00:00 server002 12
3 2020-10-27 01:00:00 server002 20
我认为我的分组有误,因为在尝试此操作时,我最终得到的通常是按日期按小时排序的任何给定主机名的每小时最大平均值。
例如,我可能会看到类似
的内容
hostname datetime sessions
0 2020-10-27 server001 00:00:00 23
1 2020-10-27 01:00:00 32
2 2020-10-27 server002 02:00:00 12
3 2020-10-27 server003 03:00:00 20
而不是列出每个主机名的完整 24 小时。
我试过的代码是:
df = df.groupby(['hostname']).resample(
'H', on='datetime'
).agg({'sessions': 'mean'}).round(0).astype(int)
我需要做什么才能得到想要的结果?
这是一个基于您提供的数据的示例。我添加了将日期转换为日期时间(如果它们是对象)并将日期时间设置为 datetimeindex
以便使用 resample
的步骤。它会是这样的:
import pandas as pd
import numpy as np
d ={'datetime' :['2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15','2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15'],
'hostname':['server001','server001','server001','server001','server001','server001','server002','server002','server002','server002','server002','server002'],
'sessions':[ 22,25,21 ,30,30,35,15,10, 11,19,22,18]}
df = pd.DataFrame(data=d)
df['datetime'] = pd.to_datetime(df['datetime'])
df = df.set_index(pd.DatetimeIndex(df['datetime']))
df.resample('H').mean()
实际上,您可以修改此示例以适应其他目的。据我了解您的问题,您想要计算每小时的平均会话数。如果您需要其他 groupby.s
,请检查 resample
-功能
替代方法是将 date
和 time
分开,然后取平均值:
df['datetime'] = pd.to_datetime(df['datetime'])
df['Date'] = [x.strftime('%Y-%m-%d') for x in df['datetime'].tolist()]
df['Time'] = ['%s:00' % x.strftime('%H') for x in df['datetime'].tolist()]
df_1 = df.groupby(['Date', 'Time', 'hostname']).mean()
这给出了
编辑:请参阅 Serge de Gosson de Varnnes 的第二个示例。这正是我想要的。
我相信我已经找到了答案的解决方案。我犯的第一个错误是没有按小时创建索引。我相信 Amit Kumar 正在谈论这个,但当时我不太明白他的意思。 Serge de Gosson de Varnnes 也在他的示例中为数据设置了索引。
我将使用 Serge de Gosson de Varnnes 的 我的数据插入示例,因此任何发现此示例的人都可以直接使用示例并检查输出:
import pandas as pd
d ={'datetime' :['2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15','2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15'],
'hostname':['server001','server001','server001','server001','server001','server001','server002','server002','server002','server002','server002','server002'],
'sessions':[ 22,25,21 ,30,30,35,15,10, 11,19,22,18]}
df = pd.DataFrame(data=d)
df['datetime'] = pd.to_datetime(df['datetime'])
df = df.set_index(pd.DatetimeIndex(df['datetime']))
hour_index = df.index.hour
df = groupby([hour_index, 'hostname'])['sessions'].mean().round(0).astype(int)
with pd.option_context(
'display.max_rows',
None,
'display.max_columns',
None
):
print(df)
这里应用了 round 和 astype 方法来四舍五入到最接近的整数。这不是我之前指定的内容,因为我已经知道如何处理它,但为了完整起见,我会把它放在这里。
这里的 with 语句是为了允许打印完整的数据帧(小心处理大数据帧,因为这可能会同时在屏幕上打印大量数据)。
输出:
datetime hostname
0 server001 23
server002 12
1 server001 32
server002 20
此处唯一的改进是采用带有时间戳的时钟格式的小时索引。
另一件没有解决但超出此特定问题范围的事情是日期时间列中是否有多天。我将在每天每个数据帧中分离我的数据帧来处理这个问题。但是我是否应该找到更好的方法来处理每一天,我会将其添加到我的解决方案中。
数据框看起来像这样。
datetime hostname sessions
0 2020-10-27 00:00:05 server001 22
1 2020-10-27 00:00:10 server001 25
2 2020-10-27 00:00:15 server001 21
3 2020-10-27 01:00:05 server001 30
4 2020-10-27 01:00:10 server001 30
5 2020-10-27 01:00:15 server001 35
6 2020-10-27 00:00:05 server002 15
7 2020-10-27 00:00:10 server002 10
8 2020-10-27 00:00:15 server002 11
9 2020-10-27 01:00:05 server002 19
10 2020-10-27 01:00:10 server002 22
11 2020-10-27 01:00:15 server002 18
我正在尝试按单个主机名显示每小时的平均会话数。
所以我会得到这样的东西。
datetime hostname sessions
0 2020-10-27 00:00:00 server001 23
1 2020-10-27 01:00:00 server001 32
2 2020-10-27 00:00:00 server002 12
3 2020-10-27 01:00:00 server002 20
我认为我的分组有误,因为在尝试此操作时,我最终得到的通常是按日期按小时排序的任何给定主机名的每小时最大平均值。
例如,我可能会看到类似
的内容 hostname datetime sessions
0 2020-10-27 server001 00:00:00 23
1 2020-10-27 01:00:00 32
2 2020-10-27 server002 02:00:00 12
3 2020-10-27 server003 03:00:00 20
而不是列出每个主机名的完整 24 小时。
我试过的代码是:
df = df.groupby(['hostname']).resample(
'H', on='datetime'
).agg({'sessions': 'mean'}).round(0).astype(int)
我需要做什么才能得到想要的结果?
这是一个基于您提供的数据的示例。我添加了将日期转换为日期时间(如果它们是对象)并将日期时间设置为 datetimeindex
以便使用 resample
的步骤。它会是这样的:
import pandas as pd
import numpy as np
d ={'datetime' :['2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15','2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15'],
'hostname':['server001','server001','server001','server001','server001','server001','server002','server002','server002','server002','server002','server002'],
'sessions':[ 22,25,21 ,30,30,35,15,10, 11,19,22,18]}
df = pd.DataFrame(data=d)
df['datetime'] = pd.to_datetime(df['datetime'])
df = df.set_index(pd.DatetimeIndex(df['datetime']))
df.resample('H').mean()
实际上,您可以修改此示例以适应其他目的。据我了解您的问题,您想要计算每小时的平均会话数。如果您需要其他 groupby.s
,请检查resample
-功能
替代方法是将 date
和 time
分开,然后取平均值:
df['datetime'] = pd.to_datetime(df['datetime'])
df['Date'] = [x.strftime('%Y-%m-%d') for x in df['datetime'].tolist()]
df['Time'] = ['%s:00' % x.strftime('%H') for x in df['datetime'].tolist()]
df_1 = df.groupby(['Date', 'Time', 'hostname']).mean()
这给出了
编辑:请参阅 Serge de Gosson de Varnnes
我相信我已经找到了答案的解决方案。我犯的第一个错误是没有按小时创建索引。我相信 Amit Kumar 正在谈论这个,但当时我不太明白他的意思。 Serge de Gosson de Varnnes 也在他的示例中为数据设置了索引。
我将使用 Serge de Gosson de Varnnes 的 我的数据插入示例,因此任何发现此示例的人都可以直接使用示例并检查输出:
import pandas as pd
d ={'datetime' :['2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15','2020-10-27 00:00:05','2020-10-27 00:00:10','2020-10-27 00:00:15','2020-10-27 01:00:05','2020-10-27 01:00:10','2020-10-27 01:00:15'],
'hostname':['server001','server001','server001','server001','server001','server001','server002','server002','server002','server002','server002','server002'],
'sessions':[ 22,25,21 ,30,30,35,15,10, 11,19,22,18]}
df = pd.DataFrame(data=d)
df['datetime'] = pd.to_datetime(df['datetime'])
df = df.set_index(pd.DatetimeIndex(df['datetime']))
hour_index = df.index.hour
df = groupby([hour_index, 'hostname'])['sessions'].mean().round(0).astype(int)
with pd.option_context(
'display.max_rows',
None,
'display.max_columns',
None
):
print(df)
这里应用了 round 和 astype 方法来四舍五入到最接近的整数。这不是我之前指定的内容,因为我已经知道如何处理它,但为了完整起见,我会把它放在这里。
这里的 with 语句是为了允许打印完整的数据帧(小心处理大数据帧,因为这可能会同时在屏幕上打印大量数据)。
输出:
datetime hostname
0 server001 23
server002 12
1 server001 32
server002 20
此处唯一的改进是采用带有时间戳的时钟格式的小时索引。
另一件没有解决但超出此特定问题范围的事情是日期时间列中是否有多天。我将在每天每个数据帧中分离我的数据帧来处理这个问题。但是我是否应该找到更好的方法来处理每一天,我会将其添加到我的解决方案中。