[pandas组队学习 task-10](http://inter.joyfulpandas.datawhale.club/Content/ch10
import pandas as pd
import numpy as np
path = r'C:\Users\yongx\Desktop\data'
时序中的基本对象
- 时间戳(Data times):表示时刻的特殊字符串,如’2020-9-7 08:00:00’.
pandas
中称之为Timestamp
.由时间戳元素构成的序列可以组成DatetimeIndex
,当将其放入Series
中,Series
的类型将变为datetime64[ns]
,同时当涉及时区时为datetime64[ns,tz]
(tz:TimeZone). - 时间差(Time deltas):两个时刻做差值,
pandas
中表示为Timedelta
. 同样的由时间差元素构成的序列为TimedeltaIndex
,当期放入Series
中后,Series
的类型将变为timedelta64[ns]
,牵涉到时区时同时间戳Date times
类似. - 时间段(Time spans):两个时刻之间的区间.
pandas
中表示为Period
,类似的有PeriodIndex
,放入Series
中后变为Period[freq]
- 日期偏置(Date offsets):只知道具体时刻而不知道具体的时间日期,
在pandas
中表示为DateOffset
,但pandas
中并没有为一列时间偏置专门设计存储类型,原始是需求较为器官,一般情况下只需要对一批时间特征做一个同一的特殊日期偏置
时间戳
Timestamp的构造与属性
- 生成单个时间戳方法:使用
pd.Timestamp
函数方法,可以将常见的日期格式成功转换 - 获取具体的数值方法: 通过
year
,month
,day
,hour
,minute
,second
获取具体所表示的数值. - 获取时间戳表示的范围方法:通过
pd.Timestamp.max
和pd.Timestamp.min
获得时间戳可以表示的范围.因为时间戳的最小精度是ns
,同时使用了64位存储,可以表示时间的范围如下
T i m e R a n g e = 2 64 1 0 9 × 60 × 60 × 24 × 365 ≈ 585 ( Y e a r s ) TimeRange = \frac{2^{64}}{10^9\times60\times60\times 24\times365}\approx585(Years) TimeRange=109×60×60×24×365264≈585(Years)
ts = pd.Timestamp('2020/1/1')
ts
Timestamp('2020-01-01 00:00:00')
ts = pd.Timestamp('2020-1-1 08:10:30')
ts
Timestamp('2020-01-01 08:10:30')
#获取具体的数值
print('year: ',ts.year)
print('month: ',ts.month)
print('day: ',ts.day)
print('hour: ',ts.hour)
print('min: ',ts.minute)
print('second: ',ts.second)
year: 2020
month: 1
day: 1
hour: 8
min: 10
second: 30
#获取时间戳范围
print('上限: ',pd.Timestamp.max)
print('下限: ',pd.Timestamp.min)
上限: 2262-04-11 23:47:16.854775807
下限: 1677-09-21 00:12:43.145225
Datetime序列的生成
通过to_datetime
和date_range
方法组成时间序列.
to_datetime
:将时间戳格式的列表对象转成datetime64[ns]
类型的时间序列,此时返回DatetimeIndex
.to_datetime
也可通过表的多列时间属性拼接成时间序列,但此时需要保证列名同时间关键词列名相同.date_range
:生成连续间隔时间序列,需要参数有start
(开始时间),end
(结束时间),freq
(时间间隔),periods
(时间戳个数).使用时因为之间的运算关系,因此可以通过任意三个参数实现全部功能,asfreq
:根据给定的freq对序列进行类似于reindex
的操作来改变序列采样频率.
注意:
1.极少数情况下可使用
format
方法强制匹配不满足不是要求的时间戳.
2.当to_datetime
传入参数为列表时返回DatetimeIndex
对象,若需要返回datetime[ns]
类型的序列,则需要显式用Series
进行转化.
3.在date_range
函数中,若开始日期或结束日期作为端点,则它本身将被包含.
4.因datetime64[ns]
本质上为一个大整数,所以可以通过max
,min
,mean
来获取该类型序列中关于时间戳的有关特性.
#注意此时返回序列的类型为DatetimeIndex而不是datetime64[ns]
pd.to_datetime(['2020-1-1','2020-1-3','2020-1-6'])
DatetimeIndex(['2020-01-01', '2020-01-03', '2020-01-06'], dtype='datetime64[ns]', freq=None)
df = pd.read_csv(path+'\\learn_pandas.csv')
s = pd.to_datetime(df.Test_Date)
s.head()
0 2019-10-05
1 2019-09-04
2 2019-09-12
3 2020-01-03
4 2019-11-06
Name: Test_Date, dtype: datetime64[ns]
df.Test_Date.head(3)
0 2019/10/5
1 2019/9/4
2 2019/9/12
Name: Test_Date, dtype: object
#使用format参数 强制匹配转换不满足格式的时间戳
temp = pd.to_datetime(['2020\\1\\1','2020\\1\\3'],format='%Y\\%m\\%d')
temp
DatetimeIndex(['2020-01-01', '2020-01-03'], dtype='datetime64[ns]', freq=None)
#通过Series将DatetimeIndex类型序列显示转化,从而获得datetime64[ns]类型的序列
pd.Series(temp).head()
0 2020-01-01
1 2020-01-03
dtype: datetime64[ns]
#使用通过列名为时间关键词的表构建时间时间序列
df_date_cols = pd.DataFrame({'year':[2020,2020],
'month':[1,1],
'day':[1,2],
'hour':[10,20],
'minute':[30,50],
'second':[20,40]})
pd.to_datetime(df_date_cols)
0 2020-01-01 10:30:20
1 2020-01-02 20:50:40
dtype: datetime64[ns]
#使用date_range生成连续间隔的时间, freq参数输入字符串需要指定时间间隔
pd.date_range('2020-1-1','2020-1-21',freq='10D') #包含端点
DatetimeIndex(['2020-01-01', '2020-01-11', '2020-01-21'], dtype='datetime64[ns]', freq='10D')
pd.date_range('2020-1-1','2020-2-28',freq='10D')#半包含
DatetimeIndex(['2020-01-01', '2020-01-11', '2020-01-21', '2020-01-31',
'2020-02-10', '2020-02-20'],
dtype='datetime64[ns]', freq='10D')
#最后一个间隔因为时间取不到而导致时间间隔不同于前面
pd.date_range('2020-1-1','2020-2-28',periods=6)
DatetimeIndex(['2020-01-01 00:00:00', '2020-01-12 14:24:00',
'2020-01-24 04:48:00', '2020-02-04 19:12:00',
'2020-02-16 09:36:00', '2020-02-28 00:00:00'],
dtype='datetime64[ns]', freq=None)
#使用asfreq改变序列采样频率
s = pd.Series(np.random.rand(5), index = pd.to_datetime(['2020-1-%d'%i for i in range(1,10,2)]))
s.head()
2020-01-01 0.265058
2020-01-03 0.137528
2020-01-05 0.281711
2020-01-07 0.016862
2020-01-09 0.626784
dtype: float64
#按照日期进行排序(默认将时间序列补充为连续序列)
s.asfreq('D').head()
2020-01-01 0.265058
2020-01-02 NaN
2020-01-03 0.137528
2020-01-04 NaN
2020-01-05 0.281711
Freq: D, dtype: float64
s.asfreq('12H').head()
2020-01-01 00:00:00 0.265058
2020-01-01 12:00:00 NaN
2020-01-02 00:00:00 NaN
2020-01-02 12:00:00 NaN
2020-01-03 00:00:00 0.137528
Freq: 12H, dtype: float64
dt对象
类似于category
序列中定义的cat
来完成分类数据的操作,string
序列中定义的str
来完成文本数据的操作, 时序类型的序列上定义了dt
对象来完成时序数据的相关操作.相对于datetime64[ns]
类型,大致有三类操作:取出
,判断
和取整
三种操作.
- 取出操作:有以下
date, time, year, moth, day, hour, minute, second, microsecond, nanosecond, dayofweek, weekofyear, daysinmonth, quarter
等常用属性.
1.
daysinmonth
:表示该月共有几天
2.quarter
:表示共有几个季度
3.dayofweek
:返回该周的星期情况,起始值周一为0
4.moth_name
:返回英文的月名(为函数方法)
5.day_name
:返回英文的星期名 (为函数方法)
- 判断操作:主要用来测试是否为月/季/年的第一天或最后一天.常用属性有:
is_year_start, is_quarter_start, is_month_start, is_year_end, is_quarter_end, is_month_end
- 取整操作:
round
(四舍五入),ceil
(向上取整),floor
(向下取整),公共参数为freq
,可选择的包括H, min, s
等等.
s = pd.Series(pd.date_range('2020-1-1','2020-1-3',freq='D'))
s.dt.date
0 2020-01-01
1 2020-01-02
2 2020-01-03
dtype: object
s.dt.time
0 00:00:00
1 00:00:00
2 00:00:00
dtype: object
s.dt.day
0 1
1 2
2 3
dtype: int64
#查看该月共有几天
s.dt.daysinmonth
0 31
1 31
2 31
dtype: int64
#查看日期所属月份英文名, 注意month_name 方法
s.dt.month_name()
0 January
1 January
2 January
dtype: object
#day_name 返回日期所属星期名 注意day_name 也为方法
s.dt.day_name()
0 Wednesday
1 Thursday
2 Friday
dtype: object
#判断该日期是否为该年的第一天
s.dt.is_year_start
0 True
1 False
2 False
dtype: bool
#初始化指定间隔的datetime64[ns] Series序列
s = pd.Series(pd.date_range('2020-1-1 20:35:00',
'2020-1-1 22:35:00',
freq='45min'))
s
0 2020-01-01 20:35:00
1 2020-01-01 21:20:00
2 2020-01-01 22:05:00
dtype: datetime64[ns]
#按小时取整 (四舍五入)
s.dt.round('1H')
0 2020-01-01 21:00:00
1 2020-01-01 21:00:00
2 2020-01-01 22:00:00
dtype: datetime64[ns]
#按小时取整 向上取整
s.dt.ceil('1H')
0 2020-01-01 21:00:00
1 2020-01-01 22:00:00
2 2020-01-01 23:00:00
dtype: datetime64[ns]
#按小时取整, 向下取整
s.dt.floor('1H')
0 2020-01-01 20:00:00
1 2020-01-01 21:00:00
2 2020-01-01 22:00:00
dtype: datetime64[ns]
时间戳的切片和索引
- 利用
dt
对象和布尔条件联合使用选取出某个子时间戳序列 - 利用切片取出连续时间戳
s = pd.Series(np.random.randint(2,size=366), index = pd.date_range('2020-01-01','2020-12-31'))
idx = pd.Series(s.index).dt
s.head()
2020-01-01 0
2020-01-02 0
2020-01-03 1
2020-01-04 1
2020-01-05 1
Freq: D, dtype: int32
#获取每月的第一天或最后一天
s[(idx.is_month_start | idx.is_month_end).values].head()
2020-01-01 0
2020-01-31 1
2020-02-01 0
2020-02-29 0
2020-03-01 1
dtype: int32
#获取双休日
s[(idx.dayofweek.isin([5,6])).values].head()
2020-01-04 1
2020-01-05 1
2020-01-11 0
2020-01-12 0
2020-01-18 1
dtype: int32
#取出单日值
s['2020-01-01']
0
#自动转换日期格式
s['20200101']
0
#取出七月
s['2020-07'].head()
2020-07-01 0
2020-07-02 0
2020-07-03 0
2020-07-04 0
2020-07-05 0
Freq: D, dtype: int32
#取出5月初至7月15日
s['2020-05':'2020-07-15'].head()
2020-05-01 1
2020-05-02 0
2020-05-03 0
2020-05-04 0
2020-05-05 0
Freq: D, dtype: int32
时间差
Timedelta的生成
- 通过
Timedelta
来构成时间差. - 通过
to_timedelta
来生成timedelta64[ns]
类型的时间差序列 - 通过
timedelta_range
来生成时间差序列,类似于date_range
函数
Timedelta
的dt
对象,主要属性包括days
, seconds
, mircroseconds
, nanoseconds
,它们分别返回了对应的时间差特征.
注意:
1.
seconds
不是单纯的秒,而是对天数取余后剩余的秒数.
2.total_seconds
:直接对应秒数而不对天数取余.
3.取整函数同样可以在dt
对象上使用.
4.使用Timedeta生成对象时参数为复数(加s)
#直接做差生成
pd.Timestamp('20200102 08:00:00')-pd.Timestamp('20200101 07:35:00')
Timedelta('1 days 00:25:00')
#通过Timedelta 传入参数生成
pd.Timedelta(days=1,minutes=25)
Timedelta('1 days 00:25:00')
#通过Timedelta 传入字符串生成
pd.Timedelta('1 days 25 minutes')
Timedelta('1 days 00:25:00')
# 使用to_timedelta 生成等差序列
s = pd.to_timedelta(df.Time_Record)
s.head()
0 0 days 00:04:34
1 0 days 00:04:20
2 0 days 00:05:22
3 0 days 00:04:08
4 0 days 00:05:22
Name: Time_Record, dtype: timedelta64[ns]
#使用timedelta_range生成等差序列
pd.timedelta_range('0s','1000s',freq='6min')
TimedeltaIndex(['0 days 00:00:00', '0 days 00:06:00', '0 days 00:12:00'], dtype='timedelta64[ns]', freq='6T')
pd.timedelta_range('0s','1000s',periods=3)
TimedeltaIndex(['0 days 00:00:00', '0 days 00:08:20', '0 days 00:16:40'], dtype='timedelta64[ns]', freq=None)
#获取对天数取余后剩余的秒数
s.dt.seconds.head()
0 274
1 260
2 322
3 248
4 322
Name: Time_Record, dtype: int64
#获取不对天数取余直接对应的秒数
s.dt.total_seconds().head()
0 274.0
1 260.0
2 322.0
3 248.0
4 322.0
Name: Time_Record, dtype: float64
#取整操作
pd.to_timedelta(df.Time_Record).dt.round('min').head()
0 0 days 00:05:00
1 0 days 00:04:00
2 0 days 00:05:00
3 0 days 00:04:00
4 0 days 00:05:00
Name: Time_Record, dtype: timedelta64[ns]
Timedelta的运算
三种常用运算
- 与标量的乘法运算
- 与时间戳的加减法运算
- 与时间差的加减法与除法运算
注意: 所有允许的运算均可实现在时间差序列中
td1 = pd.Timedelta(days=1)
td2 = pd.Timedelta(days=3)
ts = pd.Timestamp('20200101')
#与标量的乘法运算
td1*2
Timedelta('2 days 00:00:00')
#与时间差的减法运算
td2-td1
Timedelta('2 days 00:00:00')
#与时间戳的加法运算
ts+td1
Timestamp('2020-01-02 00:00:00')
日期偏置
Offset对象
日期偏置为一种和日历相关的特殊时间差, 即将模糊的时间表达转化为具体的时间戳形式.
Offset
对象在pd.offsets
中被定义, 当使用+
时表示获取离其最近的下一个日期, 使用-
时表示获取离其最近的上一个日期CDay
:特殊的Offset
对象CDay
,CDay
的holidays, weekmask
参数可以分别对自定义的日期和时间进行过滤.
1.
holidays
传入需要过滤的日期列表
2.weekmask
传入的为三个字母的星期缩写所构成的星期字符串,作用是只保留字符串中出现的星期
**注意:**由于当前版本存在一些bug
导致无法正常使用Day
级别以下的Offset
对象,如Hour
,Second
等, 需要通过对应的Timedelta
对象来代替实现
#求解2020年9月的第一个周一的日期
pd.Timestamp('20200901') + pd.offsets.WeekOfMonth(week=0,weekday=0)
Timestamp('2020-09-07 00:00:00')
#求解2020年9月7日之后的第30个工作日 BDay : B(工作), Day(日)
pd.Timestamp('20200907') + pd.offsets.BDay(30)
Timestamp('2020-10-19 00:00:00')
#获取离目标日期最近的上一个日期
pd.Timestamp('20200901')-pd.offsets.WeekOfMonth(week=0, weekday = 0)
Timestamp('2020-08-03 00:00:00')
pd.Timestamp('20200907')-pd.offsets.BDay(30)
Timestamp('2020-07-27 00:00:00')
#获取时间戳所在的月份的最后一天的时间戳 MonthEnd
pd.Timestamp('20200907') +pd.offsets.MonthEnd()
Timestamp('2020-09-30 00:00:00')
#日期和假日过滤
# n表示增加一天CDay,只保留 Wed 和Fri 两天, 将2020-01-09过滤掉
my_filter = pd.offsets.CDay(n=1, weekmask='Wed Fri', holidays='20200109')
dr = pd.date_range('20200108','20200111')
dr.to_series().dt.dayofweek
2020-01-08 2
2020-01-09 3
2020-01-10 4
2020-01-11 5
Freq: D, dtype: int64
[i+my_filter for i in dr]
[Timestamp('2020-01-10 00:00:00'),
Timestamp('2020-01-10 00:00:00'),
Timestamp('2020-01-15 00:00:00'),
Timestamp('2020-01-15 00:00:00')]
偏置字符串
date_range
的freq
取值可使用Offset
对象, 在pandas
中每一个Offset
对象均绑定了日期偏置字符串(frequencies strings /offset aliases
), 可以指定Offset
对应的字符串来替代使用:
MS
: 月初 == pd.offsets.MonthBegin()M
:月末 == pd.offsets.MonthEnd()B
:工作日 == pd.offsets.BDay()W-MON
:周一 == pd.offsets.CDay()WOM-1MON
:每月的第一个周一 == pd.offsets.WeekOfMonth(week=0,weekday=0)
#获取月初 MS : Month Start
pd.date_range('20200101', '20200331',freq='MS')
DatetimeIndex(['2020-01-01', '2020-02-01', '2020-03-01'], dtype='datetime64[ns]', freq='MS')
#获取月末
pd.date_range('20200101','20200331', freq='M')
DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31'], dtype='datetime64[ns]', freq='M')
#获取工作日
pd.date_range('20200101','20200110',freq='B')
DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-06',
'2020-01-07', '2020-01-08', '2020-01-09', '2020-01-10'],
dtype='datetime64[ns]', freq='B')
#获取周一
pd.date_range('20200101','20200201', freq='W-MON')
DatetimeIndex(['2020-01-06', '2020-01-13', '2020-01-20', '2020-01-27'], dtype='datetime64[ns]', freq='W-MON')
#获取每月的第一个周一
pd.date_range('20200101','20200201', freq ='WOM-1MON')
DatetimeIndex(['2020-01-06'], dtype='datetime64[ns]', freq='WOM-1MON')
#使用Offset对象完成等价操作
#获取月初
pd.date_range('20200101','20200331',freq = pd.offsets.MonthBegin())
DatetimeIndex(['2020-01-01', '2020-02-01', '2020-03-01'], dtype='datetime64[ns]', freq='MS')
注意:
各类时间对象的开发,除了使用 python
内置的 datetime
模块, pandas 还利用了 dateutil
模块,很大一部分是为了处理时区问题。众所周知,我国是没有夏令时调整时间一说的,但有些国家会有这种做法,导致了相对而言一天里可能会有23/24/25个小时,也就是 relativedelta
,这使得 Offset
对象和 Timedelta
对象有了对同一问题处理产生不同结果的现象,其中的规则也较为复杂,官方文档的写法存在部分描述错误,并且难以对描述做出统一修正,因为牵涉到了 Offset
相关的很多组件。暂时完全不考虑时区处理
时序中的滑窗与分组
滑动窗口
- 时序的滑窗函数, 以
freq
关键词代替滑动窗口 - 对于
shift
函数而言,作用在datetime64
为索引的序列上时,可以指定freq
单位进行滑动 - 可通过对
datetime64[ns]
类型的序列进行diff
操作后从而得到timedelta64[ns]
的序列, 这种操作后的序列有助于观察有序时间序列的间隔
import matplotlib.pyplot as plt
idx = pd.date_range('20200101','20201231',freq='B')
np.random.seed(2020)
data = np.random.randint(-1, 2, len(idx)).cumsum()
s = pd.Series(data, index = idx)
s.head()
2020-01-01 -1
2020-01-02 -2
2020-01-03 -1
2020-01-06 -1
2020-01-07 -2
Freq: B, dtype: int32
r = s.rolling('30D')
plt.plot(s)
plt.title('BOLL LINES')
plt.plot(r.mean())
plt.plot(r.mean()+r.std()*2)
plt.plot(r.mean()-r.std()*2)
plt.show()
my_series = pd.Series(s.index)
my_series.head()
0 2020-01-01
1 2020-01-02
2 2020-01-03
3 2020-01-06
4 2020-01-07
dtype: datetime64[ns]
my_series.diff(1).head()
0 NaT
1 1 days
2 1 days
3 3 days
4 1 days
dtype: timedelta64[ns]
重采样
- 针对时间序列的分组计算而设计的分组对象
resample
操纵及功能类似于groupby
- 若没有内置定义的处理函数,可以通过
apply
方法实现自定义的函数功能 - 在
resample
中需要注意组边界值的处理情况,默认情况开始值的计算方法从最小值时间戳对应日期的午夜00:00:00
开始增加freq
,直到不超过该最小时间戳的最大时间戳,由此对应的时间戳为起始值,每次累加freq
参数作为分割结点进行分组,区间情况为左闭右开.*** 意思即使用resample
时需要注意默认情况resample
的起点为该时间戳当天午夜0:00:00
开始经由多个freq
而得到的最接近于起始点的时间戳.*** - 可以通过指定
origin
参数为start
来从序列的最小时间戳开始依次增加freq
进行分组. - 索引一般为取组的第一个时间戳,但
M, A, Q, BM, BA, BQ, W
七个为取对应区间的最后一个时间戳
#计算每十天的均值
s.resample('10D').mean().head()
2020-01-01 -2.000000
2020-01-11 -3.166667
2020-01-21 -3.625000
2020-01-31 -4.000000
2020-02-10 -0.375000
Freq: 10D, dtype: float64
#计算每十天内的最大值与最小值之差
s.resample('10D').apply(lambda x:x.max()-x.min()).head()
2020-01-01 3
2020-01-11 4
2020-01-21 4
2020-01-31 2
2020-02-10 4
Freq: 10D, dtype: int32
#起始时间戳满足fre的运算方法构成的数组
idx = pd.date_range('20200101 8:26:35', '20200101 9:31:58', freq='77s')
data = np.random.randint(-1, 2, len(idx)).cumsum()
s = pd.Series(data, index = idx)
s.head()
2020-01-01 08:26:35 -1
2020-01-01 08:27:52 -1
2020-01-01 08:29:09 -2
2020-01-01 08:30:26 -3
2020-01-01 08:31:43 -4
Freq: 77S, dtype: int32
#时间戳不满足freq的运算方法构成的数组,此时不同于原起点
s.resample('7min').mean().head()
2020-01-01 08:24:00 -1.750000
2020-01-01 08:31:00 -2.600000
2020-01-01 08:38:00 -2.166667
2020-01-01 08:45:00 0.200000
2020-01-01 08:52:00 2.833333
Freq: 7T, dtype: float64
#将origin参数设置为start以保证起始端点为原始端点
s.resample('7min', origin='start').mean().head()
2020-01-01 08:26:35 -2.333333
2020-01-01 08:33:35 -2.400000
2020-01-01 08:40:35 -1.333333
2020-01-01 08:47:35 1.200000
2020-01-01 08:54:35 3.166667
Freq: 7T, dtype: float64
# 取组最后一个时间戳的参数 M, A, Q, BM, BA, BQ, W
s = pd.Series(np.random.randint(2, size = 366),
index = pd.date_range('2020-01-01',
'2020-12-31'))
s.resample('M').mean().head()
2020-01-31 0.451613
2020-02-29 0.448276
2020-03-31 0.516129
2020-04-30 0.566667
2020-05-31 0.451613
Freq: M, dtype: float64
#返回组第一个时间戳的 参数
s.resample('MS').mean().head()
2020-01-01 0.451613
2020-02-01 0.448276
2020-03-01 0.516129
2020-04-01 0.566667
2020-05-01 0.451613
Freq: MS, dtype: float64
df = pd.read_csv(path+'\\solar.csv', usecols = ['Data', 'Time','Radiation', 'Temperature'])
df.head(3)
Data | Time | Radiation | Temperature | |
---|---|---|---|---|
0 | 9/29/2016 12:00:00 AM | 23:55:26 | 1.21 | 48 |
1 | 9/29/2016 12:00:00 AM | 23:50:23 | 1.21 | 48 |
2 | 9/29/2016 12:00:00 AM | 23:45:26 | 1.23 | 48 |
solar_date = df.Data.str.extract('([/|\w]+\s).+')[0]
df['Data'] = pd.to_datetime(solar_date+df.Time)
df = df.drop(columns = 'Time').rename(columns={'Data':'Datetime'}).set_index('Datetime').sort_index()
df.head(3)
Radiation | Temperature | |
---|---|---|
Datetime | ||
2016-09-01 00:00:08 | 2.58 | 51 |
2016-09-01 00:05:10 | 2.83 | 51 |
2016-09-01 00:20:06 | 2.16 | 51 |
s = df.index.to_series().reset_index(drop = True).diff().dt.total_seconds()
max_3 = s.nlargest(3).index
df.index[max_3.union(max_3 - 1)]
DatetimeIndex(['2016-09-29 23:55:26', '2016-10-01 00:00:19',
'2016-11-29 19:05:02', '2016-12-01 00:00:02',
'2016-12-05 20:45:53', '2016-12-08 11:10:42'],
dtype='datetime64[ns]', name='Datetime', freq=None)
res = s.mask((s>s.quantile(0.99)) | (s<s.quantile(0.01)))
plt.hist(res, bins = 50)
plt.show()
C:\Users\yongx\Miniconda3\envs\TF_2C\lib\site-packages\numpy\lib\histograms.py:824: RuntimeWarning: invalid value encountered in greater_equal
keep = (tmp_a >= first_edge)
C:\Users\yongx\Miniconda3\envs\TF_2C\lib\site-packages\numpy\lib\histograms.py:825: RuntimeWarning: invalid value encountered in less_equal
keep &= (tmp_a <= last_edge)
res = df.Radiation.rolling('6H').corr(df.Temperature)
res.head(3)
Datetime
2016-09-01 00:00:08 NaN
2016-09-01 00:05:10 NaN
2016-09-01 00:20:06 inf
dtype: float64
res.tail(3)
Datetime
2016-12-31 23:45:04 0.328574
2016-12-31 23:50:03 0.261883
2016-12-31 23:55:01 0.262406
dtype: float64
res = df.Temperature.resample('6H', origin = '03:00:00').mean()
res.head()
Datetime
2016-08-31 21:00:00 51.218750
2016-09-01 03:00:00 50.033333
2016-09-01 09:00:00 59.379310
2016-09-01 15:00:00 57.984375
2016-09-01 21:00:00 51.393939
Freq: 6H, Name: Temperature, dtype: float64
my_dt = df.index.shift(freq= '-6H')
int_loc = [df.index.get_loc(i, method = 'nearest') for i in my_dt]
res = df.Radiation.iloc[int_loc]
res.tail(3)
Datetime
2016-12-31 17:45:02 9.33
2016-12-31 17:50:01 8.49
2016-12-31 17:55:02 5.84
Name: Radiation, dtype: float64
df = pd.read_csv(path + '\\fruit.csv')
df.head(3)
Date | Fruit | Sale | |
---|---|---|---|
0 | 2019-04-18 | Peach | 15 |
1 | 2019-12-29 | Peach | 15 |
2 | 2019-06-05 | Peach | 19 |
df.Date = pd.to_datetime(df.Date)
df_grape = df.query("Fruit == 'Grape'")
res = df_grape.groupby([np.where(df_grape.Date.dt.day<=15, 'First','Second'),
df_grape.Date.dt.month])['Sale'].mean().to_frame().unstack(0).droplevel(0, axis = 1)
res = (res.First / res.Second).rename_axis('Month')
res.head()
Month
1 1.174998
2 0.968890
3 0.951351
4 1.020797
5 0.931061
dtype: float64
df[df.Date.dt.is_month_end].query("Fruit == 'Pear'").groupby('Date').Sale.sum().head()
Date
2019-01-31 847
2019-02-28 774
2019-03-31 761
2019-04-30 648
2019-05-31 616
Name: Sale, dtype: int64
df[df.Date.isin(pd.date_range('20190101', '20191231',
freq = 'BM'))].query("Fruit =='Pear'").groupby('Date').Sale.mean().head()
Date
2019-01-31 60.500000
2019-02-28 59.538462
2019-03-29 56.666667
2019-04-30 64.800000
2019-05-31 61.600000
Name: Sale, dtype: float64
target_dt = df.drop_duplicates().groupby(df.Date.drop_duplicates().dt.month)['Date'].nlargest(5).reset_index(drop = True)
res = df.set_index('Date').loc[target_dt].reset_index().query("Fruit=='Apple'")
res = res.groupby(res.Date.dt.month)['Sale'].mean().rename_axis('Month')
res.head()
Month
1 65.313725
2 54.061538
3 59.325581
4 65.795455
5 57.465116
Name: Sale, dtype: float64
month_order = ['January','February','March','April','May','June',
'July','August','September','October','November','December']
week_order = ['Mon','Tue','Wed','Thu','Fri','Sat','Sum']
group1 = df.Date.dt.month_name().astype('category').cat.reorder_categories(month_order, ordered = True)
group2 = df.Fruit
group3 = df.Date.dt.dayofweek.replace(dict(zip(range(7),week_order))) .astype('category').cat.reorder_categories(week_order, ordered = True)
res = df.groupby([group1, group2, group3])['Sale'].count().to_frame().unstack(0).droplevel(0, axis = 1)
res.head()
Date | January | February | March | April | May | June | July | August | September | October | November | December | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Fruit | Date | ||||||||||||
Apple | Mon | 46 | 43 | 43 | 47 | 43 | 40 | 41 | 38 | 59 | 42 | 39 | 45 |
Tue | 50 | 40 | 44 | 52 | 46 | 39 | 50 | 42 | 40 | 57 | 47 | 47 | |
Wed | 50 | 47 | 37 | 43 | 39 | 39 | 58 | 43 | 35 | 46 | 47 | 38 | |
Thu | 45 | 35 | 31 | 47 | 58 | 33 | 52 | 44 | 36 | 63 | 37 | 40 | |
Fri | 32 | 33 | 52 | 31 | 46 | 38 | 37 | 48 | 34 | 37 | 46 | 41 |
df_apple = df[(df.Fruit=='Apple') & ~df.Date.dt.dayofweek.isin([5,6])]
s = pd.Series(df_apple.Sale.values, index = df_apple.Date).groupby('Date').sum()
res = s.rolling('10D').mean().reindex(pd.date_range('20190101','20191231')).fillna(method='ffill')
res.head()
2019-01-01 189.000000
2019-01-02 335.500000
2019-01-03 520.333333
2019-01-04 527.750000
2019-01-05 527.750000
Freq: D, dtype: float64