Python 金融编程第二版(GPT 重译)(二)(5)

简介: Python 金融编程第二版(GPT 重译)(二)

Python 金融编程第二版(GPT 重译)(二)(4)https://developer.aliyun.com/article/1559310


合并

虽然连接操作是基于要连接的 DataFrame 对象的索引进行的,但合并操作通常是在两个数据集之间共享的列上进行的。为此,将新列 C 添加到原始的两个 DataFrame 对象中:

In [105]: c = pd.Series([250, 150, 50], index=['b', 'd', 'c'])
          df1['C'] = c
          df2['C'] = c
In [106]: df1
Out[106]:      A      C
          a  100    NaN
          b  200  250.0
          c  300   50.0
          d  400  150.0
In [107]: df2
Out[107]:      B      C
          f  200    NaN
          b  150  250.0
          d   50  150.0

默认情况下,此情况下的合并操作基于单个共享列 C 进行。然而,还有其他选项可用。

In [108]: pd.merge(df1, df2)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[108]:      A      C    B
          0  100    NaN  200
          1  200  250.0  150
          2  400  150.0   50
In [109]: pd.merge(df1, df2, on='C')  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[109]:      A      C    B
          0  100    NaN  200
          1  200  250.0  150
          2  400  150.0   50
In [110]: pd.merge(df1, df2, how='outer')  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[110]:      A      C    B
          0  100    NaN  200
          1  200  250.0  150
          2  300   50.0  NaN
          3  400  150.0   50


默认在列 C 上合并。


外部合并也是可能的,保留所有数据行。

还有许多其他类型的合并操作可用,以下代码示例了其中的一些:

In [111]: pd.merge(df1, df2, left_on='A', right_on='B')
Out[111]:      A    C_x    B  C_y
          0  200  250.0  200  NaN
In [112]: pd.merge(df1, df2, left_on='A', right_on='B', how='outer')
Out[112]:      A    C_x    B    C_y
          0  100    NaN  NaN    NaN
          1  200  250.0  200    NaN
          2  300   50.0  NaN    NaN
          3  400  150.0  NaN    NaN
          4  NaN    NaN  150  250.0
          5  NaN    NaN   50  150.0
In [113]: pd.merge(df1, df2, left_index=True, right_index=True)
Out[113]:      A    C_x    B    C_y
          b  200  250.0  150  250.0
          d  400  150.0   50  150.0
In [114]: pd.merge(df1, df2, on='C', left_index=True)
Out[114]:      A      C    B
          f  100    NaN  200
          b  200  250.0  150
          d  400  150.0   50
In [115]: pd.merge(df1, df2, on='C', right_index=True)
Out[115]:      A      C    B
          a  100    NaN  200
          b  200  250.0  150
          d  400  150.0   50
In [116]: pd.merge(df1, df2, on='C', left_index=True, right_index=True)
Out[116]:      A      C    B
          b  200  250.0  150
          d  400  150.0   50

性能方面

本章中的许多示例说明了使用 pandas 可以实现相同目标的多个选项。本节比较了用于逐元素添加两列的此类选项。首先,使用 NumPy 生成的数据集。

In [117]: data = np.random.standard_normal((1000000, 2))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [118]: data.nbytes  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[118]: 16000000
In [119]: 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 [120]: 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: 1000000 entries, 0 to 999999
          Data columns (total 2 columns):
          x    1000000 non-null float64
          y    1000000 non-null float64
          dtypes: float64(2)
          memory usage: 15.3 MB


带有随机数字的 ndarray 对象。


带有随机数字的 DataFrame 对象。

第二,一些完成任务的性能值的选项。

In [121]: %time res = df['x'] + df['y']  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          CPU times: user 5.68 ms, sys: 14.5 ms, total: 20.1 ms
          Wall time: 4.06 ms
In [122]: res[:3]
Out[122]: 0    0.387242
          1   -0.969343
          2   -0.863159
          dtype: float64
In [123]: %time res = df.sum(axis=1)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
          CPU times: user 44 ms, sys: 14.9 ms, total: 58.9 ms
          Wall time: 57.6 ms
In [124]: res[:3]
Out[124]: 0    0.387242
          1   -0.969343
          2   -0.863159
          dtype: float64
In [125]: %time res = df.values.sum(axis=1)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
          CPU times: user 16.1 ms, sys: 1.74 ms, total: 17.8 ms
          Wall time: 16.6 ms
In [126]: res[:3]
Out[126]: array([ 0.3872424 , -0.96934273, -0.86315944])
In [127]: %time res = np.sum(df, axis=1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
          CPU times: user 39.7 ms, sys: 8.91 ms, total: 48.7 ms
          Wall time: 47.7 ms
In [128]: res[:3]
Out[128]: 0    0.387242
          1   -0.969343
          2   -0.863159
          dtype: float64
In [129]: %time res = np.sum(df.values, axis=1)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
          CPU times: user 16.1 ms, sys: 1.78 ms, total: 17.9 ms
          Wall time: 16.6 ms
In [130]: res[:3]
Out[130]: array([ 0.3872424 , -0.96934273, -0.86315944])


直接操作列(Series对象)是最快的方法。


这通过在 DataFrame 对象上调用 sum() 方法来计算总和。


这通过在 ndarray 对象上调用 sum() 方法来计算总和。


这通过在 DataFrame 对象上调用 np.sum() 方法来计算总和。


这通过在 ndarray 对象上使用通用函数 np.sum() 方法来计算总和。

最后,更多基于 eval()apply() 方法的选项。

In [131]: %time res = df.eval('x + y')  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          CPU times: user 13.3 ms, sys: 15.6 ms, total: 28.9 ms
          Wall time: 18.5 ms
In [132]: res[:3]
Out[132]: 0    0.387242
          1   -0.969343
          2   -0.863159
          dtype: float64
In [133]: %time res = df.apply(lambda row: row['x'] + row['y'], axis=1)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
          CPU times: user 22 s, sys: 71 ms, total: 22.1 s
          Wall time: 22.1 s
In [134]: res[:3]
Out[134]: 0    0.387242
          1   -0.969343
          2   -0.863159
          dtype: float64
# tag::PD_34[]


eval() 是专门用于评估(复杂)数值表达式的方法;可以直接访问列。


最慢的选项是逐行使用 apply() 方法;这就像在 Python 级别上循环遍历所有行。

注意

pandas 通常提供多种选项来实现相同的目标。如果不确定,应该比较一些选项,以确保在时间紧迫时获得最佳性能。在简单示例中,执行时间相差数个数量级。

结论

pandas 是数据分析的强大工具,并已成为所谓 PyData 栈的核心包。它的 DataFrame 类特别适用于处理任何类型的表格数据。对这种对象的大多数操作都是矢量化的,这不仅使代码简洁,而且通常性能很高,与 NumPy 的情况一样。此外,pandas 还使得处理不完整的数据集变得方便,例如,使用 NumPy 并不那么方便。在本书的许多后续章节中,pandasDataFrame 类将是核心,当需要时还将使用和说明其他功能。

进一步阅读

pandas 是一个文档齐全的开源项目,既有在线文档,也有可供下载的 PDF 版本。¹。以下页面提供了所有资源:

至于 NumPy,在书籍形式上推荐的参考资料是:

  • McKinney, Wes (2017): Python 数据分析. 第二版, O’Reilly, 北京等地。
  • VanderPlas, Jake (2016): Python 数据科学手册. O’Reilly, 北京等地。

¹ 在撰写本文时,PDF 版本共有 2,207 页(版本 0.21.1)。

2 -0.863159

dtype: float64

In [125]: %time res = df.values.sum(axis=1)

CPU times: user 16.1 ms, sys: 1.74 ms, total: 17.8 ms
      Wall time: 16.6 ms

In [126]: res[:3]

Out[126]: array([ 0.3872424 , -0.96934273, -0.86315944])

In [127]: %time res = np.sum(df, axis=1)

CPU times: user 39.7 ms, sys: 8.91 ms, total: 48.7 ms
      Wall time: 47.7 ms

In [128]: res[:3]

Out[128]: 0 0.387242

1 -0.969343

2 -0.863159

dtype: float64

In [129]: %time res = np.sum(df.values, axis=1)

CPU times: user 16.1 ms, sys: 1.78 ms, total: 17.9 ms
      Wall time: 16.6 ms

In [130]: res[:3]

Out[130]: array([ 0.3872424 , -0.96934273, -0.86315944])

[外链图片转存中...(img-rjeMDAFN-1717935513102)]
直接操作列(`Series`对象)是最快的方法。
[外链图片转存中...(img-TeYber2X-1717935513102)]
这通过在 `DataFrame` 对象上调用 `sum()` 方法来计算总和。
[外链图片转存中...(img-r8epalL2-1717935513102)]
这通过在 `ndarray` 对象上调用 `sum()` 方法来计算总和。
[外链图片转存中...(img-tN3j1PId-1717935513102)]
这通过在 `DataFrame` 对象上调用 `np.sum()` 方法来计算总和。
[外链图片转存中...(img-DuFuJDwd-1717935513102)]
这通过在 `ndarray` 对象上使用通用函数 `np.sum()` 方法来计算总和。
最后,更多基于 `eval()` 和 `apply()` 方法的选项。
```py
In [131]: %time res = df.eval('x + y')  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          CPU times: user 13.3 ms, sys: 15.6 ms, total: 28.9 ms
          Wall time: 18.5 ms
In [132]: res[:3]
Out[132]: 0    0.387242
          1   -0.969343
          2   -0.863159
          dtype: float64
In [133]: %time res = df.apply(lambda row: row['x'] + row['y'], axis=1)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
          CPU times: user 22 s, sys: 71 ms, total: 22.1 s
          Wall time: 22.1 s
In [134]: res[:3]
Out[134]: 0    0.387242
          1   -0.969343
          2   -0.863159
          dtype: float64
# tag::PD_34[]

[外链图片转存中…(img-c1dcFfnu-1717935513102)]

eval() 是专门用于评估(复杂)数值表达式的方法;可以直接访问列。

[外链图片转存中…(img-3htITLCT-1717935513103)]

最慢的选项是逐行使用 apply() 方法;这就像在 Python 级别上循环遍历所有行。

注意

pandas 通常提供多种选项来实现相同的目标。如果不确定,应该比较一些选项,以确保在时间紧迫时获得最佳性能。在简单示例中,执行时间相差数个数量级。

结论

pandas 是数据分析的强大工具,并已成为所谓 PyData 栈的核心包。它的 DataFrame 类特别适用于处理任何类型的表格数据。对这种对象的大多数操作都是矢量化的,这不仅使代码简洁,而且通常性能很高,与 NumPy 的情况一样。此外,pandas 还使得处理不完整的数据集变得方便,例如,使用 NumPy 并不那么方便。在本书的许多后续章节中,pandasDataFrame 类将是核心,当需要时还将使用和说明其他功能。

进一步阅读

pandas 是一个文档齐全的开源项目,既有在线文档,也有可供下载的 PDF 版本。¹。以下页面提供了所有资源:

至于 NumPy,在书籍形式上推荐的参考资料是:

  • McKinney, Wes (2017): Python 数据分析. 第二版, O’Reilly, 北京等地。
  • VanderPlas, Jake (2016): Python 数据科学手册. O’Reilly, 北京等地。

¹ 在撰写本文时,PDF 版本共有 2,207 页(版本 0.21.1)。

相关文章
|
9月前
|
数据采集 机器学习/深度学习 人工智能
Python:现代编程的首选语言
Python:现代编程的首选语言
1494 102
|
9月前
|
数据采集 机器学习/深度学习 算法框架/工具
Python:现代编程的瑞士军刀
Python:现代编程的瑞士军刀
486 104
|
9月前
|
人工智能 自然语言处理 算法框架/工具
Python:现代编程的首选语言
Python:现代编程的首选语言
376 103
|
9月前
|
机器学习/深度学习 人工智能 数据挖掘
Python:现代编程的首选语言
Python:现代编程的首选语言
401 82
|
8月前
|
Python
Python编程:运算符详解
本文全面详解Python各类运算符,涵盖算术、比较、逻辑、赋值、位、身份、成员运算符及优先级规则,结合实例代码与运行结果,助你深入掌握Python运算符的使用方法与应用场景。
503 3
|
8月前
|
数据处理 Python
Python编程:类型转换与输入输出
本教程介绍Python中输入输出与类型转换的基础知识,涵盖input()和print()的使用,int()、float()等类型转换方法,并通过综合示例演示数据处理、错误处理及格式化输出,助你掌握核心编程技能。
729 3
|
8月前
|
并行计算 安全 计算机视觉
Python多进程编程:用multiprocessing突破GIL限制
Python中GIL限制多线程性能,尤其在CPU密集型任务中。`multiprocessing`模块通过创建独立进程,绕过GIL,实现真正的并行计算。它支持进程池、队列、管道、共享内存和同步机制,适用于科学计算、图像处理等场景。相比多线程,多进程更适合利用多核优势,虽有较高内存开销,但能显著提升性能。合理使用进程池与通信机制,可最大化效率。
539 3
|
8月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
745 0
|
9月前
|
数据采集 机器学习/深度学习 人工智能
Python:现代编程的多面手
Python:现代编程的多面手
429 0
|
9月前
|
存储 人工智能 算法
Python实现简易成语接龙小游戏:从零开始的趣味编程实践
本项目将中国传统文化与编程思维相结合,通过Python实现成语接龙游戏,涵盖数据结构、算法设计与简单AI逻辑,帮助学习者在趣味实践中掌握编程技能。
709 0

推荐镜像

更多