df = DataSource('bar1d_CN_STOCK_A').read(['000001.SZA','300023.SZA'],'2017-02-10','2017-02-20',fields=['close','open','high','low','amount'])
df.head(6)
'''查看按股票分组数据'''
groups = df.groupby('instrument')
for k in groups:
print(k)
'''查看按日期分组数据'''
groups = df.groupby('date')
for k in groups:
print(k)
'''按股票分组计算每个股票一段时间的成交量和收盘价中位数'''
df.groupby('instrument').agg({'amount':'mean','close':'median'})
'''若聚合函数相同可以简化写法'''
df.groupby('instrument')[['amount','close']].mean()
'''按日期分组计算每日所有股票的成交量和收盘价平均值'''
df.groupby('date')[['amount','close']].mean()
'''按股票分组计算某列的标量统计量,eg.和、数量、中位数、分位数、最小值、最大值、平均值、方差、标准差、峰度、平均绝对离差'''
df.groupby('instrument')[['close']].agg({'sum','count','median','min','max','mean','var','std','skew','mad'})
'''按股票分组后对多列进行不同的聚合计算'''
df.groupby('instrument').agg({'amount':['sum','min'],'close':['max','std']})
'''多层索引的处理'''
datas = df.groupby('instrument').agg({'amount':['sum','min'],'close':['max','std']})
print(datas.columns)
columns = [k+'_'+v for k,v in datas.columns]
datas.columns = columns
datas
''''按股票分组计算统计量序列,eg.累积和、累乘、峰度、偏度, 累积最小、累积最大、一阶差分、变化率'''
df_tj = df.groupby('instrument').agg({'low':['cumsum','cumprod','cummin','cummax','diff','pct_change']})
df_tj.head()
'''常用统计量的分组快速查看'''
df.groupby('instrument')[['amount','close']].describe()
df.head()
'''股票分组后计算成交量和收盘价序列的滚动两日平均值(移动均线)'''
df[['avg_amount','avg_close']] = df.groupby('instrument')[['amount','close']].apply(lambda x:x.rolling(2,min_periods=1).mean())
df.head()
df['close_1'] = df.groupby('instrument')['close'].apply(lambda x:x.shift(1))
df.head()
'''将DataFrame转化为收盘价的日期序列表格'''
close_table = df.set_index(['date','instrument'])['close'].unstack() # 或者使用 pd.pivot_table(df, index='date',columns='instrument',values='close')
close_table
'''计算日收益率 即 收盘价的1日变化率'''
daily_ret_table = close_table.pct_change()
daily_ret_table
'''第一天的日收益率填充为0'''
daily_ret_table.fillna(0,inplace=True)
daily_ret_table
'''计算当日净值 = 上一日净值 * (1+日收益率), 这里默认第一天的净值为1.0'''
net_table = (daily_ret_table+1).cumprod()
net_table
'''计算累计收益率 = 每日净值 - 1'''
cum_ret = net_table - 1
cum_ret
'''整合后的快速计算'''
cum_ret = (df.set_index(['date','instrument'])['close'].unstack().pct_change().fillna(0) + 1).cumprod() - 1
cum_ret
'''绘制累计收益率曲线'''
T.plot(cum_ret, title= '股票累计收益率曲线')
df['instrument'].unique()
'''使用axis=1参数改变计算方向为沿行计算'''
df['avg_price'] = df[['close','open']].mean(axis=1)
df.head()
'''纵向拼接'''
pd.concat([df,df,df]).reset_index(drop=True)
'''横向拼接, 指定按公共轴date和instrument对齐,返回索引交集结果'''
df1 = df[['date','instrument','close']].set_index(['date','instrument']).head(3)
print(df1)
df2 = df[['date','instrument','open']].set_index(['date','instrument'])
print(df2)
pd.concat([df1,df2], axis=1,join='inner') # inner表示对于索引不同步时,返回交集结果
'''横向拼接, 指定按公共轴date和instrument对齐,返回索引并集结果'''
pd.concat([df1,df2], axis=1,join='outer') # outer表示对于索引不同步时,返回并集结果
df_tj = df.groupby('instrument').agg({'low':['cumsum','cumprod','cummin','cummax','diff','pct_change']})
columns = [k+'_'+v for k,v in df_tj.columns]
df_tj.columns = columns
df_tj.head()
'''groupby操作后索引顺序没有改变,直接按照索引拼接'''
pd.concat([df, df_tj],axis=1, join='inner')
'''使用merge指定按公共列date和instrument对齐合并,返回的结果方式包括inner、outer、left、right、cross'''
df1 = df[['date','instrument','close']].head(3)
df2 = df[['date','instrument','open']]
df_merge = df1.merge(df2, on=['date', 'instrument'], how='inner')
df_merge
df_merge = df1.merge(df2, on=['date', 'instrument'], how='outer')
df_merge