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

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

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


零基编号

与其他一些编程语言(如Matlab)相比,Python使用零基编号方案。例如,tuple对象的第一个元素的索引值为 0。

这种对象类型提供的特殊方法仅有两个:countindex。第一个方法统计某个对象的出现次数,第二个方法给出其第一次出现的索引值:

In [100]: t.count('data')
Out[100]: 1
In [101]: t.index(1)
Out[101]: 0

tuple对象是不可变对象。这意味着一旦定义,它们就不容易更改。

列表

类型为list的对象比tuple对象更加灵活和强大。从财务角度来看,你可以仅使用list对象就能实现很多,比如存储股价报价和添加新数据。list对象通过括号定义,其基本功能和行为与tuple对象相似:

In [102]: l = [1, 2.5, 'data']
          l[2]
Out[102]: 'data'

也可以通过使用函数list来定义或转换list对象。以下代码通过转换前面示例中的tuple对象生成一个新的list对象:

In [103]: l = list(t)
          l
Out[103]: [1, 2.5, 'data']
In [104]: type(l)
Out[104]: list

除了tuple对象的特性外,list对象还可以通过不同的方法进行扩展和缩减。换句话说,虽然stringtuple对象是不可变序列对象(具有索引),一旦创建就无法更改,但list对象是可变的,并且可以通过不同的操作进行更改。你可以将list对象附加到现有的list对象上,等等:

In [105]: l.append([4, 3])  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          l
Out[105]: [1, 2.5, 'data', [4, 3]]
In [106]: l.extend([1.0, 1.5, 2.0])  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
          l
Out[106]: [1, 2.5, 'data', [4, 3], 1.0, 1.5, 2.0]
In [107]: l.insert(1, 'insert')  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
          l
Out[107]: [1, 'insert', 2.5, 'data', [4, 3], 1.0, 1.5, 2.0]
In [108]: l.remove('data')  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
          l
Out[108]: [1, 'insert', 2.5, [4, 3], 1.0, 1.5, 2.0]
In [109]: p = l.pop(3)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
          print(l, p)
          [1, 'insert', 2.5, 1.0, 1.5, 2.0] [4, 3]


在末尾附加list对象。


添加list对象的元素。


在索引位置之前插入对象。


删除对象的第一次出现。


删除并返回索引位置的对象。

切片也很容易实现。在这里,切片指的是将数据集分解为较小部分(感兴趣的部分)的操作:

In [110]: l[2:5]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[110]: [2.5, 1.0, 1.5]


第三到第五个元素。

Table 3-2 提供了list对象的选定操作和方法的摘要。

表 3-2. list对象的选定操作和方法

方法 参数 返回/结果
l[i] = x [i] 将第i个元素替换为x
l[i:j:k] = s [i:j:k] s替换从ij-1的每个第k个元素
append (x) x附加到对象
count (x) 对象x的出现次数
del l[i:j:k] [i:j:k] 删除索引值为ij-1的元素
extend (s) s的所有元素附加到对象
index (x[, i[, j]]) 元素ij-1之间x的第一个索引
insert (i, x) 在索引i之前/后插入x
remove (i) 删除索引为i的元素
pop (i) 删除索引为i的元素并返回它
reverse () 将所有项目原地颠倒
sort ([cmp[, key[, reverse]]]) 原地对所有项目排序

专题:控制结构

虽然控制结构本身是一个专题,像for循环这样的控制结构可能最好是基于Python中的list对象介绍的。这是因为一般情况下循环是在list对象上进行的,这与其他语言中通常的标准相当不同。看下面的例子。for循环遍历list对象l的元素,索引值为 2 到 4,并打印出相应元素的平方。注意第二行缩进(空格)的重要性:

In [111]: for element in l[2:5]:
              print(element ** 2)
          6.25
          1.0
          2.25

这相比于典型的基于计数器的循环提供了非常高的灵活性。基于(标准的)list对象range也可以使用计数器进行循环:

In [112]: r = range(0, 8, 1)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          r
Out[112]: range(0, 8)
In [113]: type(r)
Out[113]: range


参数是startendstep size

为了比较,相同的循环使用range实现如下:

In [114]: for i in range(2, 5):
              print(l[i] ** 2)
          6.25
          1.0
          2.25

遍历列表

Python中,你可以遍历任意的list对象,不管对象的内容是什么。这通常避免了引入计数器。

Python还提供了典型的(条件)控制元素ifelifelse。它们在其他语言中的使用方式类似:

In [115]: for i in range(1, 10):
              if i % 2 == 0:  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
                  print("%d is even" % i)
              elif i % 3 == 0:
                  print("%d is multiple of 3" % i)
              else:
                  print("%d is odd" % i)
          1 is odd
          2 is even
          3 is multiple of 3
          4 is even
          5 is odd
          6 is even
          7 is odd
          8 is even
          9 is multiple of 3


%代表取模。

同样,while提供了另一种控制流的手段:

In [116]: total = 0
          while total < 100:
              total += 1
          print(total)
          100

Python的一个特点是所谓的list 推导式。与遍历现有list对象不同,这种方法以一种相当紧凑的方式通过循环生成list对象:

In [117]: m = [i ** 2 for i in range(5)]
          m
Out[117]: [0, 1, 4, 9, 16]

从某种意义上说,这已经提供了一种生成“类似”的向量化代码的第一手段,因为循环相对来说更加隐式而不是显式的(代码的向量化将在本章后面更详细地讨论)。

专题:功能编程

Python还提供了一些功能编程支持工具,即将函数应用于整套输入(在我们的情况下是list对象)。其中包括filtermapreduce。然而,我们首先需要一个函数定义。首先从一个非常简单的函数开始,考虑一个返回输入x的平方的函数f

In [118]: def f(x):
              return x ** 2
          f(2)
Out[118]: 4

当然,函数可以是任意复杂的,具有多个输入/参数对象,甚至多个输出(返回对象)。但是,考虑以下函数:

In [119]: def even(x):
              return x % 2 == 0
          even(3)
Out[119]: False

返回对象是一个布尔值。这样的函数可以通过使用 map 应用于整个 list 对象:

In [120]: list(map(even, range(10)))
Out[120]: [True, False, True, False, True, False, True, False, True, False]

为此,我们还可以直接将函数定义作为 map 的参数提供,通过使用 lambda匿名函数:

In [121]: list(map(lambda x: x ** 2, range(10)))
Out[121]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

函数也可以用于过滤 list 对象。在下面的示例中,过滤器返回符合由 even 函数定义的布尔条件的 list 对象元素:

In [122]: list(filter(even, range(15)))
Out[122]: [0, 2, 4, 6, 8, 10, 12, 14]

列表推导、函数式编程、匿名函数

Python 级别尽可能避免使用循环被认为是良好的实践list 推导和函数式编程工具如 mapfilterreduce 提供了编写没有(显式)循环的代码的方法,这种代码既紧凑又通常更可读。在这种情况下,lambda 或匿名函数也是强大的工具。

字典

dict 对象是字典,也是可变序列,允许通过可以是 string 对象的键来检索数据。它们被称为键值存储。虽然 list 对象是有序且可排序的,但 dict 对象是无序且不可排序的。通过示例可以更好地说明与 list 对象的进一步差异。花括号是定义 dict 对象的标志:

In [123]: d = {
               'Name' : 'Angela Merkel',
               'Country' : 'Germany',
               'Profession' : 'Chancelor',
               'Age' : 63
               }
          type(d)
Out[123]: dict
In [124]: print(d['Name'], d['Age'])
          Angela Merkel 63

同样,这类对象具有许多内置方法:

In [125]: d.keys()
Out[125]: dict_keys(['Name', 'Country', 'Profession', 'Age'])
In [126]: d.values()
Out[126]: dict_values(['Angela Merkel', 'Germany', 'Chancelor', 63])
In [127]: d.items()
Out[127]: dict_items([('Name', 'Angela Merkel'), ('Country', 'Germany'), ('Profession', 'Chancelor'), ('Age', 63)])
In [128]: birthday = True
          if birthday is True:
              d['Age'] += 1
          print(d['Age'])
          64

有几种方法可以从 dict 对象获取 iterator 对象。当进行迭代时,这些对象的行为类似于 list 对象:

In [129]: for item in d.items():
              print(item)
          ('Name', 'Angela Merkel')
          ('Country', 'Germany')
          ('Profession', 'Chancelor')
          ('Age', 64)
In [130]: for value in d.values():
              print(type(value))
          <class 'str'>
          <class 'str'>
          <class 'str'>
          <class 'int'>

表 3-3 提供了 dict 对象的选定操作和方法的摘要。

表 3-3. dict 对象的选定操作和方法

方法 参数 返回/结果
d[k] [k] d 中具有键 k 的项目
d[k] = x [k] 将项目键 k 设置为 x
del d[k] [k] 删除具有键 k 的项目
clear () 删除所有项目
copy () 复制一个副本
has_key (k) 如果 k 是键,则为 True
items () 迭代器遍历所有项目
keys () 迭代器遍历所有键
values () 迭代器遍历所有值
popitem (k) 返回并删除具有键 k 的项目
update ([e]) e 中的项目更新项目

集合

我们将考虑的最后一个数据结构是 set 对象。尽管集合论是数学和金融理论的基石,但对于 set 对象的实际应用并不太多。这些对象是其他对象的无序集合,每个元素只包含一次:

In [131]: s = set(['u', 'd', 'ud', 'du', 'd', 'du'])
          s
Out[131]: {'d', 'du', 'u', 'ud'}
In [132]: t = set(['d', 'dd', 'uu', 'u'])

使用 set 对象,您可以像在数学集合论中一样实现操作。例如,您可以生成并集、交集和差异:

In [133]: s.union(t)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[133]: {'d', 'dd', 'du', 'u', 'ud', 'uu'}
In [134]: s.intersection(t)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[134]: {'d', 'u'}
In [135]: s.difference(t)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[135]: {'du', 'ud'}
In [136]: t.difference(s)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
Out[136]: {'dd', 'uu'}
In [137]: s.symmetric_difference(t)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
Out[137]: {'dd', 'du', 'ud', 'uu'}


st 的全部。


st 中都有。


s 中但不在 t 中。


t 中但不在 s 中。


在其中一个但不是两者都。

set对象的一个应用是从list对象中消除重复项。例如:

In [138]: from random import randint
          l = [randint(0, 10) for i in range(1000)]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          len(l)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[138]: 1000
In [139]: l[:20]
Out[139]: [10, 9, 2, 4, 5, 1, 7, 4, 6, 10, 9, 5, 4, 6, 10, 3, 4, 7, 0, 5]
In [140]: s = set(l)
          s
Out[140]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}


1,000 个 0 到 10 之间的随机整数。


l 中的元素数量。

结论

基本的Python解释器已经提供了丰富灵活的数据结构。从金融的角度来看,以下可以被认为是最重要的:

基本数据类型

在金融中,intfloatstring类提供了原子数据类型。

标准数据结构

tuplelistdictset类在金融领域有许多应用领域,其中list通常是最灵活的通用工作马。

进一步资源

本章重点讨论可能对金融算法和应用特别重要的问题。但是,它只能代表探索Python中数据结构和数据建模的起点。有许多宝贵的资源可供进一步深入了解。

书籍形式的良好参考资料包括:

  • Goodrich, Michael 等(2013):Python 数据结构与算法. John Wiley & Sons, Hoboken, NJ.
  • Harrison, Matt (2017): Python 3 图解指南. Treading on Python Series.
  • Ramalho, Luciano (2016): 流畅的 Python. O’Reilly, Beijing et al.

¹ Cython将静态类型和编译功能引入Python,与C中的相似。实际上,CythonPythonC的混合语言。

² 在这里和后续讨论中,诸如floatfloat 对象等术语可互换使用,承认每个float也是一个对象。对于其他对象类型也是如此。

³ 参考http://en.wikipedia.org/wiki/Double-precision_floating-point_format

⁴ 在这里不可能详细介绍,但互联网上有大量关于正则表达式的信息,特别是针对Python。关于这个主题的介绍,请参阅 Fitzgerald, Michael (2012): 正则表达式入门. O’Reilly, Sebastopol, CA.

石,但对于 set 对象的实际应用并不太多。这些对象是其他对象的无序集合,每个元素只包含一次:

In [131]: s = set(['u', 'd', 'ud', 'du', 'd', 'du'])
          s
Out[131]: {'d', 'du', 'u', 'ud'}
In [132]: t = set(['d', 'dd', 'uu', 'u'])

使用 set 对象,您可以像在数学集合论中一样实现操作。例如,您可以生成并集、交集和差异:

In [133]: s.union(t)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[133]: {'d', 'dd', 'du', 'u', 'ud', 'uu'}
In [134]: s.intersection(t)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[134]: {'d', 'u'}
In [135]: s.difference(t)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[135]: {'du', 'ud'}
In [136]: t.difference(s)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
Out[136]: {'dd', 'uu'}
In [137]: s.symmetric_difference(t)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
Out[137]: {'dd', 'du', 'ud', 'uu'}

[外链图片转存中…(img-jRWfaNE1-1717935840758)]

st 的全部。

[外链图片转存中…(img-PwcZYTDE-1717935840758)]

st 中都有。

[外链图片转存中…(img-SoZkO8vS-1717935840758)]

s 中但不在 t 中。

[外链图片转存中…(img-3xnwT7OQ-1717935840759)]

t 中但不在 s 中。

[外链图片转存中…(img-rNDbfeFX-1717935840759)]

在其中一个但不是两者都。

set对象的一个应用是从list对象中消除重复项。例如:

In [138]: from random import randint
          l = [randint(0, 10) for i in range(1000)]  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          len(l)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[138]: 1000
In [139]: l[:20]
Out[139]: [10, 9, 2, 4, 5, 1, 7, 4, 6, 10, 9, 5, 4, 6, 10, 3, 4, 7, 0, 5]
In [140]: s = set(l)
          s
Out[140]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

[外链图片转存中…(img-kYDec8em-1717935840759)]

1,000 个 0 到 10 之间的随机整数。

[外链图片转存中…(img-WiF4IKCk-1717935840759)]

l 中的元素数量。

结论

基本的Python解释器已经提供了丰富灵活的数据结构。从金融的角度来看,以下可以被认为是最重要的:

基本数据类型

在金融中,intfloatstring类提供了原子数据类型。

标准数据结构

tuplelistdictset类在金融领域有许多应用领域,其中list通常是最灵活的通用工作马。

进一步资源

本章重点讨论可能对金融算法和应用特别重要的问题。但是,它只能代表探索Python中数据结构和数据建模的起点。有许多宝贵的资源可供进一步深入了解。

书籍形式的良好参考资料包括:

  • Goodrich, Michael 等(2013):Python 数据结构与算法. John Wiley & Sons, Hoboken, NJ.
  • Harrison, Matt (2017): Python 3 图解指南. Treading on Python Series.
  • Ramalho, Luciano (2016): 流畅的 Python. O’Reilly, Beijing et al.

¹ Cython将静态类型和编译功能引入Python,与C中的相似。实际上,CythonPythonC的混合语言。

² 在这里和后续讨论中,诸如floatfloat 对象等术语可互换使用,承认每个float也是一个对象。对于其他对象类型也是如此。

³ 参考http://en.wikipedia.org/wiki/Double-precision_floating-point_format

⁴ 在这里不可能详细介绍,但互联网上有大量关于正则表达式的信息,特别是针对Python。关于这个主题的介绍,请参阅 Fitzgerald, Michael (2012): 正则表达式入门. O’Reilly, Sebastopol, CA.

相关文章
|
2天前
|
数据可视化 Python
Python 金融编程第二版(三)(4)
Python 金融编程第二版(三)
12 2
|
2天前
|
存储 数据可视化 API
Python 金融编程第二版(三)(5)
Python 金融编程第二版(三)
8 1
|
2天前
|
存储 数据可视化 索引
Python 金融编程第二版(三)(3)
Python 金融编程第二版(三)
11 1
|
2天前
|
程序员 索引 Python
Python 金融编程第二版(三)(2)
Python 金融编程第二版(三)
9 1
|
2天前
|
存储 机器学习/深度学习 关系型数据库
Python 金融编程第二版(四)(5)
Python 金融编程第二版(四)
8 0
|
2天前
|
存储 SQL 数据库
Python 金融编程第二版(四)(4)
Python 金融编程第二版(四)
8 0
|
2天前
|
SQL 存储 数据库
Python 金融编程第二版(四)(3)
Python 金融编程第二版(四)
8 0
|
2天前
|
存储 分布式计算 数据可视化
Python 金融编程第二版(四)(2)
Python 金融编程第二版(四)
10 0
|
2天前
|
存储 SQL 数据可视化
Python 金融编程第二版(四)(1)
Python 金融编程第二版(四)
9 0
|
2天前
|
算法 程序员 索引
Python 金融编程第二版(三)(1)
Python 金融编程第二版(三)
9 0