第十章 时序数据

学习参考:https://github.com/datawhalechina/joyful-pandas

Ex1:太阳辐射数据集

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

现有一份关于太阳辐射的数据集:

df = pd.read_csv('../data/solar.csv', usecols=['Data','Time','Radiation','Temperature'])
df.head(3)

在这里插入图片描述

  1. Date, Time合并为一个时间列Datetime,同时把它作为索引后排序。
  2. 每条记录时间的间隔显然并不一致,请解决如下问题:
  • 找出间隔时间的前三个最大值所对应的三组时间戳。
  • 是否存在一个大致的范围,使得绝大多数的间隔时间都落在这个区间中?如果存在,请对此范围内的样本间隔秒数画出柱状图,设置bins=50
  1. 求如下指标对应的Series
  • 温度与辐射量的6小时滑动相关系数
  • 以三点、九点、十五点、二十一点为分割,该观测所在时间区间的温度均值序列
  • 每个观测6小时前的辐射量(一般而言不会恰好取到,此时取最近时间戳对应的辐射量)
#1.将Datetime, Time合并为一个时间列Datetime,同时把它作为索引后排序。
solar_date = df.Data.str.extract(r'([/\w]+\s).+')[0]
solar_date.head()

在这里插入图片描述

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()

在这里插入图片描述

#2.找出间隔时间的前三个最大值所对应的三组时间戳
s = df.index.to_series().reset_index(drop=True)
s

在这里插入图片描述

diff_s = s.diff().dt.total_seconds()  # 间隔时间
diff_s

在这里插入图片描述

max_3 = diff_s.nlargest(3).index  # 间隔时间的前三个最大值对应的索引
max_3

在这里插入图片描述

max_3.union(max_3-1)  # 对应原表的索引

在这里插入图片描述

df.index[max_3.union(max_3-1)]

在这里插入图片描述

#3.是否存在一个大致的范围,使得绝大多数的间隔时间都落在这个区间中?如果存在,请对此范围内的样本间隔秒数画出柱状图,设置bins=50。
res = diff_s.mask((diff_s>diff_s.quantile(0.99))|(diff_s<diff_s.quantile(0.01)))  # 时间间隔数值落在quantile(0.01-0.99)之间
_ = plt.hist(res, bins=50)

在这里插入图片描述

#4.温度与辐射量的6小时滑动相关系数
res = df.Radiation.rolling('6H').corr(df.Temperature)
res.tail()

在这里插入图片描述

#5.以三点、九点、十五点、二十一点为分割,该观测所在时间区间的温度均值序列
res = df.Temperature.resample('6H', origin='03:00:00').mean()
res.head()  # 从前一天的21点开始计算

在这里插入图片描述

#6.每个观测6小时前的辐射量(取最近时间戳对应的辐射量)
my_dt = df.index.shift(freq='-6H')
my_dt[:5]

在这里插入图片描述

int_loc = [df.index.get_loc(i, method='nearest') for i in my_dt]  # my_dt数组中的datatime在df数据框的索引
int_loc[:5]

在这里插入图片描述

res = df.Radiation.iloc[int_loc]
res.head()

在这里插入图片描述

Ex2:水果销量数据集

现有一份2019年每日水果销量记录表:

df = pd.read_csv('../data/fruit.csv')
df.head(3)

在这里插入图片描述

  1. 统计如下指标:
  • 每月上半月(15号及之前)与下半月葡萄销量的比值
  • 每月最后一天的生梨销量总和
  • 每月最后一天工作日的生梨销量总和
  • 每月最后五天的苹果销量均值
  1. 按月计算周一至周日各品种水果的平均记录条数,行索引外层为水果名称,内层为月份,列索引为星期。
  2. 按天计算向前10个工作日窗口的苹果销量均值序列,非工作日的值用上一个工作日的结果填充。
#1.每月上半月(15号及之前)与下半月葡萄销量的比值
df.Date = pd.to_datetime(df.Date)
df_grape = df.query("Fruit == 'Grape'")
df_grape.head()

在这里插入图片描述

np.where(df_grape.Date.dt.day<=15,'First', 'Second')  # 使用'First','Second'分别替代上半月和下半月的日期

在这里插入图片描述

res = df_grape.groupby([np.where(df_grape.Date.dt.day<=15,'First', 'Second'),df_grape.Date.dt.month])['Sale'].mean().to_frame()  # 每月上半月和下半月葡萄销量
res.head()

在这里插入图片描述

res = res.unstack(0).droplevel(0,axis=1)  # 去除外层索引
res.head()

在这里插入图片描述

res = (res.First/res.Second).rename_axis('Month')
res.head()

在这里插入图片描述

#2.每月最后一天的生梨销量总和
pear_df = df[df.Date.dt.is_month_end].query("Fruit == 'Pear'")
pear_df.head()

在这里插入图片描述

pear_df.groupby('Date')['Sale'].sum()

在这里插入图片描述

#3.每月最后一天工作日的生梨销量总和
workday_array = pd.date_range('20190101', '20191231',freq='BM')  # 每月最后一个工作日
workday_array[:5]

在这里插入图片描述

pear_df = df[df.Date.isin(workday_array)].query("Fruit == 'Pear'")
pear_df.head()

在这里插入图片描述

pear_df.groupby('Date').Sale.mean().head()

在这里插入图片描述

#4.每月最后五天的苹果销量均值
target_dt = df.drop_duplicates().groupby(df.Date.drop_duplicates().dt.month)['Date'].nlargest(5).reset_index(drop=True) # 每个月最后五天
target_dt.head()

在这里插入图片描述

res = df.set_index('Date').loc[target_dt].reset_index().query("Fruit == 'Apple'")  # 每个月最后五天苹果销量
res.head()

在这里插入图片描述

res = res.groupby(res.Date.dt.month)['Sale'].mean().rename_axis('Month')
res

在这里插入图片描述

#4.按月计算周一至周日各品种水果的平均记录条数,行索引外层为水果名称,内层为月份,列索引为星期。
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)  # df数据月份替换为英文名
group1.head()

在这里插入图片描述

group2 = df.Fruit
group3 = df.Date.dt.dayofweek.replace(dict(zip(range(7),week_order))
            ).astype('category').cat.reorder_categories(week_order, ordered=True)  # df数据日期按照周一至周日进行替换
group3.head()

在这里插入图片描述

res = df.groupby([group1, group2,group3])['Sale'].count().to_frame()
res.head()

在这里插入图片描述

res = res.unstack(0).droplevel(0,axis=1)
res.head()

在这里插入图片描述

#5.按天计算向前10个工作日窗口的苹果销量均值序列,非工作日的值用上一个工作日的结果填充。
df_apple = df[(df.Fruit=='Apple')&(~df.Date.dt.dayofweek.isin([5,6]))]  # 工作日苹果的销量
df_apple.head()

在这里插入图片描述

s = pd.Series(df_apple.Sale.values,index=df_apple.Date).groupby('Date').sum()  # 工作日苹果的销量
s.head()

在这里插入图片描述

res = s.rolling('10D').mean().reindex(pd.date_range('20190101','20191231')).fillna(method='ffill')  #前10个工作日窗口的苹果销量均值
res.head()

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值