求助:Pandas处理object类型时间列绘制直方图pd.cut报错
问题分析与解决方案
错误原因
pd.cut()仅支持对数值型数据进行分桶操作,你的time列是object类型的字符串(格式为hh:mm),无法直接用于分桶,因此抛出类型错误。
解决步骤
1. 将字符串时间转换为数值型数据
把hh:mm格式的时间转换为总分钟数(或总秒数),转换成数值后就能正常使用pd.cut()分桶:
# 把hh:mm转成总分钟数(00:00对应0,23:59对应1439) data['total_minutes'] = data['time'].apply(lambda x: int(x.split(':')[0])*60 + int(x.split(':')[1]))
如果需要更灵活的时间操作,也可以转成timedelta类型再提取数值:
# 转成timedelta格式,再提取总秒数 data['time_delta'] = pd.to_timedelta(data['time']) data['total_seconds'] = data['time_delta'].dt.total_seconds()
2. 对数值型时间分桶
用转换后的数值列执行分桶操作,支持两种分桶方式:
- 自动均分桶(比如分10个桶):
data['bucket'] = pd.cut(data['total_minutes'], bins=10)
- 自定义时间间隔(比如每10分钟一个桶):
# 自定义从0到1440分钟(24小时),每10分钟一个区间 custom_bins = range(0, 1441, 10) data['bucket'] = pd.cut(data['total_minutes'], bins=custom_bins)
3. 分组求和并绘图
修改后的完整可运行代码:
import pandas as pd import matplotlib.pyplot as plt # 读取文件 data = pd.read_csv(r'database.csv', low_memory=False) # 转换时间为总分钟数 data['total_minutes'] = data['time'].apply(lambda x: int(x.split(':')[0])*60 + int(x.split(':')[1])) # 自定义10分钟间隔分桶(可替换为bins=10实现自动均分) custom_bins = range(0, 1441, 10) data['bucket'] = pd.cut(data['total_minutes'], bins=custom_bins) # 按桶分组求和 newdata = data[['bucket', 'movements']].groupby('bucket').sum() # 绘制直方图 newdata.plot(kind='bar', figsize=(12,6)) plt.xlabel('时间间隔(分钟)') plt.ylabel('总运动次数') plt.title('昆虫不同时间间隔的运动次数统计') plt.xticks(rotation=45) plt.tight_layout() plt.show()
额外说明
- 如果原始数据的
time是按分钟逐行递增的,也可以直接用行索引分桶,但转换为数值型时间的方式更直观易懂。 - 若需要按秒统计,只需调整时间转换逻辑:
int(x.split(':')[0])*3600 + int(x.split(':')[1])*60(若数据包含秒数,再追加对应计算部分即可)。
内容的提问来源于stack exchange,提问作者Hdez
相关产品推荐
相关产品推荐

