深入浅出pandas-5
我们再来补充一些使用DataFrame
做数据分析时会使用到的操作,这些操作不仅常见而且也非常重要。
计算同比环比
我们之前讲过一个统计月度销售额的例子,我们可以通过groupby
方法做分组聚合,也可以通过pivot_table
生成透视表,如下所示。
sales_df = pd.read_excel('data/2020年销售数据.xlsx')
sales_df['月份'] = sales_df.销售日期.dt.month
sales_df['销售额'] = sales_df.售价 * sales_df.销售数量
result_df = sales_df.pivot_table(index='月份', values='销售额', aggfunc='sum')
result_df.rename(columns={
'销售额': '本月销售额'}, inplace=True)
result_df
输出:
本月销售额
月份
1 5409855
2 4608455
3 4164972
4 3996770
5 3239005
6 2817936
7 3501304
8 2948189
9 2632960
10 2375385
11 2385283
12 1691973
在得到月度销售额之后,如果我们需要计算月环比,这里有两种方案。第一种方案是我们可以使用shift
方法对数据进行移动,将上一个月的数据与本月数据对齐,然后通过(本月销售额 - 上月销售额) / 上月销售额
来计算月环比,代码如下所示。
result_df['上月销售额'] = result_df.本月销售额.shift(1)
result_df
输出:
本月销售额 上月销售额
月份
1 5409855 NaN
2 4608455 5409855.0
3 4164972 4608455.0
4 3996770 4164972.0
5 3239005 3996770.0
6 2817936 3239005.0
7 3501304 2817936.0
8 2948189 3501304.0
9 2632960 2948189.0
10 2375385 2632960.0
11 2385283 2375385.0
12 1691973 2385283.0
在上面的例子中,shift
方法的参数为1
表示将数据向下移动一个单元,当然我们可以使用参数-1
将数据向上移动一个单元。相信大家能够想到,如果我们有更多年份的数据,我们可以将参数设置为12
,这样就可以计算今年的每个月与去年的每个月之间的同比。
result_df['环比'] = (result_df.本月销售额 - result_df.上月销售额) / result_df.上月销售额
result_df.style.format(
formatter={
'上月销售额': '{:.0f}', '环比': '{:.2%}'},
na_rep='--------'
)
输出:
本月销售额 上月销售额 环比
月份
1 5409855 -------- --------
2 4608455 5409855 -14.81%
3 4164972 4608455 -9.62%
4 3996770 4164972 -4.04%
5 3239005 3996770 -18.96%
6 2817936 3239005 -13.00%
7 3501304 2817936 24.25%
8 2948189 3501304 -15.80%
9 2632960 2948189 -10.69%
10 2375385 2632960 -9.78%
11 2385283 2375385 0.42%
12 1691973 2385283 -29.07%
说明:使用 JupyterLab 时,可以通过
DataFrame
对象的style
属性在网页中对其进行渲染,上面的代码通过Styler
对象的format
方法将环比格式化为百分比进行显示,此外还指定了将空值替换为--------
。
更为简单的第二种方案是直接使用pct_change
方法计算变化的百分比,我们先将之前的上月销售额和环比列删除掉。
result_df.drop(columns=['上月销售额', '环比'], inplace=True)
接下来,我们使用DataFrame
对象的pct_change
方法完成环比的计算。值得一提的是,pct_change
方法有一个名为periods
的参数,它的默认值是1
,计算相邻两项数据变化的百分比,这不就是我们想要的环比吗?如果我们有很多年的数据,在计算时把这个参数的值修改为12
,就可以得到相邻两年的月同比。
result_df['环比'] = result_df.pct_change()
result_df
窗口计算
DataFrame
对象的rolling
方法允许我们将数据置于窗口中,然后用函数对窗口中的数据进行运算和处理。例如,我们获取了某只股票近期的数据,想制作5日均线和10日均线,那么就需要先设置窗口再进行运算。我们先用如下所示的代码读取2022年百度的股票数据,数据文件可以通过下面的链接来获取。
baidu_df = pd.read_excel('data/2022年股票数据.xlsx', sheet_name='BIDU')
baidu_df.sort_index(inplace=True)
baidu_df
输出:
上面的DataFrame
有Open
、High
、Low
、Close
、Volume
五个列,分别代表股票的开盘价、最高价、最低价、收盘价和成交量,接下来我们对百度的股票数据进行窗口计算。
baidu_df.rolling(5).mean()
输出:
我们也可以在Series
上使用rolling
设置窗口并在窗口内完成运算,例如我们可以对上面的百度股票收盘价(Close
列)计算5日均线和10日均线,并使用merge
函数将其组装到一个DataFrame
对象中并绘制出双均线图,代码如下所示。
close_ma5 = baidu_df.Close.rolling(5).mean()
close_ma10 = baidu_df.Close.rolling(10).mean()
result_df = pd.merge(close_ma5, close_ma10, left_index=True, right_index=True)
result_df.rename(columns={'Close_x': 'MA5', 'Close_y': 'MA10'}, inplace=True)
result_df.plot(kind='line', figsize=(10, 6))
plt.show()
输出:
相关性判定
在统计学中,我们通常使用协方差(covariance)来衡量两个随机变量的联合变化程度。如果变量 X \small{X} X 的较大值主要与另一个变量 Y \small{Y} Y 的较大值相对应,而两者较小值也相对应,那么两个变量倾向于表现出相似的行为,协方差为正。如果一个变量的较大值主要对应于另一个变量的较小值,则两个变量倾向于表现出相反的行为,协方差为负。简单的说,协方差的正负号显示着两个变量的相关性。方差是协方差的一种特殊情况,即变量与自身的协方差。
c o v ( X , Y ) = E ( ( X − μ ) ( Y − υ ) ) = E ( X ⋅ Y ) − μ υ cov(X,Y) = E((X - \mu)(Y - \upsilon)) = E(X \cdot Y) - \mu\upsilon co