数据仓库的定义之一是反应历史变化,数据或多或少都会包含时间特征,因此日期维度就成了数据仓库中不可或缺的维度之一,可以说在任何一个事实表中都会有一个或者多个日期维度的外键。日期维度可以尽可能多的包含日期详细信息,比如周几、农历、年、月、日、节假日、季度,甚至是生肖年、干支纪年、星座等信息。
生成日期维度表的方式有很多,可以通过数据库例如MySQL直接生成日期维度,也可以通过编程语言JAVA、PYTHON等来生成。本文采用的是通过PYTHON来实现日期维度表的生成,该方式的优点是生成的日期维度相对详实。先来看一下最终的结果
每一列的含义如下
日期
id
2018-01-01
年
year
2018
月
month
1
日
day
1
季度
quarter
1
星期几
day_name
Monday
一年的第几周
weekofyear
1
一年的第几天
dayofyear
1
该月有几天
daysinmonth
31
这周第几天
dayofweek
1
是否闰年
is_leap_year
FALSE
是否月末最后一天
is_month_end
FALSE
是否月初第一天
is_month_start
TRUE
是否季度末最后一天
is_quarter_end
FALSE
是否季度初第一天
is_quarter_start
TRUE
是否年末最后一天
is_year_end
FALSE
是否年初第一天
is_year_start
TRUE
农历
lunar_date
冬月十五
干支纪年
gz_year
丁酉年
生肖年
sx_year
鸡年
干支纪日
gz_day
癸巳日
节气
solar_terms
星座
zodiac
摩羯座
节假日
holiday
元旦
实现方式:
from util.lunar import Lunar
import pandas as pd
def getLunar(ct=None):
ln = Lunar(ct)
return (ln.ln_date_str(), ln.gz_year(), ln.sx_year(), ln.gz_day(),ln.ln_jie())
def holiday(ln_date):
n = (u'春节',u'春节',u'春节',u'端午节',u'中秋节',u'元旦',u'劳动节',u'国庆节',u'国庆节',u'国庆节')
d = ('腊月三十','正月初一','正月初二','五月初五','八月十五',(1,1),(5,1),(10,1),(10,2),(10,3))
dic = dict(zip(d,n))
if ln_date in d:
return dic[ln_date]
def zodiac(month, day):
n = (u'摩羯座',u'水瓶座',u'双鱼座',u'白羊座',u'金牛座',u'双子座',u'巨蟹座',u'狮子座',u'处女座',u'天秤座',u'天蝎座',u'射手座')
d = ((1,20),(2,19),(3,21),(4,21),(5,21),(6,22),(7,23),(8,23),(9,23),(10,23),(11,23),(12,23))
return n[len(list(filter(lambda y:y<=(month,day), d)))%12]
def generateData(startDate='2019-1-01', endDate='2019-1-31'):
d = {'id':pd.date_range(start=startDate, end=endDate)}
data = pd.DataFrame(d)
data['year'] = data['id'].apply(lambda x:x.year)
data['month'] = data['id'].apply(lambda x:x.month)
data['day'] = data['id'].apply(lambda x:x.day)
data['quarter'] = data['id'].apply(lambda x:x.quarter)
data['day_name'] = data['id'].apply(lambda x:x.day_name())
data['weekofyear'] = data['id'].apply(lambda x:x.weekofyear)
data['dayofyear'] = data['id'].apply(lambda x:x.dayofyear)
data['daysinmonth'] = data['id'].apply(lambda x:x.daysinmonth)
data['dayofweek'] = data['id'].apply(lambda x:x.dayofweek)
data['is_leap_year'] = data['id'].apply(lambda x:x.is_leap_year)
data['is_month_end'] = data['id'].apply(lambda x:x.is_month_end)
data['is_month_start'] = data['id'].apply(lambda x:x.is_month_start)
data['is_quarter_end'] = data['id'].apply(lambda x:x.is_quarter_end)
data['is_quarter_start'] = data['id'].apply(lambda x:x.is_quarter_start)
data['is_year_end'] = data['id'].apply(lambda x:x.is_year_end)
data['is_year_start'] = data['id'].apply(lambda x:x.is_year_start)
data['lunar'] = data['id'].apply(lambda x:getLunar(x))
data['lunar_date'] = data['lunar'].apply(lambda x:x[0])
data['gz_year'] = data['lunar'].apply(lambda x:x[1])
data['sx_year'] = data['lunar'].apply(lambda x:x[2])
data['gz_day'] = data['lunar'].apply(lambda x:x[3])
data['solar_terms'] = data['lunar'].apply(lambda x:x[4])
data['zodiac'] = data['id'].apply(lambda x:(x.month,x.day))
data['holiday0']= data['zodiac'].apply(lambda x:holiday(x))
data['holiday1']= data['lunar_date'].apply(lambda x:holiday(x))
data['zodiac'] = data['zodiac'].apply(lambda x:zodiac(x[0],x[1]))
del data['lunar']
return data
data =generateData(startDate='2018-1-01', endDate='2018-12-31')
data.to_csv('DIM_TIME.csv', index = False,index_label = False)
最后将生成的csv文件导入数据库即可