You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按每秒预设时间区间统计CSV事件并绘制直方图?

统计CSV数据中每秒事件数并绘制直方图

问题描述

需求:统计CSV数据文件中每秒的事件数量,并根据结果绘制直方图,但不清楚如何正确获取每秒的事件数。

现有代码:

from matplotlib import pyplot as pl
import pandas as pd
import numpy as np

def read_data():
    df = pd.read_csv("test.csv", usecols=['time', 'unix_time', 'name'])
    df['time'] = pd.to_datetime(df['time'])
    df['unix_time'] = (df['unix_time']).astype(int)
    df.info()

    i = 1

    time_counts = df.groupby((3600 * df.time.dt.minute + df.time.dt.second) // i * i)['time'].count()
    print(time_counts)


if __name__ == "__main__":
    read_data()

异常输出:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 33 entries, 0 to 32
Data columns (total 3 columns):

Column Non-Null Count Dtype

0 time 33 non-null datetime64[ns]
1 unix_time 33 non-null int32
2 name 33 non-null object
dtypes: datetime64ns, int32(1), object(1)
memory usage: 788.0+ bytes

time
18 1
25217 1
43209 1
43219 1
46804 1
54047 1
61241 1
64815 1
64833 1
68402 1
75620 1
79235 1
82806 1
82837 2
86407 1
86446 1
93625 1
97254 1
104446 1
140438 1
144050 1
162025 1
169250 1
180050 1
183623 1
183658 1
194404 1
194412 2
194433 1
194438 1
205219 1
Name: time, dtype: int64

问题分析

原代码的分组键计算逻辑错误:3600 * df.time.dt.minute + df.time.dt.second 用小时转秒的系数去乘分钟,得到的不是从0开始的有效秒数,而是混乱的累计值,导致分组结果的索引毫无意义。

正确实现方法

以下两种方式可可靠统计每秒事件数,并完成直方图绘制:

方法1:使用resample按秒重采样

pandas的resample是时间序列频率转换的专用工具,直接按秒聚合即可,还会自动补全无事件的秒数(计数为0):

from matplotlib import pyplot as plt
import pandas as pd

def read_data():
    df = pd.read_csv("test.csv", usecols=['time', 'unix_time', 'name'])
    df['time'] = pd.to_datetime(df['time'])
    # 将time列设为索引,方便resample操作
    df = df.set_index('time')
    # 按秒统计事件数
    time_counts = df.resample('S')['name'].count()
    print(time_counts)
    
    # 绘制直方图
    plt.figure(figsize=(12, 6))
    time_counts.plot(kind='bar')
    plt.title('每秒事件数量分布')
    plt.xlabel('时间(秒)')
    plt.ylabel('事件数')
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    read_data()

方法2:按秒级时间戳分组

若不想设置索引,可直接提取秒级时间作为分组键:

from matplotlib import pyplot as plt
import pandas as pd

def read_data():
    df = pd.read_csv("test.csv", usecols=['time', 'unix_time', 'name'])
    df['time'] = pd.to_datetime(df['time'])
    # 提取到秒级的时间作为分组键(格式如:2024-05-20 12:34:56)
    df['second'] = df['time'].dt.floor('S')
    # 按秒分组统计事件数
    time_counts = df.groupby('second')['name'].count()
    print(time_counts)
    
    # 绘制直方图
    plt.figure(figsize=(12, 6))
    time_counts.plot(kind='bar')
    plt.title('每秒事件数量分布')
    plt.xlabel('时间(秒)')
    plt.ylabel('事件数')
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    read_data()

补充说明

  • 若unix_time列是精确到秒的时间戳,也可直接用它分组:df.groupby('unix_time')['name'].count(),效果一致;
  • 若想展示事件数的分布频率,可把plot(kind='bar')换成plt.hist(time_counts.values)来绘制传统直方图。

内容的提问来源于stack exchange,提问作者ditrauth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 05:05:25