Python按周/月分组时间戳并绘图的实现及报错解决
Python实现按周/月统计PersonId并绘制时间序列图
问题根源
你碰到的float() argument must be a string or a number, not 'Period'错误,核心原因是groupby时用to_period('W')生成的是Period类型数据,matplotlib无法直接将Period作为坐标轴数值。另外代码还有两处细节错误:
[[PersonId]]中的列名需要加引号(如果PersonId是字符串列名)- 绘图时调用的
series.SubmissionID不存在,你的统计列实际是PersonId
完整实现方案
1. 预处理:确保时间列是datetime类型
先确认TimeStamp列被解析为datetime格式,未解析的话先转换:
import pandas as pd import matplotlib.pyplot as plt # 构造你的DataFrame data = { 'PersonId': [10, 1, 26, 28, 46, 2], 'TimeStamp': ['2023-03-11 02:22:25', '2023-03-30 03:02:20', '2023-01-11 08:02:28', '2023-02-26 09:25:01', '2023-01-27 11:49:40', '2023-04-01 01:32:21'] } df = pd.DataFrame(data) # 转换为datetime类型 df['TimeStamp'] = pd.to_datetime(df['TimeStamp'])
2. 通用分组统计函数
实现支持按周('W')或按月('M')分组的函数,同时自动将Period转换为matplotlib可识别的datetime类型:
def count_by_time_period(df, period='W', start_date=None, end_date=None): # 筛选指定时间范围的数据 filtered_df = df.copy() if start_date: filtered_df = filtered_df[filtered_df['TimeStamp'] >= pd.to_datetime(start_date)] if end_date: filtered_df = filtered_df[filtered_df['TimeStamp'] <= pd.to_datetime(end_date)] # 按指定周期分组统计PersonId数量 grouped = filtered_df.groupby(filtered_df['TimeStamp'].dt.to_period(period))['PersonId'].count().reset_index() # 将Period转换为datetime(默认取周期起始时间,可通过how='end'取结束时间) grouped['TimeStamp'] = grouped['TimeStamp'].dt.to_timestamp() # 重命名统计列,提升可读性 grouped.rename(columns={'PersonId': 'PersonCount'}, inplace=True) return grouped
3. 调用函数并绘图
按周统计+折线图
# 按周统计(指定时间范围:2023-01-01 至 2023-04-30) weekly_data = count_by_time_period(df, period='W', start_date='2023-01-01', end_date='2023-04-30') # 绘制折线图 fig, ax = plt.subplots(figsize=(8,6)) ax.plot(weekly_data['TimeStamp'], weekly_data['PersonCount'], marker='o', linestyle='-', color='#1f77b4') # 图表样式设置 ax.set_title('每周PersonId数量统计') ax.set_xlabel('时间') ax.set_ylabel('PersonId数量') plt.xticks(rotation=45) plt.tight_layout() plt.show()
按月统计+柱状图
# 按月统计(不指定时间范围则用全量数据) monthly_data = count_by_time_period(df, period='M') # 绘制柱状图 fig, ax = plt.subplots(figsize=(8,6)) ax.bar(monthly_data['TimeStamp'], monthly_data['PersonCount'], color='#ff7f0e') # 图表样式设置 ax.set_title('每月PersonId数量统计') ax.set_xlabel('月份') ax.set_ylabel('PersonId数量') plt.xticks(rotation=45) plt.tight_layout() plt.show()
关键细节说明
dt.to_timestamp():将Period类型转换为datetime对象,默认取周期起始时间,如需取结束时间可修改为dt.to_timestamp(how='end')- 时间范围筛选:通过
start_date和end_date参数可以快速限定统计的时间区间 - 统计列重命名:将
PersonId改为PersonCount是为了明确统计含义,可根据需求调整
内容的提问来源于stack exchange,提问作者Eisen
相关产品推荐
相关产品推荐

