python-3.x 通过按小时和天对Pandas分组来计算平均值

yruzcnhs  于 4个月前  发布在  Python
关注(0)|答案(2)|浏览(95)

基于我之前的一个question,我计算了一周中每小时和每一天的文本数量:

time_df = df.groupby(
    [
        df["timestamp"].dt.dayofweek.rename("day_of_week"),
        df["timestamp"].dt.hour.rename("hour")
    ]
).size().reset_index(name="count")

字符串
此代码返回以下输出:

day_of_week  hour   count
0            0.0   0.0   21195
1            0.0   1.0   13955
2            0.0   2.0   12767
3            0.0   3.0   17839
4            0.0   4.0   32762
..           ...   ...     ...
163          6.0  19.0  132838
164          6.0  20.0  129431
165          6.0  21.0  106678
166          6.0  22.0   69817
167          6.0  23.0   38262
[168 rows x 3 columns]


现在我想计算工作日的平均数,也就是说,如果day_of_week0,那么列count中的数字必须除以该月的星期一数,如果是1,那么必须除以星期二数,依此类推。
如果我从size()改为mean(),我会得到错误:

TypeError: agg function failed [how->mean,dtype->object]


这不是我想要的
我试图添加一个新的列day_of_week到原来的嵌套框架和计数的块的数量与相同的值,然后使用它的计算,但我不知道如何做到这一点。
有什么建议吗?

更新

抱歉,我没说清楚。
问题中的数据框是分组后从原始数据框中获得的唯一数据框,这意味着它包含一周中每一天的24个条目,每小时一个。
原始的框架是这样的:

timestamp              text
2023-01-01 00:00:00    ABC
2023-01-01 00:00:01    DEF
2023-01-01 00:00:01    GHI
...


我添加了一个新列day_of_week

timestamp              text  day_of_week
2023-01-01 00:00:00    ABC   6
2023-01-01 00:00:01    DEF   6
2023-01-01 00:00:01    GHI   6
...


从这一个我想计算平均数的文本数量为每小时和每一天的一周。
例如,我在星期一有0.021195文本,我在这个月有4个星期一,平均值是:21195 / 4 = 5298.75,所以这个框架将是:

day_of_week  hour   count  num_of_day_of_week  mean
0            0.0   0.0   21195  4                   5298.75
1            0.0   1.0   13955  4                   3488.75
2            0.0   2.0   12767  4                   3191.75
3            0.0   3.0   17839  4                   4459.75
4            0.0   4.0   32762  4                   8190.50
..           ...   ...     ...  ...                 ...


很抱歉造成了混乱,希望现在好些了。

jckbn6z7

jckbn6z71#

几个观察结果:
1.给定的代码失败,因为它试图在字符串列(文本)上应用聚合函数(mean)。
1.在这个例子中,21195是星期一第0小时的“文本”数量。记住,这是所有月份、星期的文本数量。所以21195是Jan的星期一第0小时文本+Feb的星期一第0小时文本的总和......等等。所以21195除以4是任意的。另外,记住,有些月份可以有5个星期一。
从你的问题听起来你想找到每周平均的DoW,每个月的小时明智的文本。
MonthWeekDoWHoD列添加到原始df

df['Month'] = df['timestamp'].dt.month
df['Week'] = df['timestamp'].dt.isocalendar().week
df['DoW'] = df['timestamp'].dt.day_of_week
df['HoD'] = df['timestamp'].dt.hour

字符串
现在找到每个月每个星期每个DoW每个小时的文本数量:

df_imm = df.groupby(['Month', 'Week', 'DoW', 'HoD'])['text'].count().reset_index(name='count')


现在找到每个月的每周平均DoW,小时明智的文本:

result = df_imm.groupby(['Month', 'DoW', 'HoD'])['count'].mean().reset_index()


注意-关于第2点,如果你的数据被限制在一个月内,你可以省略上面的Month列,因为它不会有什么不同,但明智的做法是将来证明你的代码来处理未来的用例。

uajslkp6

uajslkp62#

创建虚拟列以计算数值列的均值:您可以用途:

df['mean'] = df['count'] / df['day_of_week'].map(df['day_of_week'].value_counts())

字符串
输出量:

>>> df
     day_of_week  hour   count     mean
0            0.0   0.0   21195   4239.0
1            0.0   1.0   13955   2791.0
2            0.0   2.0   12767   2553.4
3            0.0   3.0   17839   3567.8
4            0.0   4.0   32762   6552.4
163          6.0  19.0  132838  26567.6
164          6.0  20.0  129431  25886.2
165          6.0  21.0  106678  21335.6
166          6.0  22.0   69817  13963.4
167          6.0  23.0   38262   7652.4


另一种方法是使用groupby_transform

df['mean'] = df['count'] / df.groupby('day_of_week').transform('size')


性能:

>>> %timeit df['day_of_week'].map(df['day_of_week'].value_counts())
292 µs ± 8.84 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

>>> %timeit df.groupby('day_of_week').transform('size')
592 µs ± 6.12 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

相关问题