時(shí)間序列數(shù)據(jù)的主要特征是它們的時(shí)間索引,這為數(shù)據(jù)提供了明確的順序。這種順序使得我們可以分析隨時(shí)間的變化趨勢、周期性和季節(jié)性模式,以及突發(fā)事件的影響。為了充分利用時(shí)間序列數(shù)據(jù),我們通常需要從時(shí)間索引中提取多種特征:
時(shí)間單位:如年、季度、月、周、日、小時(shí)等。
日期屬性:如是否為月末、季末、年末等。
星期和時(shí)間段:如星期幾、是否為工作日、時(shí)間段(早上、下午、傍晚、深夜)等。
節(jié)假日:如公共節(jié)假日、特殊事件等。
移動(dòng)窗口統(tǒng)計(jì):如過去幾小時(shí)、幾天、幾個(gè)月的平均值、中位數(shù)、方差等。
import pandas as pd
import numpy as np
# 設(shè)置時(shí)間范圍和頻率
start_date = '2024-01-01'
end_date = '2024-01-04'
freq = 'H' # 每小時(shí)
# 生成時(shí)間索引
index = pd.date_range(start=start_date, end=end_date, freq=freq)
# 生成隨機(jī)銷售數(shù)據(jù)
np.random.seed(0) # 確保結(jié)果可重復(fù)
sales_data = np.random.randint(1, 300, size=len(index)) # 銷售量范圍從1到300
# 創(chuàng)建數(shù)據(jù)框
df = pd.DataFrame({'Sales_Vol': sales_data}, index=index)
df.head() # 顯示前幾行數(shù)據(jù)
# 從日期中提取特征
df['Year'] = df.index.year
df['Quarter'] = df.index.quarter
df['Month'] = df.index.month
df['Day of Week'] = df.index.day_name()
df['Is Working Day'] = df.index.weekday < 5 # 假設(shè)周一到周五為工作日
df['Time of Day'] = pd.cut(df.index.hour, bins=[0, 6, 12, 18, 24], labels=['Late Night', 'Morning', 'Afternoon', 'Evening'])
df.head() # 顯示前幾行數(shù)據(jù)
運(yùn)行上述代碼,時(shí)間為"00:00:00"時(shí),"Time of Day"可能會(huì)出現(xiàn)空值NAN的情況。那這個(gè)時(shí)間點(diǎn)我們就特殊標(biāo)記一下,將他劃分到“Late Night”.
df['Time of Day'] = pd.cut(df.index.hour, bins=[0, 6, 12, 18, 24], right=False, labels=['Late Night', 'Morning', 'Afternoon', 'Evening'])
再格外補(bǔ)充一下,如何從時(shí)間中提取出公共節(jié)假日?
需要提前安裝一下holidays庫,pip install holidays
from holidays import China
# 使用China類來識(shí)別中國的法定節(jié)假日
cn_holidays = China()
# 標(biāo)記時(shí)間序列中的節(jié)假日
df['Is Holiday'] = df.index.map(lambda x: x in cn_holidays)
print(df)
注意:部分節(jié)假日可能會(huì)出現(xiàn)調(diào)休的情況,holidays庫可能不會(huì)自動(dòng)處理這些調(diào)休工作日,因此如果需要這些信息,您可能需要手動(dòng)添加或使用其他方法來獲取。
# 計(jì)算5小時(shí)滾動(dòng)窗口的平均銷售量
df['5-Hour Rolling Average Sales Volume'] = df['Sales_Vol'].rolling(window=5).mean()
由于滾動(dòng)窗口的計(jì)算需要足夠的數(shù)據(jù)點(diǎn),所以數(shù)據(jù)框的前幾行顯示為NaN,直到有足夠的數(shù)據(jù)點(diǎn)來計(jì)算平均值。