第8章 时序数据的洞察:从构建到分析的全链路实践
第8章 时序数据的洞察:从构建到分析的全链路实践时间序列数据是数据分析领域中最具挑战性也最具价值的类型之一。与普通的横截面数据不同,时间序列数据带有一个天然的顺序维度——时间。股票价格、气温变化、网站流量、销售额趋势,这些数据都随着时间推移而产生,前后观测值之间往往存在依赖关系。处理时间序列数据,不仅需要掌握常规的数据整理技巧,还需要理解时间索引、偏移、平滑、重采样等专门概念。本章将深入探讨如何利用ChatGPT与pandas的时间序列处理能力,系统化地构建、整理和分析时序数据。我们将从时间序列的基本概念入手,逐步深入到数据创建、查询筛选、转换汇总、时间偏移、数据平滑和重采样等高级操作。每个知识点都结合真实的商业场景,提供可直接运行的代码实例,帮助读者建立从理论到实践的完整认知。8.1 时间序列的构建:从零开始搭建时序数据集时间序列数据的核心是时间索引。与普通DataFrame使用数字索引不同,时间序列通常以时间点为索引,这使得按时间切片、重采样等操作变得异常便捷。在pandas中,我们可以使用pd.date_range创建连续的时间点,也可以将已有的日期列设置为索引。从原理上讲,pandas的DatetimeIndex是一种特殊的索引类型,它将时间点存储为纳秒级整数,支持高效的切片、对齐和重采样操作。当我们将一个列设置为DatetimeIndex后,DataFrame就变成了一个时间序列对象,可以使用一系列专门为时间序列设计的便捷方法。8.1.1 自主构建:使用date_range生成时间索引在模拟数据、生成测试集或创建时间轴时,我们需要能够自主生成一系列连续的时间点。pd.date_range是最常用的工具,它可以按指定频率生成日期范围,支持日、周、月、年等多种频率,甚至可以按业务日历生成。商业实例:某能源公司需要分析过去一年的每日用电量数据。在数据采集系统出现故障时,我们需要生成完整的日期序列,以便将缺失的日期补全。同时,我们需要模拟一些测试数据来验证分析算法的正确性。importpandasaspdimportnumpyasnpclassTimeSeriesBuilder:""" 时间序列构建器:生成日期范围并创建模拟数据 """def__init__(self):self.TimeSeries=NonedefGenerateDateRange(self,StartDate,EndDate,Frequency='D'):""" 生成日期范围 Frequency: 'D' 日, 'W' 周, 'M' 月末, 'MS' 月初, 'Q' 季末, 'H' 小时 """dateRange=pd.date_range(start=StartDate,end=EndDate,freq=Frequency)print(f"已生成日期范围,从{StartDate}到{EndDate},共{len(dateRange)}个时间点")returndateRangedefCreateEmptySeries(self,DateRange,ValueName='数值'):""" 创建以日期为索引的空时间序列 """self.TimeSeries=pd.DataFrame(index=DateRange,columns=[ValueName])self.TimeSeries.index.name='日期'print(f"已创建空时间序列,索引长度:{len(self.TimeSeries)}")returnself.TimeSeriesdefFillWithRandomData(self,ValueName,Mean=0,Std=1):""" 用随机数据填充时间序列 """ifself.TimeSeriesisNone:print("请先创建时间序列")returnNoneself.TimeSeries[ValueName]=np.random.normal(Mean,Std,len(self.TimeSeries))print(f"已用随机数据填充列{ValueName}")returnself.TimeSeriesdefFillWithTrendAndSeasonality(self,ValueName,TrendSlope=0.1,SeasonalAmplitude=10,SeasonalPeriod=7):""" 模拟带有趋势和周期性的时间序列 """ifself.TimeSeriesisNone:print("请先创建时间序列")returnNonet=np.arange(len(self.TimeSeries))# 趋势成分trend=TrendSlope*t# 季节成分,使用正弦波模拟周期性seasonal=SeasonalAmplitude*np.sin(2*np.pi*t/SeasonalPeriod)# 随机噪声noise=np.random.normal(0,2,len(self.TimeSeries))self.TimeSeries[ValueName]=trend+seasonal+noiseprint(f"已创建带趋势和周期性的时间序列,趋势斜率:{TrendSlope},周期:{SeasonalPeriod}")returnself.TimeSeries# 商业实例:生成2024年每日用电量模拟数据if__name__=="__main__":builder=TimeSeriesBuilder()# 生成2024年全年的日期范围dateRange=builder.GenerateDateRange('2024-01-01','2024-12-31',Frequency='D')# 创建空的时间序列builder.CreateEmptySeries(dateRange,'用电量(kWh)')# 填充带有趋势和季节性的模拟数据(夏季用电量更高,周末可能有变化)# 这里用周期365天模拟年度季节性,实际用电量夏季高,简化处理builder.FillWithTrendAndSeasonality('用电量(kWh)',TrendSlope=0.02,SeasonalAmplitude=50,SeasonalPeriod=365)# 查看前10行print("\n模拟的用电量数据前10行:")print(builder.TimeSeries.head(10))# 查看数据的基本统计print("\n数据统计描述:")print(builder.TimeSeries.describe())在这个实例中,我们不仅生成了日期范围,还创建了带有趋势和季节性的模拟数据。date_range的freq参数非常灵活,可以设置为'D'(日)、'W'(周)、'M'(月末)、'MS'(月初)、'Q'(季末)、'H'(小时)等多种频率。ChatGPT可以帮助我们快速查找所需的频率代码,例如“如何在pandas中生成按小时的时间序列”。8.1.2 数据导入:将外部数据转换为时间序列实际业务中,时间序列数据通常来自CSV、Excel或数据库。导入后,最关键的一步是将包含日期时间的列转换为DatetimeIndex,并设置为索引。这一步是后续所有时间序列操作的基础。商业实例:某电商平台导出了一份“每日销售数据.csv”文件,包含“日期”和“销售额”两列。我们需要将其导入并转换为时间序列,以便进行趋势分析和预测。importpandasaspdclassTimeSeriesImporter:""" 时间序列导入器:从文件导入并转换为时间序列格式 """def__init__(self):self.TimeSeries=NonedefImportFromCsv(self,FilePath,DateColumn,ValueColumns,DateFormat=None):""" 从CSV文件导入并设置日期索引 """try:df=pd.read_csv(FilePath)# 转换日期列为datetime类型ifDateFormat:df[DateColumn]=pd.to_datetime(df[DateColumn],format=DateFormat)else:df[DateColumn]=pd.to_datetime(df[DateColumn])# 设置为索引df.set_index(DateColumn,inplace=True)# 只保留需要的值列self.TimeSeries=df[ValueColumns]self.TimeSeries.index.name='日期'print(f"成功导入时间序列,共{len(self.TimeSeries)}条记录,时间范围:{self.TimeSeries.index.min()}至{self.TimeSeries.index.max()}")returnself.TimeSeriesexceptExceptionase:print(f"导入失败:{e}")returnNonedefImportFromExcel(self,FilePath,SheetName,DateColumn,ValueColumns):""" 从Excel文件导入并设置日期索引 """try:df=pd.read_excel(FilePath,sheet_name=SheetName)df[DateColumn]=pd.to_datetime(df[DateColumn])df.set_index(DateColumn,inplace=True)self.TimeSeries=df[ValueColumns]self.TimeSeries.index.name='日期'print(f"成功导入Excel时间序列,共{len(self.TimeSeries)}条记录")returnself.TimeSeriesexceptExceptionase:print(f"导入失败:{e}")returnNonedefShowTimeSeriesInfo(self):""" 显示时间序列的基本信息 """ifself.TimeSeriesisNone:print("请先导入数据")returnprint(f"\n时间序列信息:")print(f"记录数:{len(self.TimeSeries)}")print(f"起始时间:{self.TimeSeries.index.min()}")print(f"结束时间:{self.TimeSeries.index.max()}")print(f"时间频率:{pd.infer_freq(self.TimeSeries.index)}")print(f"缺失值数量:{self.TimeSeries.isnull().sum().sum()}")# 商业实例:导入每日销售数据if__name__=="__main__":# 模拟创建CSV文件内容importio csvData="""日期,销售额 2024-01-01,12500 2024-01-02,13200 2024-01-03,11800 2024-01-04,14500 2024-01-05,16800"""# 使用StringIO模拟文件读取withopen('./data/daily_sales.csv','w')asf:f.write(csvData)importer=TimeSeriesImporter()ts=importer.ImportFromCsv('./data/daily_sales.csv','日期',['销售额'])importer.ShowTimeSeriesInfo()print("\n导入后的时间序列:")print(ts)在导入过程中,pd.to_datetime会自动尝试解析常见的日期格式。如果格式特殊,可以通过format参数指定,如format='%Y/%m/%d',这能显著提高解析速度。pd.infer_freq可以自动推断时间序列的频率,这对后续的重采样操作非常有用。8.2 时间序列的基础操作:查询、筛选与转换将数据转换为时间序列后,我们就可以利用时间索引的强大功能进行各种操作。按时间范围查询、按特定条件筛选、在不同时间粒度之间转换,这些操作变得异常简洁和高效
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2438416.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!