Python 金融编程第二版(二)(3)https://developer.aliyun.com/article/1559404
基本可视化
通常情况下,一旦数据存储在DataFrame
对象中,数据的绘制就只需一行代码即可(参见图 5-1):
In [52]: from pylab import plt, mpl ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) plt.style.use('seaborn') ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) mpl.rcParams['font.family'] = 'serif' ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) %matplotlib inline In [53]: df.cumsum().plot(lw=2.0, figsize=(10, 6)); ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) # plt.savefig('../../images/ch05/pd_plot_01.png')
自定义绘图样式。
将四列的累积和绘制成折线图。
图 5-1。DataFrame
对象的折线图
基本上,pandas
提供了一个围绕 matplotplib
(参见第七章)的包装器,专门设计用于 DataFrame
对象。表 5-4 列出了 plot
方法接受的参数。
表 5-4。plot 方法的参数
参数 | 格式 | 描述 |
x |
标签/位置,默认为 None |
仅当列值为 x 刻度时使用 |
y |
标签/位置,默认为 None |
仅当列值为 y 刻度时使用 |
subplots |
布尔值,默认为 False |
在子图中绘制列 |
sharex |
布尔值,默认为 True |
x 轴共享 |
sharey |
布尔值,默认为 False |
y 轴共享 |
use_index |
布尔值,默认为 True |
使用 DataFrame.index 作为 x 刻度 |
stacked |
布尔值,默认为 False |
堆叠(仅用于柱状图) |
sort_columns |
布尔值,默认为 False |
绘图前按字母顺序排序列 |
title |
字符串,默认为 None |
绘图标题 |
grid |
布尔值,默认为 False |
水平和垂直网格线 |
legend |
布尔值,默认为 True |
标签的图例 |
ax |
matplotlib axis 对象 |
用于绘图的 matplotlib axis 对象 |
style |
字符串或列表/字典 | 线绘图风格(对每列) |
kind |
“line ”/“bar ”/“barh ”/“kde ”/“density ” |
绘图类型 |
logx |
布尔值,默认为 False |
x 轴的对数缩放 |
logy |
布尔值,默认为 False |
y 轴的对数缩放 |
xticks |
序列,默认为 Index |
绘图的 x 刻度 |
yticks |
序列,默认为 Values |
绘图的 y 刻度 |
xlim |
2-元组,列表 | x 轴的边界 |
ylim |
2-元组,列表 | y 轴的边界 |
rot |
整数,默认为 None |
x 刻度的旋转 |
secondary_y |
布尔值/序列,默认为 False |
次要 y 轴 |
mark_right |
布尔值,默认为 True |
次要轴的自动标记 |
colormap |
字符串/colormap 对象,默认为 None |
用于绘图的色图 |
kwds |
关键字 | 传递给 matplotlib 的选项 |
作为另一个示例,考虑绘制相同数据的柱状图(参见图 5-1)。
In [54]: df.plot(kind='bar', figsize=(10, 6)); ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) # plt.savefig('../../images/ch05/pd_plot_02.png')
使用 kind
参数来改变绘图类型。
图 5-2。DataFrame 对象的柱状图
Series 类
到目前为止,我们主要使用 pandas
的 DataFrame
类。Series
类是另一个与 pandas
一起提供的重要类。它的特点是只有一列数据。从这个意义上说,它是 DataFrame
类的一个特化,共享许多但不是所有的特征和功能。通常,当从多列 DataFrame
对象中选择单列时,会得到一个 Series
对象:
In [55]: type(df) Out[55]: pandas.core.frame.DataFrame In [56]: s = df['No1'] In [57]: s Out[57]: 2019-01-31 -1.749765 2019-02-28 0.981321 2019-03-31 -0.189496 2019-04-30 -0.583595 2019-05-31 -0.531280 2019-06-30 1.618982 2019-07-31 0.184519 2019-08-31 -0.326238 2019-09-30 -0.756352 Freq: M, Name: No1, dtype: float64 In [58]: type(s) Out[58]: pandas.core.series.Series
主要的DataFrame
方法也适用于Series
对象。举例来说,考虑mean()
和plot()
方法(见图 5-3):
In [59]: s.mean() Out[59]: -0.15021177307319458 In [60]: s.plot(lw=2.0, figsize=(10, 6)); # plt.savefig('../../images/ch05/pd_plot_03.png')
图 5-3。一个 Series 对象的线性图
分组操作
pandas
具有强大且灵活的分组功能。它们与SQL
中的分组以及 MicrosoftExcel
中的数据透视表类似。为了有东西可以分组,我们添加了一列,指示相应数据所属的季度:
In [61]: df['Quarter'] = ['Q1', 'Q1', 'Q1', 'Q2', 'Q2', 'Q2', 'Q3', 'Q3', 'Q3'] df Out[61]: No1 No2 No3 No4 Quarter 2019-01-31 -1.749765 0.342680 1.153036 -0.252436 Q1 2019-02-28 0.981321 0.514219 0.221180 -1.070043 Q1 2019-03-31 -0.189496 0.255001 -0.458027 0.435163 Q1 2019-04-30 -0.583595 0.816847 0.672721 -0.104411 Q2 2019-05-31 -0.531280 1.029733 -0.438136 -1.118318 Q2 2019-06-30 1.618982 1.541605 -0.251879 -0.842436 Q2 2019-07-31 0.184519 0.937082 0.731000 1.361556 Q3 2019-08-31 -0.326238 0.055676 0.222400 -1.443217 Q3 2019-09-30 -0.756352 0.816454 0.750445 -0.455947 Q3
现在,我们可以按Quarter
列进行分组,并且可以输出单个组的统计信息:
In [62]: groups = df.groupby('Quarter') ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) In [63]: groups.size() ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) Out[63]: Quarter Q1 3 Q2 3 Q3 3 dtype: int64 In [64]: groups.mean() ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png) Out[64]: No1 No2 No3 No4 Quarter Q1 -0.319314 0.370634 0.305396 -0.295772 Q2 0.168035 1.129395 -0.005765 -0.688388 Q3 -0.299357 0.603071 0.567948 -0.179203 In [65]: groups.max() ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png) Out[65]: No1 No2 No3 No4 Quarter Q1 0.981321 0.514219 1.153036 0.435163 Q2 1.618982 1.541605 0.672721 -0.104411 Q3 0.184519 0.937082 0.750445 1.361556 In [66]: groups.aggregate([min, max]).round(2) ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png) Out[66]: No1 No2 No3 No4 min max min max min max min max Quarter Q1 -1.75 0.98 0.26 0.51 -0.46 1.15 -1.07 0.44 Q2 -0.58 1.62 0.82 1.54 -0.44 0.67 -1.12 -0.10 Q3 -0.76 0.18 0.06 0.94 0.22 0.75 -1.44 1.36
根据Quarter
列进行分组。
给出组中的行数。
给出每列的均值。
给出每列的最大值。
给出每列的最小值和最大值。
也可以通过多个列进行分组。为此,引入另一列,指示索引日期的月份是奇数还是偶数:
In [67]: df['Odd_Even'] = ['Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd'] In [68]: groups = df.groupby(['Quarter', 'Odd_Even']) In [69]: groups.size() Out[69]: Quarter Odd_Even Q1 Even 1 Odd 2 Q2 Even 2 Odd 1 Q3 Even 1 Odd 2 dtype: int64 In [70]: groups[['No1', 'No4']].aggregate([sum, np.mean]) Out[70]: No1 No4 sum mean sum mean Quarter Odd_Even Q1 Even 0.981321 0.981321 -1.070043 -1.070043 Odd -1.939261 -0.969631 0.182727 0.091364 Q2 Even 1.035387 0.517693 -0.946847 -0.473423 Odd -0.531280 -0.531280 -1.118318 -1.118318 Q3 Even -0.326238 -0.326238 -1.443217 -1.443217 Odd -0.571834 -0.285917 0.905609 0.452805
这就是对pandas
和DataFrame
对象的介绍。后续部分将使用这个工具集来处理真实世界的金融数据。
复杂选择
数据选择通常通过在列值上制定条件来完成,并可能逻辑地组合多个这样的条件。考虑以下数据集。
In [71]: data = np.random.standard_normal((10, 2)) ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) In [72]: df = pd.DataFrame(data, columns=['x', 'y']) ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) In [73]: df.info() ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) <class 'pandas.core.frame.DataFrame'> RangeIndex: 10 entries, 0 to 9 Data columns (total 2 columns): x 10 non-null float64 y 10 non-null float64 dtypes: float64(2) memory usage: 240.0 bytes In [74]: df.head() ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png) Out[74]: x y 0 1.189622 -1.690617 1 -1.356399 -1.232435 2 -0.544439 -0.668172 3 0.007315 -0.612939 4 1.299748 -1.733096 In [75]: df.tail() ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png) Out[75]: x y 5 -0.983310 0.357508 6 -1.613579 1.470714 7 -1.188018 -0.549746 8 -0.940046 -0.827932 9 0.108863 0.507810
具有标准正态分布随机数的ndarray
对象。
具有相同随机数的DataFrame
对象。
通过head()
方法获得前五行。
通过tail()
方法获得最后五行。
下面的代码说明了 Python 的比较运算符和逻辑运算符在两列值上的应用。
In [76]: df['x'] > 0.5 ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) Out[76]: 0 True 1 False 2 False 3 False 4 True 5 False 6 False 7 False 8 False 9 False Name: x, dtype: bool In [77]: (df['x'] > 0) & (df['y'] < 0) ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) Out[77]: 0 True 1 False 2 False 3 True 4 True 5 False 6 False 7 False 8 False 9 False dtype: bool In [78]: (df['x'] > 0) | (df['y'] < 0) ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png) Out[78]: 0 True 1 True 2 True 3 True 4 True 5 False 6 False 7 True 8 True 9 True dtype: bool
检查x
列中的值是否大于 0.5。
检查x
列中的值是否为正且y
列中的值是否为负。
检查x
列中的值是否为正或y
列中的值是否为负。
使用结果布尔Series
对象,复杂数据(行)的选择很简单。
In [79]: df[df['x'] > 0] ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) Out[79]: x y 0 1.189622 -1.690617 3 0.007315 -0.612939 4 1.299748 -1.733096 9 0.108863 0.507810 In [80]: df[(df['x'] > 0) & (df['y'] < 0)] ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) Out[80]: x y 0 1.189622 -1.690617 3 0.007315 -0.612939 4 1.299748 -1.733096 In [81]: df[(df.x > 0) | (df.y < 0)] ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png) Out[81]: x y 0 1.189622 -1.690617 1 -1.356399 -1.232435 2 -0.544439 -0.668172 3 0.007315 -0.612939 4 1.299748 -1.733096 7 -1.188018 -0.549746 8 -0.940046 -0.827932 9 0.108863 0.507810
所有x
列的值大于 0.5 的行。
所有x
列的值为正且y
列的值为负的行。
所有列中 x
的值为正或列中 y
的值为负的所有行(这里通过各自的属性访问列)。
比较运算符也可以一次应用于完整的 DataFrame
对象。
In [82]: df > 0 ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) Out[82]: x y 0 True False 1 False False 2 False False 3 True False 4 True False 5 False True 6 False True 7 False False 8 False False 9 True True In [83]: df[df > 0] ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) Out[83]: x y 0 1.189622 NaN 1 NaN NaN 2 NaN NaN 3 0.007315 NaN 4 1.299748 NaN 5 NaN 0.357508 6 NaN 1.470714 7 NaN NaN 8 NaN NaN 9 0.108863 0.507810
DataFrame
对象中哪些值是正数?
选择所有这样的值,并在所有其他位置放置 NaN
。
Python 金融编程第二版(二)(5)https://developer.aliyun.com/article/1559407