pandas日期类型汇总
pandas日期类型汇总
时间序列数据的特点是有规律地随着时间变化而变化,它们的变化趋势可以被分析和预测。时间序列分析是一种用于预测未来值或评估过去值的统计方法,常常被用于预测未来趋势、季节性变化、周期性变化、随机波动等。
1.日期类型
原始数据中,日期一般会存储为各种类型字符串,比如:
- • 2022/5/1
- • 2022-05-02
- • 3/5/2022
将其统一转换为pandas
的日期类型,后续统计分析时,不仅方便计算,还可以有效避免应对各种格式带来的麻烦。
1.1 pandas中6个时间相关的类
- 对时间类型数据进行分析的前提就是将原本字符串的时间转换为标准时间类型,pandas继承了Numpy可和datetime库的时间相关模块,提供了6种时间相关的类
类名称 | 说明 |
---|---|
Timestamp(时间点) | 最基础的时间类,表示某个时间点。在大多数的场景中的时间数据都是以Timestamp形式的时间 |
Period(时间段) | 表示单个时间跨度,或者某个时间段,例如某一天,某一个小时等 |
Timedelta(时间间隔) | 表 示不同单位的时间,例如1天,1.5小时。2分钟,4秒等,而非具体的某个时间段 |
DatetimeIndex | 一组Timestamp构成的Index,可以用来作为Series或者DataFrame的索引 |
PeriodtimeIndex | 一组Period构成的Index,可以用来作为Series或者DataFrame的索引 |
TimedeltaIndex | 一组Timedelta构成的Index,可以用来作为Series或者DataFrame的索引 |
2.日期类型的相关操作
2.1 生成日期序列
除了将数据集读取来的日期字符串转换为日期类型,我们也可以生成日期序列,这些生成的日期序列可以作为的数据索引,也可以用来补充数据集中缺失的日期值。
df = pd.DataFrame()
df["年"] = pd.date_range('2020-01-01', periods=3, freq='Y')
df["月"] = pd.date_range('2020-01-01', periods=3, freq='M')
df["日"] = pd.date_range('2020-01-01', periods=3, freq='D')
df["周"] = pd.date_range('2020-01-01', periods=3, freq='W')
df["季度"] = pd.date_range('2020-01-01', periods=3, freq='Q')
#生成10个间隔为12小时的时间数据
pd.Series(pd.date_range(start="2017-11-24",periods=10,freq="12H")) #freq取值范围比较
上面的示例分别以年,月,日,周,季度为间隔,生成3条连续的时间序列。
2.2 转换为日期类型
pandas
的to_datetime
函数对于数据集中各类日期字符串都能有效的转换。
df = pd.DataFrame(
{
"日期": ["2022/5/1", "2022-05-02", "3/5/2022"],
"城市": ["合肥", "合肥", "合肥"],
"平均气温": [28, 31, 27],
},
)
print(df)
print(df.dtypes)
#对于多个数据列批量进行类型转换
cols = df.columns[0:]
df[cols] = df[cols].apply(pd.to_datetime)
可以看出,默认的日期是字符串类型且格式混乱。转换后:
df["日期"] = pd.to_datetime(df["日期"])
print(df)
print(df.dtypes)
日期显示起来格式统一了,类型也变为了datetime64[ns]
。
2.3 修改日期
修改日期的值,也是利用日期类型自带的方法,不用像修改字符串那样修改,那样极易出错。
df = pd.DataFrame()
d = pd.date_range('2020-01-01', periods=3, freq='D')
df["原始日期"] = d
df["延迟三天"] = d.shift(3, freq="D")
df["提前三天"] = d.shift(-3, freq="D")
df
#也可以应用Timedelta进行操作
#日期前移一天
df["HepB_1"] + pd.Timedelta(days = 1)
#日期后移一天
df["HepB_1"] + pd.Timedelta(days =-1)
这里是按天调整的,如果要按照年,月,周,季度等调整,像上一个例子那样设置freq
参数即可。
2.4日期相关操作
1.日期选取(可以选择年、月、日、周、季度、天等)
-
1. 通过Timestamp进行操作
- Timestamp类常用属性
属性名称 说明 属性名称 说明 year 年 week 一年中第几周 month 月 quarter 季度 day 日 weekofyear 一年中的第几周 hour 小时 dayofyear 一年中的第几天 minute 分钟 dayofweek 一周第几天 second 秒 weekday 一周第几天 date 日期 weekday_name 星期名称 time 时间 is_leap_year 是否闰年 df["HepB_1"][1].year df["HepB_1"][1].month df["HepB_1"][1].minute#当原始数据中没有该时间时,便会显示为0 df["HepB_1"][1].week df["HepB_1"][1].dayofyear df["HepB_1"][1].is_leap_year#是否为闰年,返回的是布尔型
-
2.通过PeriodIndex进行
#在只需要提取部分时间特征时,如年、月等; df[["HepB_1","HepB_2"]] = df[["HepB_1","HepB_2"]].apply(pd.PeriodIndex,freq="M")#添加参数 #PeriodIndex pd.PeriodIndex(df["HepB_1"],freq = "M")#freq指定什么输出的就到那一位,
-
3.通过dt属性进行
#年 df = pd.DataFrame( { "日期": ["2020/5/1", "2021/5/1", "2021/6/3", "2022/9/4"], "平均气温": [28, 31, 27, 33], }, ) df["日期"] = pd.to_datetime(df["日期"]) df["年"] = df["日期"].dt.year print(df) print(df.groupby(df["年"]).sum()) #月 df = pd.DataFrame( { "日期": ["2020/5/1", "2021/5/1", "2021/6/3", "2022/9/4"], "平均气温": [28, 31, 27, 33], }, ) df["日期"] = pd.to_datetime(df["日期"]) df["月"] = df["日期"].dt.month print(df) print(df.groupby(df["月"]).sum() #周 df = pd.DataFrame( { "日期": ["2021/5/1", "2021/5/31", "2021/6/3", "2021/9/4"], "平均气温": [28, 31, 27, 33], }, ) df["日期"] = pd.to_datetime(df["日期"]) df["周"] = df["日期"].dt.isocalendar().week print(df) print(df.groupby(df["周"]).sum()) #季度 df = pd.DataFrame( { "日期": ["2021/5/1", "2021/5/31", "2021/6/3", "2021/9/4"], "平均气温": [28, 31, 27, 33], }, ) df["日期"] = pd.to_datetime(df["日期"]) df["季度"] = df["日期"].dt.quarter print(df) print(df.groupby(df["季度"]).sum()) print(df1.dt.day)##****dt.***,只能用于series不可用于数据框 df["HepB_1"].dt.is_leap_year#这样加个dt便可应用用这个数据框了
-
4.通过strftime方法进行
t = df["日期"].dt.strftime("%Y-%m")#输出结果为:'2016-12' print(t)
1.2日期的计算
#计算生日
age = (pd.to_datetime('2019-9-4') - pd.to_datetime('1993-5-27')) / pd.Timedelta(days=365)
print(age)
#做数据筛选
df[(pd.datetime.now()- df['发货日期']) < pd.Timedelta(days=30)]
3.时间特征索引
import pandas as pd
filepath = r"E:\Desktop\配套代码和数据集\配套代码和数据集\第3章:Pandas\Pandas代码\data\flowdata.csv"
df = pd.read_csv(filepath,index_col=0,parse_dates=True) #以时间特征我索引
df[pd.Timestamp("2012"):pd.Timestamp("2013")]
df["2013"]#选取年份
df["2012-1":"2013-03"]#选取时间间隔数据
#接下来试一试日期和小时能不能行?
df["2012-1-20":"2012-3-30"] #日期是可以的!!
df["2012-1-20 21:00:00":"2012-3-30 12:00:00"] #精确到时、分、秒也是可以的,要注意格式问题
df[(df.index.hour>8)&(df.index.hour<21)] #选取每天中在8~21点的数据
#resample函数
#原数据中每天都有好多数据,但想统计的是每天的平均指标
df.resample("D").mean().head() #求每天的平均指标
df.resample("3D").mean().head()#求每3天的平均指标
df.resample("M").min().head()#求每个月的最小值
df.resample("Y").max().head()#求每年的最大值
import pandas as pd
filepath = r"E:\Desktop\区分诊断前和诊断后.xlsx"
df = pd.read_excel(filepath,index_col=1,parse_dates=True) #在此处呢,试验了如果诊断时间(行索引中)存在空值的问题,发现当索引中有空值时
#会自动用NaT代替,并不影响操作结果
df[pd.Timestamp("2018-01-01"):pd.Timestamp("2019-01-10")]#不知道为啥这个怎么也实验不同,难受
记录学习的点点滴滴