如何从Pandas Timestamp提取时分并绘制时间及差值的概率密度函数?
解决方案:基于时分字段生成时间PDF及时间差PDF
Python 实现
步骤1:剥离日期,转换为当日秒数
不用修改日期,直接提取时分秒并转换为当天的总秒数(范围0-86399),彻底剥离日期影响:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from scipy.stats import gaussian_kde # 示例Timestamp元组数组 time_tuples = [ (pd.Timestamp('2024-01-01 08:30:00'), pd.Timestamp('2024-01-01 09:15:00')), (pd.Timestamp('2024-01-02 14:20:00'), pd.Timestamp('2024-01-02 15:00:00')), (pd.Timestamp('2024-01-03 07:45:00'), pd.Timestamp('2024-01-03 08:30:00')) ] # 提取首个时间的当日秒数 first_time_sec = [t1.hour * 3600 + t1.minute * 60 + t1.second for t1, t2 in time_tuples] # 计算两个时间的差值(秒) time_diff_sec = [(t2 - t1).total_seconds() for t1, t2 in time_tuples]
步骤2:生成并可视化PDF
用核密度估计(KDE)生成平滑的概率密度曲线:
# 首个时间的PDF kde_first = gaussian_kde(first_time_sec) x_first = range(0, 86400, 300) # 每5分钟取一个采样点 y_first = kde_first(x_first) plt.figure(figsize=(10,5)) plt.plot(x_first, y_first, linewidth=2) plt.xlabel('一天内的秒数') plt.ylabel('概率密度') plt.title('首个时间的PDF') plt.show() # 时间差的PDF kde_diff = gaussian_kde(time_diff_sec) x_diff = range(0, max(time_diff_sec)+300, 300) y_diff = kde_diff(x_diff) plt.figure(figsize=(10,5)) plt.plot(x_diff, y_diff, linewidth=2) plt.xlabel('时间差(秒)') plt.ylabel('概率密度') plt.title('时间差的PDF') plt.show()
R 实现
步骤1:处理时间数据
用lubridate提取时分信息,转换为当日分钟数,计算时间差:
library(lubridate) library(ggplot2) # 示例数据 time_tuples <- list( list(ymd_hms("2024-01-01 08:30:00"), ymd_hms("2024-01-01 09:15:00")), list(ymd_hms("2024-01-02 14:20:00"), ymd_hms("2024-01-02 15:00:00")), list(ymd_hms("2024-01-03 07:45:00"), ymd_hms("2024-01-03 08:30:00")) ) # 提取首个时间的当日分钟数 first_time_min <- sapply(time_tuples, function(x) hour(x[[1]])*60 + minute(x[[1]])) # 计算时间差(分钟) time_diff_min <- sapply(time_tuples, function(x) as.duration(x[[2]] - x[[1]])/dminutes(1))
步骤2:绘制PDF曲线
用ggplot2的密度曲线功能可视化:
# 首个时间的PDF ggplot(data.frame(minutes = first_time_min), aes(x = minutes)) + geom_density(fill = "lightblue", alpha = 0.5, linewidth=1) + xlab("一天内的分钟数") + ylab("概率密度") + ggtitle("首个时间的PDF") # 时间差的PDF ggplot(data.frame(diff_min = time_diff_min), aes(x = diff_min)) + geom_density(fill = "lightgreen", alpha = 0.5, linewidth=1) + xlab("时间差(分钟)") + ylab("概率密度") + ggtitle("时间差的PDF")
Julia 实现
步骤1:转换时间数据
用Dates包提取时分,计算当日秒数和时间差:
using Dates, Plots, StatsPlots # 示例数据 time_tuples = [ (DateTime("2024-01-01T08:30:00"), DateTime("2024-01-01T09:15:00")), (DateTime("2024-01-02T14:20:00"), DateTime("2024-01-02T15:00:00")), (DateTime("2024-01-03T07:45:00"), DateTime("2024-01-03T08:30:00")) ] # 提取首个时间的当日秒数 first_time_sec = [Dates.hour(t1)*3600 + Dates.minute(t1)*60 + Dates.second(t1) for (t1, t2) in time_tuples] # 计算时间差(秒,DateTime差值为毫秒,需转换) time_diff_sec = [Dates.value(t2 - t1) / 1000 for (t1, t2) in time_tuples]
步骤2:生成PDF
用StatsPlots绘制核密度曲线:
# 首个时间的PDF density(first_time_sec, xlabel="一天内的秒数", ylabel="概率密度", title="首个时间的PDF", fill=true, alpha=0.5, linewidth=2) # 时间差的PDF density(time_diff_sec, xlabel="时间差(秒)", ylabel="概率密度", title="时间差的PDF", fill=true, alpha=0.5, linewidth=2)
核心思路说明
- 避开修改日期的坑:直接将时间转换为当日的秒数/分钟数,无需改动时间戳的日期部分,避免时间类型的边界问题。
- 时间差无需关注日期:两个时间戳的差值本身与日期无关,直接计算即可。
- 用KDE生成平滑PDF:核密度估计比直方图更适合连续时间数据的概率密度展示。
内容的提问来源于stack exchange,提问作者Shankar Ramharack
相关产品推荐
相关产品推荐

