一.高级处理-交叉表与透视表
学习目标
- 目标
- 应用crosstab和pivot_table实现交叉表与透视表
- 应用
- 股票的每日涨跌跟星期几关系大
1 交叉表与透视表什么作用
探究股票的涨跌与星期几有关?
以下图当中表示,week代表星期几,1,0代表这一天股票的涨跌幅是好还是坏,里面的数据代表比例
可以理解为所有时间为星期一等等的数据当中涨跌幅好坏的比例
2 使用crosstab(交叉表)实现上图
-
交叉表:
交叉表用于计算一列数据对于另外一列数据的分组个数(寻找两个列之间的关系)
- pd.crosstab(value1, value2)
- DataFrame.pivot_table([], index=[])
3 案例分析
3.1 数据准备
- 准备两列数据,星期数据以及涨跌幅是好是坏数据
- 进行交叉表计算
# 寻找星期几跟股票张得的关系
# 1、先把对应的日期找到星期几
date = pd.to_datetime(data.index).weekday
data['week'] = date
# 2、假如把p_change按照大小去分个类0为界限
data['posi_neg'] = np.where(data['p_change'] > 0, 1, 0)
# 通过交叉表找寻两列数据的关系
count = pd.crosstab(data['week'], data['posi_neg'])
但是我们看到count只是每个星期日子的好坏天数,并没有得到比例,该怎么去做?
- 对于每个星期一等的总天数求和,运用除法运算求出比例
# 算数运算,先求和
sum = count.sum(axis=1).astype(np.float32)
# 进行相除操作,得出比例
pro = count.div(sum, axis=0)
3.2 查看效果
使用plot画出这个比例,使用stacked的柱状图
pro.plot(kind='bar', stacked=True)
plt.show()
3.3 使用pivot_table(透视表)实现
使用透视表,刚才的过程更加简单
# 通过透视表,将整个过程变成更简单一些
data.pivot_table(['posi_neg'], index='week')
4 小结
- 交叉表与透视表的作用【知道】
二.案例实现
交叉表和透视表
In [65]:
data.index
Out[65]:
Index(['2018-02-27', '2018-02-26', '2018-02-23', '2018-02-22', '2018-02-14',
'2018-02-13', '2018-02-12', '2018-02-09', '2018-02-08', '2018-02-07',
...
'2015-03-13', '2015-03-12', '2015-03-11', '2015-03-10', '2015-03-09',
'2015-03-06', '2015-03-05', '2015-03-04', '2015-03-03', '2015-03-02'],
dtype='object', length=643)
In [66]:
time = pd.to_datetime(data.index)
In [68]:
time
Out[68]:
DatetimeIndex(['2018-02-27', '2018-02-26', '2018-02-23', '2018-02-22',
'2018-02-14', '2018-02-13', '2018-02-12', '2018-02-09',
'2018-02-08', '2018-02-07',
...
'2015-03-13', '2015-03-12', '2015-03-11', '2015-03-10',
'2015-03-09', '2015-03-06', '2015-03-05', '2015-03-04',
'2015-03-03', '2015-03-02'],
dtype='datetime64[ns]', length=643, freq=None)
In [70]:
time.day
Out[70]:
Int64Index([27, 26, 23, 22, 14, 13, 12, 9, 8, 7,
...
13, 12, 11, 10, 9, 6, 5, 4, 3, 2],
dtype='int64', length=643)
In [73]:
weekday = time.weekday
In [75]:
data["week"] = weekday
- 以上操作获得星期几后,添加到表尾。
In [77]:
data.head()
Out[77]:
open | high | close | low | volume | price_change | p_change | ma5 | ma10 | ma20 | v_ma5 | v_ma10 | v_ma20 | turnover | week | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2018-02-27 | 23.53 | 25.88 | 24.16 | 23.53 | 95578.03 | 0.63 | 2.68 | 22.942 | 22.142 | 22.875 | 53782.64 | 46738.65 | 55576.11 | 2.39 | 1 |
2018-02-26 | 22.80 | 23.78 | 23.53 | 22.80 | 60985.11 | 0.69 | 3.02 | 22.406 | 21.955 | 22.942 | 40827.52 | 42736.34 | 56007.50 | 1.53 | 0 |
2018-02-23 | 22.88 | 23.37 | 22.82 | 22.71 | 52914.01 | 0.54 | 2.42 | 21.938 | 21.929 | 23.022 | 35119.58 | 41871.97 | 56372.85 | 1.32 | 4 |
2018-02-22 | 22.25 | 22.76 | 22.28 | 22.02 | 36105.01 | 0.36 | 1.64 | 21.446 | 21.909 | 23.137 | 35397.58 | 39904.78 | 60149.60 | 0.90 | 3 |
2018-02-14 | 21.49 | 21.99 | 21.92 | 21.48 | 23331.04 | 0.44 | 2.05 | 21.366 | 21.923 | 23.253 | 33590.21 | 42935.74 | 61716.11 | 0.58 | 2 |
- 获得股票涨的部分
In [87]:
data["p_n"] = np.where(data["p_change"]>0,1,0) #假如把p_change按照大小去分个类0为界限
In [89]:
data.head()
Out[89]:
open | high | close | low | volume | price_change | p_change | ma5 | ma10 | ma20 | v_ma5 | v_ma10 | v_ma20 | turnover | week | p_n | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2018-02-27 | 23.53 | 25.88 | 24.16 | 23.53 | 95578.03 | 0.63 | 2.68 | 22.942 | 22.142 | 22.875 | 53782.64 | 46738.65 | 55576.11 | 2.39 | 1 | 1 |
2018-02-26 | 22.80 | 23.78 | 23.53 | 22.80 | 60985.11 | 0.69 | 3.02 | 22.406 | 21.955 | 22.942 | 40827.52 | 42736.34 | 56007.50 | 1.53 | 0 | 1 |
2018-02-23 | 22.88 | 23.37 | 22.82 | 22.71 | 52914.01 | 0.54 | 2.42 | 21.938 | 21.929 | 23.022 | 35119.58 | 41871.97 | 56372.85 | 1.32 | 4 | 1 |
2018-02-22 | 22.25 | 22.76 | 22.28 | 22.02 | 36105.01 | 0.36 | 1.64 | 21.446 | 21.909 | 23.137 | 35397.58 | 39904.78 | 60149.60 | 0.90 | 3 | 1 |
2018-02-14 | 21.49 | 21.99 | 21.92 | 21.48 | 23331.04 | 0.44 | 2.05 | 21.366 | 21.923 | 23.253 | 33590.21 | 42935.74 | 61716.11 | 0.58 | 2 | 1 |
- 得到股票涨和星期的交集
In [90]:
count = pd.crosstab(data["week"],data["p_n"])
In [91]:
count
Out[91]:
p_n | 0 | 1 |
---|---|---|
week | ||
0 | 63 | 62 |
1 | 55 | 76 |
2 | 61 | 71 |
3 | 63 | 65 |
4 | 59 | 68 |
- 先求和,再相除得出好坏占的比例
In [93]:
sum = count.sum(axis=1)
In [94]:
sum
Out[94]:
week
0 125
1 131
2 132
3 128
4 127
dtype: int64
In [98]:
per = count.div(sum,axis = 0)
In [99]:
per
Out[99]:
p_n | 0 | 1 |
---|---|---|
week | ||
0 | 0.504000 | 0.496000 |
1 | 0.419847 | 0.580153 |
2 | 0.462121 | 0.537879 |
3 | 0.492188 | 0.507812 |
4 | 0.464567 | 0.535433 |
In [107]:
# stacked = True:堆叠
per.plot(kind = "bar",stacked = True)
Out[107]:
<AxesSubplot:xlabel='week'>
In [109]:
per.plot(kind = "bar")
Out[109]:
<AxesSubplot:xlabel='week'>
- 使用透视表,让以上过程更简单:pivot_table([“需要求占比的列”,index = “索引列”])
In [113]:
pro2 = data.pivot_table(["p_n"],index="week")
# 输出p_n为1的占比
Out[113]:
p_n | |
---|---|
week | |
0 | 0.496000 |
1 | 0.580153 |
2 | 0.537879 |
3 | 0.507812 |
4 | 0.535433 |
pro2.plot(kind = "bar")