pct_change()
计算百分比变化。
cov()
计算协方差。其中用到了内置函数 concat,它是以 Series 对象组成的列表为输出,当参数 axis 的值为 1 的时候把他们一行一行从左到右的组合成一个 DataFrame 的对象,。然后使用方法 cov 得到这三个行之间的一个相关矩阵。
import pandas as pd
import matplotlib.pyplot as plt
stock1 = pd.read_excel('sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
stock2 = pd.read_excel('sz50.xlsx',sheet_name = '600050.XSHG', index_col = 'datetime')
stock3 = pd.read_excel('sz50.xlsx',sheet_name = '601318.XSHG', index_col = 'datetime')
five_day_df = pd.concat([stock1.close.pct_change(5), stock2.close.pct_change(5), stock3.close.pct_change(5)], keys = ['stock1', 'stock2', 'stock3'], axis = 1)
print(five_day_df.cov())
在整个 DataFrame 对象中每一列,每个 Series 对象中含有 nan 无效值时,使用 cov 并不会失败,pandas 用了一种估计的方法来解决这个无效值,并不是简单地用某个固定的值替代,具体参考文章如下,把教程中的任务完成就会来解决这个点。
https://en.wikipedia.org/w/index.php?title=Estimation_of_covariance_matrices
corr()
计算相关系数矩阵,得到的依然是一个 DataFrame 对象。
import pandas as pd
import matplotlib.pyplot as plt
stock1 = pd.read_excel('sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
stock2 = pd.read_excel('sz50.xlsx',sheet_name = '600050.XSHG', index_col = 'datetime')
stock3 = pd.read_excel('sz50.xlsx',sheet_name = '601318.XSHG', index_col = 'datetime')
five_day_df = pd.concat([stock1.close.pct_change(5), stock2.close.pct_change(5), stock3.close.pct_change(5)], keys = ['stock1', 'stock2', 'stock3'], axis = 1)
print(five_day_df.corr())
corr 和 cov 还有一个更基础的用法就是用在单独的 Series 对象上,在 cov 或者 corr 中填入想要比较的另一个 Series 对象。
stock1.close.pct_change()[1:].cov(stock2.close.pct_change[1:])
stock1.close.pct_change()[1:].corr(stock2.close.pct_change[1:])
当然以上的方法要求 Series 对象的长度相同,不然无法匹配。那么如果是 DataFrame 对象,通过默认值为 1 表示列(0 表示行)的参数 axis ,那么会匹配两个对象中 columns 的值相同的列,例如以下代码:
import pandas as pd
import numpy as np
frame1 = pd.DataFrame(np.random.randn(5, 4), index = ['1','2','3','4','5'], columns = ['a', 'b', 'c', 'd'])
frame2 = pd.DataFrame(np.random.randn(4, 4), index = frame1.index[:4], columns = ['a', 'b', 'c', 'd'])
print(frame1.corrwith(frame2))
print(frame2.corrwith(frame1))
结果:
a -0.732968
b -0.246053
c 0.022138
d -0.612281
dtype: float64
a -0.732968
b -0.246053
c 0.022138
d -0.612281
dtype: float64
如果是直接 frame1.corr(frame2) 会报错但报错内容不是很直接地指出我们这个问题,报错内容为
TypeError: Could not compare ['pearson'] with block values
pearson 代表的是 standard correlation coefficient也就是最常见最基础的相关系数的计算方式,因为 DataFrame 对象的 corr 与 Series 对象的 corr 不同,DataFrame 的 corr 接受两个参数 method 和 min_period,method:{‘pearson’, ‘kendall’, ‘spearman’},所以才会报错个什么 pearson。
rank()
排序。得到了每个位置上的数据在该列中的排序的序号,默认的有两个参数,axis 默认为 0 表示按列排序,ascending 为 True 表示升序排列即数值为大排名越靠后(序号越大)。如果数据中有无效值,那么得到的排序相应的位置呈现为 nan,其他的正常数据不受影响。
import pandas as pd
import matplotlib.pyplot as plt
stock1 = pd.read_excel('sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
stock2 = pd.read_excel(‘sz50.xlsx',sheet_name = '600050.XSHG', index_col = 'datetime')
stock3 = pd.read_excel('sz50.xlsx',sheet_name = '601318.XSHG', index_col = 'datetime')
five_day_df = pd.concat([stock1.close.pct_change(5), stock2.close.pct_change(5), stock3.close.pct_change(5)], keys = ['stock1', 'stock2', 'stock3'], axis = 1)
part = five_day_df.tail()
print(part)
print(part.rank())
rolling()
滚动计算。滚动窗口计算的意思是我围绕一个点,用一个确定长度的窗体 window 包含最近一段时间的数据。例如有如下的数据,设窗体的尺度为3,那么 index 为 3 的数据对应的为 [3,5,4].
index | |
1 | 3 |
2 | 5 |
3 | 4 |
4 | 7 |
5 | 3 |
得到 roling 对象之后不能直接整个内容输出,而是要根据需要调用相应的方法。例如 sum,求和;mean,求平均,在官方文档中有相关方法的集合如下。
以如下的代码为例子,可以看出设 window 为 4 时前三个空为零,因为默认的另一个参数 min_period 会等于 window,当然我们可以设置得小于 window 那样子就会使得不必每个窗体都必须有 4 个对象,3个或者更少也没问题。还有参数 center 默认为 False,也就是我们获取当前点为最后一个值的一个箱体,如果 center 设置为 True 就会把我们获取的当前点作为中点,如果 window 的长度为偶数时就会是在 window/2 + 1 个位置上。
import pandas as pd
import matplotlib.pyplot as plt
stock1 = pd.read_excel(’sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
part = stock1.close.head(10)
print(part.rolling(window = 4).sum())
expanding()
expanding 和 rolling 本质是相同的,只不过 expanding 可以忽略 nan 而 rolling 不行,从下面的例子可以看出来。
import pandas as pd
import numpy as np
sn = pd.Series([1, 2, np.nan, 3, np.nan, 4])
print(sn.rolling(window = 2).sum())
print(sn.expanding(2).sum())
apply() & aggregate()
apply 方法在刚才我们谈到的 rolling 的方法中有出现,但是并不局限与 rolling 得到的对象,DataFrame、Series 乃至大多数对象都有 apply 方法,可以供我们执行自己创建的函数。这个函数要求是要以一个 ndarray 作为输入然后输出单个值。
以 rolling 得到的 Rolling 对象举例。我们定义了一个函数 mad,这个函数计算的是一个日期对应的窗口中的所有值,各自与他们均值的差的绝对值(np.fabs 计算绝对值)的平均值。我们也可以写成一个公式,假设 window = 5:
那这个计算式有什么意义呢??与均值的差的绝对值的均值在定义上类似于方差,都是描述波动的强度,我们把这种方式描述的震荡强度和走势一起绘制,注意二者的大小不同。而且 pandas 中的对象都支持 plot 方法,得到的是一个 AxisSubplots 对象,直接 plt.show 就可以得到,更加方便了。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
stock1 = pd.read_excel("sz50.xlsx", sheet_name = '601318.XSHG', index_col = 'datetime')
close = stock1.close
rol = close.rolling(5)
mad = lambda x:np.fabs(x - x.mean()).mean()
ax = rol.apply(mad).plot()
ax1 = ax.twinx()
ax1.plot(close, c= 'r')
plt.show()
可以看到,蓝色代表震荡,红色代表走势,在有较大涨幅时波动性也会更强。不过,波动性终究是个滞后指标,无法帮助我们进行更多有价值的预测。
DataFrame 和 Series 应用 apply 方法类似,不过前者有参数 axis 来控制是将行(1)或者列(0)看成在函数中会用到的array。
groupby()
分组函数。我们可以用在 Series 和 DataFrame 对象上,后者只是简单地重复在每一个列(也就是一个 Series)上执行然后把结果整合起来。官方文档解释的不是很具体我一下子没看明白,百度了一下才发现原来是这样子的意思。用 DataFrame 对象作为例子,代码和结果如下,当我们传入一个代表列名的字符串时,表示我们要按照该列中的序列来分组我们的其他行,例如 data1 这一行中根据 key1 中的指示,把第1、2、5 个归成一组而第3、4 归成一组。
另外也可以传入一个新的数列,也可以实现相同的功能,不过可以看到没有显示是按照该表中的某列去排序即 key1 的字样。
import pandas as pd
df = pd.DataFrame({'key1':['a', 'a', 'b', 'b', 'a'],
'key2':['one','two','two','two','one'],
'data1':[1,1,2,2,3],
'data2':[3,3,4,5,6]})
print(df)
# data1 data2 key1 key2
# 0 1 3 a one
# 1 1 3 a two
# 2 2 4 b two
# 3 2 5 b two
# 4 3 6 a one
grouped = df.groupby('key1').mean()
print(grouped)
# data1 data2
# key1
# a 1.666667 4.0
# b 2.000000 4.5
lis = [1,1,2,2,1]
print(df.groupby(lis).mean())
# data1 data2
# 1 1.666667 4.0
# 2 2.000000 4.5