快乐学习pandas,大家可以看joyful-pandas教程
joyful-pandas
这里全抄答案来打卡,因为准备期末了,搞完期末再回来补
【问题一】 如何对date_range进行批量加帧操作或对某一时间段加大时间戳密度?
【问题二】 如何批量增加TimeStamp的精度?
【问题三】 对于超出处理时间的时间点,是否真的完全没有处理方法?
【问题四】 给定一组非连续的日期,怎么快速找出位于其最大日期和最小日期之间,且没有出现在该组日期中的日期?
【练习一】 现有一份关于某超市牛奶销售额的时间序列数据,请完成下列问题:
(a)销售额出现最大值的是星期几?(提示:利用dayofweek函数)
df['日期'].dt.dayofweek[df['销售额'].idxmax()]
(b)计算除去春节、国庆、五一节假日的月度销售总额
holiday = pd.date_range(start='20170501', end='20170503').append(
pd.date_range(start='20171001', end='20171007')).append(
pd.date_range(start='20180215', end='20180221')).append(
pd.date_range(start='20180501', end='20180503')).append(
pd.date_range(start='20181001', end='20181007')).append(
pd.date_range(start='20190204', end='20190224')).append(
pd.date_range(start='20190501', end='20190503')).append(
pd.date_range(start='20191001', end='20191007'))
result = df[~df['日期'].isin(holiday)].set_index('日期').resample('MS').sum()
(c)按季度计算周末(周六和周日)的销量总额
result = df[df['日期'].dt.dayofweek.isin([5,6])].set_index('日期').resample('QS').sum()
(d)从最后一天开始算起,跳过周六和周一,以5天为一个时间单位向前计算销售总和
df_temp = df[~df['日期'].dt.dayofweek.isin([5,6])].set_index('日期').iloc[::-1]
L_temp,date_temp = [],[0]*df_temp.shape[0]
for i in range(df_temp.shape[0]//5):
L_temp.extend([i]*5)
L_temp.extend([df_temp.shape[0]//5]*(df_temp.shape[0]-df_temp.shape[0]//5*5))
date_temp = pd.Series([i%5==0 for i in range(df_temp.shape[0])])
df_temp['num'] = L_temp
result = pd.DataFrame({'5天总额':df_temp.groupby('num')['销售额'].sum().values},
index=df_temp.reset_index()[date_temp]['日期']).iloc[::-1]
(e)假设现在发现数据有误,所有同一周里的周一与周五的销售额记录颠倒了,请计算2018年中每月第一个周一的销售额(如果该周没有周一或周五的记录就保持不动)
from datetime import datetime
df_temp = df.copy()
df_fri = df.shift(4)[df.shift(4)['日期'].dt.dayofweek==1]['销售额']
df_mon = df.shift(-4)[df.shift(-4)['日期'].dt.dayofweek==5]['销售额']
df_temp.loc[df_fri.index,['销售额']] = df_fri
df_temp.loc[df_mon.index,['销售额']] = df_mon
df_temp.loc[df_temp[df_temp['日期'].dt.year==2018]['日期'][
df_temp[df_temp['日期'].dt.year==2018]['日期'].apply(
lambda x:True if datetime.strptime(str(x).split()[0],'%Y-%m-%d').weekday() == 0
and 1 <= datetime.strptime(str(x).split()[0],'%Y-%m-%d').day <= 7 else False)].index,:]
【练习二】 继续使用上一题的数据,请完成下列问题:
(a)以50天为窗口计算滑窗均值和滑窗最大值(min_periods设为1)
df = pd.read_csv('data/time_series_one.csv',index_col='日期',parse_dates=['日期'])
df['销售额'].rolling(window=50,min_periods=1).max()
(b)现在有如下规则:若当天销售额超过向前5天的均值,则记为1,否则记为0,请给出2018年相应的计算结果
def f(x):
if len(x) == 6:
return 1 if x[-1]>np.mean(x[:-1]) else 0
else:
return 0
result_b = df.loc[pd.date_range(start='20171227',end='20181231'),:].rolling(
window=6,min_periods=1).agg(f)[5:].head()
(c)将©中的“向前5天”改为“向前非周末5天”,请再次计算结果
def f(x):
if len(x) == 8:
return 1 if x[-1]>np.mean(x[:-1][pd.Series([
False if i in [5,6] else True for i in x[:-1].index.dayofweek],index=x[:-1].index)]) else 0
else:
return 0
result_c = df.loc[pd.date_range(start='20171225',end='20181231'),:].rolling(
window=8,min_periods=1).agg(f)[7:].head()