Pandas数据分析-Task11
记录DataWhale的Pandas数据分析的学习过程,使用的教材为 joyful-pandas。
Task10是pandas的时间序列数据的处理,内容基本可以分为四个部分,第一部分介绍了pandas中时序数据的四个基本对象;第二部分介绍了时间戳的构造,索引,dt对象;第三部分介绍了时间差的构造,dt对象和运算;第三部分介绍了日期偏执对象及其常用方法;第四部分介绍了时序滑动窗口和分组。本篇文章中所有的代码示例中用到的原始文件都可以在 此链接中下载。
思维导图
练习1-太阳辐射数据集
1 .思路:需要先将原始表格中Data这一列的日期提取出来,可以考虑使用上一节中的str.extract(正则表达式),然后和Time这一列的时间拼接,同样可以使用上一节中提到的str.cat()函数,然后通过pd.to_to_datetime()函数就能得到时间序列,最后使用set_index()设置index即可。
df = pd.read_csv('data/solar.csv', usecols=['Data','Time', 'Radiation','Temperature'])
r=df.Data.str.extract('(\d+.\d+.\d+)')[0].str.cat(df.Time,'-')#提取日期并与Time列拼接
df['Datetime']=pd.to_datetime(r,format='%m/%d/%Y-%H:%M:%S')#转换成日期类型
df=df.drop(columns=['Data','Time']).set_index('Datetime').sort_index()
>>>
> 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
2016-09-01 00:25:05 2.21 51
2016-09-01 00:30:09 2.25 51
2-(a) .思路:元素为datetime64[ns]类型的Series可以直接使用diff方法求相邻两个数据的时间差,为方便比较,我们使用dt.total_seconds()函数将时间差统一转换为秒,然后再用nlargest(3).index函数即可求出最大的3个值对应的下标。因为这个下标是diff()后的,所以对应的应该是(index-1,index)这一组时间的差,可以使用union()函数将index-1和index合并到一个列表中。
s_idx=pd.Series(df.index).diff(1).dt.total_seconds()#index转化为Series求diff
df.index[(s_idx.nlargest(3).index).union((s_idx.nlargest(3).index)-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)
2-(b) 思路:求绝大部分间隔落在的区间,可以根据分位点确定。
import matplotlib.pyplot as plt
r=s_idx.where((s_idx<s_idx.quantile(0.99)) & (s_idx>s_idx.quantile(0.01)))
plt.hist(r, bins=50)
plt.show()
3(a)思路:使用rolling()构造滑动对象,freq=6H
rad=df.Radiation.rolling('6H')
rad.corr(df.Temperature)
3(b) 思路:三点、九点、十五点、二十一点的区间的均值,就是求从3点开始没隔6个小时分一组,时间序列分组用resample()函数,从3点开始,设置origin='03:00:00’即可。
df.Temperature.resample('6H',origin='03:00:00').mean()
>>>
>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
练习2-水果销量数据集
1-(a)思路:根据月份和每个月的上半月下半月对表格进行分组,关键是如何判断上半月和下半月,时间序列类型的数据有.day属性,可以返回时间是哪一天,根据这个性质可以进行判断。
df = pd.read_csv('data/fruit.csv')
df.Date = pd.to_datetime(df.Date)#先转化为时间序列格式
df_grape = df.loc[df.Fruit == 'Grape'] #只对葡萄进行操作
s=df_grape.Date.apply(lambda x: '月初' if x.day>=15 else '月末')#根据月初月末返回不同的分组依据
r=df_grape.groupby([s,df.Date.dt.month])['Sale'].sum().unstack(0)#分组
(r.月初/r.月末).rename_axis('Month')
>>>
>Month
1 1.133159
2 1.201336
3 1.490644
4 1.142372
5 1.306105
2-(b) 思路:主要是如何判断某个日期是否为一个月的最后一天,dt.dt.is_month_end即可达到这个要求,返回的布尔序列可以作为索引。
df[df.Date.dt.is_month_end].loc[df.Fruit=='Pear'].groupby(df.Date.dt.month)['Sale'].sum().rename_axis('Month')
>>>
>Month
1 847
2 774
3 761
4 648
5 616