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

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: Python 金融编程第二版(GPT 重译)(四)

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


基于 HDF5 的数据存储

当涉及到结构化的数值和金融数据时,HDF5分层数据库(文件)格式是一个强大的替代方案,例如,关系数据库。无论是在直接使用PyTables还是与pandas的功能结合使用时,您都可以期望获得几乎达到可用硬件允许的最大 I/O 性能。

内存外计算

PyTables支持内存外操作,这使得可以实现不适合内存的基于数组的计算。为此,请考虑以下基于EArray类的代码。这种类型的对象允许在一维(按行)中扩展,而列数(每行的元素)需要固定。

In [182]: filename = path + 'earray.h5'
In [183]: h5 = tb.open_file(filename, 'w')
In [184]: n = 500  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [185]: ear = h5.create_earray('/', 'ear',  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
                                atom=tb.Float64Atom(),  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
                                shape=(0, n))  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
In [186]: type(ear)
Out[186]: tables.earray.EArray
In [187]: rand = np.random.standard_normal((n, n))  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
          rand[:4, :4]
Out[187]: array([[-1.25983231,  1.11420699,  0.1667485 ,  0.7345676 ],
                 [-0.13785424,  1.22232417,  1.36303097,  0.13521042],
                 [ 1.45487119, -1.47784078,  0.15027672,  0.86755989],
                 [-0.63519366,  0.1516327 , -0.64939447, -0.45010975]])
In [188]: %%time
          for _ in range(750):
              ear.append(rand)  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
          ear.flush()
          CPU times: user 728 ms, sys: 1.11 s, total: 1.84 s
          Wall time: 2.03 s
In [189]: ear
Out[189]: /ear (EArray(375000, 500)) ''
            atom := Float64Atom(shape=(), dflt=0.0)
            maindim := 0
            flavor := 'numpy'
            byteorder := 'little'
            chunkshape := (16, 500)
In [190]: ear.size_on_disk
Out[190]: 1500032000


这定义了固定的列数。


EArray对象的路径和技术名称。


单个值的原子dtype对象。


用于实例化的形状(没有行,n列)。


具有随机数的ndarray对象…


… 多次附加。

对于不会导致聚合的内存外计算,需要另一个相同形状(大小)的EArray对象。 PyTables+有一个特殊模块可以高效处理数值表达式。它称为Expr,基于数值表达式库numexpr。接下来的代码使用Expr计算之前整个EArray对象中的方程式 9-1 的数学表达式。

方程式 9-1. 示例数学表达式

y = 3 sin ( x ) + | x |

结果存储在out EArray对象中,表达式评估以块方式进行。

In [191]: out = h5.create_earray('/', 'out',
                                atom=tb.Float64Atom(),
                                shape=(0, n))
In [192]: out.size_on_disk
Out[192]: 0
In [193]: expr = tb.Expr('3 * sin(ear) + sqrt(abs(ear))')  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [194]: expr.set_output(out, append_mode=True)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [195]: %time expr.eval()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
          CPU times: user 2.98 s, sys: 1.38 s, total: 4.36 s
          Wall time: 3.28 s
Out[195]: /out (EArray(375000, 500)) ''
            atom := Float64Atom(shape=(), dflt=0.0)
            maindim := 0
            flavor := 'numpy'
            byteorder := 'little'
            chunkshape := (16, 500)
In [196]: out.size_on_disk
Out[196]: 1500032000
In [197]: out[0, :10]
Out[197]: array([-1.73369462,  3.74824436,  0.90627898,  2.86786818,  1.75424957,
                 -0.91108973, -1.68313885,  1.29073295, -1.68665599, -1.71345309])
In [198]: %time out_ = out.read()  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
          CPU times: user 879 ms, sys: 1.11 s, total: 1.99 s
          Wall time: 2.18 s
In [199]: out_[0, :10]
Out[199]: array([-1.73369462,  3.74824436,  0.90627898,  2.86786818,  1.75424957,
                 -0.91108973, -1.68313885,  1.29073295, -1.68665599, -1.71345309])


这将基于str对象的表达式转换为Expr对象。


这定义了输出为 out EArray 对象。


这启动了表达式的评估。


这将整个 EArray 读入内存。

考虑到整个操作是在内存之外进行的,可以认为是相当快的,尤其是在标准硬件上执行。作为基准,可以考虑 numexpr 模块的内存性能(也见[Link to Come])。它更快,但并不是很大的优势:

In [200]: import numexpr as ne  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [201]: expr = '3 * sin(out_) + sqrt(abs(out_))'  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [202]: ne.set_num_threads(1)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
Out[202]: 4
In [203]: %time ne.evaluate(expr)[0, :10]  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
          CPU times: user 1.72 s, sys: 529 ms, total: 2.25 s
          Wall time: 2.38 s
Out[203]: array([-1.64358578,  0.22567882,  3.31363043,  2.50443549,  4.27413965,
                 -1.41600606, -1.68373023,  4.01921805, -1.68117412, -1.66053597])
In [204]: ne.set_num_threads(4)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
Out[204]: 1
In [205]: %time ne.evaluate(expr)[0, :10]  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
          CPU times: user 2.29 s, sys: 804 ms, total: 3.09 s
          Wall time: 1.56 s
Out[205]: array([-1.64358578,  0.22567882,  3.31363043,  2.50443549,  4.27413965,
                 -1.41600606, -1.68373023,  4.01921805, -1.68117412, -1.66053597])
In [206]: h5.close()
In [207]: !rm -f $path*


导入用于 内存中 评估数值表达式的模块。


数值表达式作为 str 对象。


将线程数设置为仅一个。


使用一个线程在内存中评估数值表达式。


将线程数设置为四。


使用四个线程在内存中评估数值表达式。

通过 TsTables 进行 I/O 操作。

TsTables 包使用 PyTables 构建了一个高性能的时间序列数据存储。主要的使用场景是“一次写入,多次检索”。这是金融分析中的典型场景,因为数据是在市场上创建的,可能是实时或异步检索,并存储在磁盘上以供以后使用。这样的使用场景可能是一个较大的交易策略回测程序,需要反复使用历史金融时间序列的不同子集。因此,数据检索速度很重要。

示例数据

通常情况下,首先生成一些足够大的示例数据集,以说明 TsTables 的好处。以下代码基于几何布朗运动的模拟生成了三个相当长的金融时间序列(见[Link to Come])。

In [208]: no = 5000000  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          co = 3  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
          interval = 1. / (12 * 30 * 24 * 60)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
          vol = 0.2  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
In [209]: %%time
          rn = np.random.standard_normal((no, co))  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
          rn[0] = 0.0  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
          paths = 100 * np.exp(np.cumsum(-0.5 * vol ** 2 * interval +
                  vol * np.sqrt(interval) * rn, axis=0))  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/7.png)
          paths[0] = 100  ![8](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/8.png)
          CPU times: user 932 ms, sys: 204 ms, total: 1.14 s
          Wall time: 1.2 s


时间步数。


时间序列的数量。


年份间隔作为年分数。


波动率。


标准正态分布的随机数。


初始随机数设为 0。


基于 Euler 离散化的模拟。


将路径的初始值设为 100。

由于TsTablespandas DataFrame对象很好地配合,因此数据被转换为这样的对象(另见图 9-7)。

In [210]: dr = pd.date_range('2019-1-1', periods=no, freq='1s')
In [211]: dr[-6:]
Out[211]: DatetimeIndex(['2019-02-27 20:53:14', '2019-02-27 20:53:15',
                         '2019-02-27 20:53:16', '2019-02-27 20:53:17',
                         '2019-02-27 20:53:18', '2019-02-27 20:53:19'],
                        dtype='datetime64[ns]', freq='S')
In [212]: df = pd.DataFrame(paths, index=dr, columns=['ts1', 'ts2', 'ts3'])
In [213]: df.info()
          <class 'pandas.core.frame.DataFrame'>
          DatetimeIndex: 5000000 entries, 2019-01-01 00:00:00 to 2019-02-27 20:53:19
          Freq: S
          Data columns (total 3 columns):
          ts1    float64
          ts2    float64
          ts3    float64
          dtypes: float64(3)
          memory usage: 152.6 MB
In [214]: df.head()
Out[214]:                             ts1         ts2         ts3
          2019-01-01 00:00:00  100.000000  100.000000  100.000000
          2019-01-01 00:00:01  100.018443   99.966644   99.998255
          2019-01-01 00:00:02  100.069023  100.004420   99.986646
          2019-01-01 00:00:03  100.086757  100.000246   99.992042
          2019-01-01 00:00:04  100.105448  100.036033   99.950618
In [215]: df[::100000].plot(figsize=(10, 6));
          plt.savefig('../../images/ch09/io_07.png')


图 9-7. 金融时间序列的选定数据点

数据存储

TsTables基于特定的基于块的结构存储金融时间序列数据,该结构允许根据某个时间间隔快速检索任意数据子集。为此,该软件包将create_ts()函数添加到PyTables中。以下代码使用了来自PyTablesclass基于描述方法,基于tb.IsDescription类。

In [216]: import tstables as tstab
In [217]: class ts_desc(tb.IsDescription):
              timestamp = tb.Int64Col(pos=0)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
              ts1 = tb.Float64Col(pos=1)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
              ts2 = tb.Float64Col(pos=2)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
              ts3 = tb.Float64Col(pos=3)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [218]: h5 = tb.open_file(path + 'tstab.h5', 'w')  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
In [219]: ts = h5.create_ts('/', 'ts', ts_desc)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
In [220]: %time ts.append(df)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
          CPU times: user 692 ms, sys: 403 ms, total: 1.1 s
          Wall time: 1.12 s
In [221]: type(ts)
Out[221]: tstables.tstable.TsTable
In [222]: ls -n $path
          total 306720
          -rw-r--r--  1 501  20  157037368 Jan 18 10:07 tstab.h5


时间戳的列。


存储数字数据的列。


为写入(w)打开HDF5数据库文件。


基于ts_desc对象创建TsTable对象。


DataFrame对象中的数据附加到TsTable对象。

数据检索

使用TsTables编写数据显然非常快,即使与硬件有关。对数据的块的读取也是如此。方便的是,TaTables返回一个DataFrame对象(另见图 9-8)。

In [223]: read_start_dt = dt.datetime(2019, 2, 1, 0, 0)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
          read_end_dt = dt.datetime(2019, 2, 5, 23, 59)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [224]: %time rows = ts.read_range(read_start_dt, read_end_dt)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
          CPU times: user 80.5 ms, sys: 36.2 ms, total: 117 ms
          Wall time: 116 ms
In [225]: rows.info()  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
          <class 'pandas.core.frame.DataFrame'>
          DatetimeIndex: 431941 entries, 2019-02-01 00:00:00 to 2019-02-05 23:59:00
          Data columns (total 3 columns):
          ts1    431941 non-null float64
          ts2    431941 non-null float64
          ts3    431941 non-null float64
          dtypes: float64(3)
          memory usage: 13.2 MB
In [226]: rows.head()  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
Out[226]:                            ts1        ts2         ts3
          2019-02-01 00:00:00  52.063640  40.474580  217.324713
          2019-02-01 00:00:01  52.087455  40.471911  217.250070
          2019-02-01 00:00:02  52.084808  40.458013  217.228712
          2019-02-01 00:00:03  52.073536  40.451408  217.302912
          2019-02-01 00:00:04  52.056133  40.450951  217.207481
In [227]: h5.close()
In [228]: (rows[::500] / rows.iloc[0]).plot(figsize=(10, 6));
          plt.savefig('../../images/ch09/io_08.png')


时间间隔的开始时间。


时间间隔的结束时间。


函数ts.read_range()返回时间间隔的DataFrame对象。


DataFrame对象有几十万行数据。


图 9-8. 金融时间序列的特定时间间隔(归一化)

为了更好地说明基于TsTables的数据检索性能,考虑以下基准,该基准检索由三天的一秒钟柱状图组成的 100 个数据块。检索包含 345,600 行数据的DataFrame仅需不到十分之一秒。

In [229]: import random
In [230]: h5 = tb.open_file(path + 'tstab.h5', 'r')
In [231]: ts = h5.root.ts._f_get_timeseries()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [235]: %%time
          for _ in range(100):  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
              d = random.randint(1, 24)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
              read_start_dt = dt.datetime(2019, 2, d, 0, 0, 0)
              read_end_dt = dt.datetime(2019, 2, d + 3, 23, 59, 59)
              rows = ts.read_range(read_start_dt, read_end_dt)
          CPU times: user 3.51 s, sys: 1.03 s, total: 4.55 s
          Wall time: 4.62 s
In [233]: rows.info()  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
          <class 'pandas.core.frame.DataFrame'>
          DatetimeIndex: 431941 entries, 2019-02-01 00:00:00 to 2019-02-05 23:59:00
          Data columns (total 3 columns):
          ts1    431941 non-null float64
          ts2    431941 non-null float64
          ts3    431941 non-null float64
          dtypes: float64(3)
          memory usage: 13.2 MB
In [234]: !rm $path/tstab.h5


连接到TsTable对象。


数据检索重复多次。


起始日值被随机化。


最后检索到的DataFrame对象。

结论

基于SQL或关系数据库的方法在处理展示了许多单个对象/表之间关系的复杂数据结构时具有优势。在某些情况下,这可能会使它们在纯NumPy ndarraypandas DataFrame方法上的性能劣势成为合理。

金融或一般科学中的许多应用领域可以通过主要基于数组的数据建模方法取得成功。在这些情况下,通过利用原生NumPy的 I/O 功能、NumPyPyTables功能的组合,或通过HDF5-based 存储的pandas方法,可以实现巨大的性能提升。当处理大型(金融)时间序列数据集时,尤其是在“一次写入,多次检索”的场景中,TsTables特别有用。

虽然最近的一个趋势是使用基于商品硬件的大量计算节点组成的云解决方案,特别是在金融背景下,人们应该仔细考虑哪种硬件架构最适合分析需求。微软的一项研究对这个问题有所启发:

我们声称一个“扩展”服务器可以处理这些工作中的每一个,并且在性能、成本、功耗和服务器密度等方面与集群一样好,甚至更好。

Appuswamy 等人(2013 年)

从事数据分析的公司、研究机构等应该首先分析一般情况下必须完成的具体任务,然后根据以下方面的硬件/软件架构做出决策:

扩展

使用具有标准 CPU 和相对较低内存的许多商品节点的集群

扩展

使用一台或多台强大的服务器,配备多核 CPU,可能还有 GPU 甚至 TPU,当机器学习和深度学习发挥作用时,并拥有大量内存。

扩展硬件规模并应用适当的实现方法可能会显著影响性能。下一章将更多地涉及性能。

进一步阅读

本章开头引用的论文以及“结论”部分是一篇不错的文章,也是思考金融分析硬件架构的良好起点:

通常情况下,网络提供了许多有关本章涵盖主题的宝贵资源:

¹ 这里,我们不区分不同级别的 RAM 和处理器缓存。当前内存架构的最佳使用是一个独立的主题。

² 要了解 Python 可用的数据库连接器的概述,请访问https://wiki.python.org/moin/DatabaseInterfaces。与直接使用关系型数据库不同,对象关系映射器,例如SQLAlchemy,通常非常有用。它们引入了一个抽象层,允许更加 Pythonic、面向对象的代码。它们还允许更容易地在后端将一个关系型数据库更换为另一个。

³ 请参阅https://www.sqlite.org/lang.html以了解 SQLite3 语言方言的概述。

⁴ 请参阅http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html

⁵ 许多其他数据库需要服务器-客户端架构。对于交互式数据和金融分析,基于文件的数据库在一般情况下会更加方便,也足够满足大多数目的。

s: user 3.51 s, sys: 1.03 s, total: 4.55 s

Wall time: 4.62 s

In [233]: rows.info()

<class 'pandas.core.frame.DataFrame'>
      DatetimeIndex: 431941 entries, 2019-02-01 00:00:00 to 2019-02-05 23:59:00
      Data columns (total 3 columns):
      ts1    431941 non-null float64
      ts2    431941 non-null float64
      ts3    431941 non-null float64
      dtypes: float64(3)
      memory usage: 13.2 MB

In [234]: !rm $path/tstab.h5

[外链图片转存中...(img-axcfhWBH-1717935705766)]
连接到`TsTable`对象。
[外链图片转存中...(img-ieVQ1Bmg-1717935705766)]
数据检索重复多次。
[外链图片转存中...(img-LvzYt28v-1717935705767)]
起始日值被随机化。
[外链图片转存中...(img-VlipnGfe-1717935705767)]
最后检索到的`DataFrame`对象。
# 结论
基于`SQL`或关系数据库的方法在处理展示了许多单个对象/表之间关系的复杂数据结构时具有优势。在某些情况下,这可能会使它们在纯`NumPy` `ndarray`或`pandas` `DataFrame`方法上的性能劣势成为合理。
金融或一般科学中的许多应用领域可以通过主要基于数组的数据建模方法取得成功。在这些情况下,通过利用原生`NumPy`的 I/O 功能、`NumPy`和`PyTables`功能的组合,或通过`HDF5`-based 存储的`pandas`方法,可以实现巨大的性能提升。当处理大型(金融)时间序列数据集时,尤其是在“一次写入,多次检索”的场景中,`TsTables`特别有用。
虽然最近的一个趋势是使用基于商品硬件的大量计算节点组成的云解决方案,特别是在金融背景下,人们应该仔细考虑哪种硬件架构最适合分析需求。微软的一项研究对这个问题有所启发:
> 我们声称一个“扩展”服务器可以处理这些工作中的每一个,并且在性能、成本、功耗和服务器密度等方面与集群一样好,甚至更好。
> 
> Appuswamy 等人(2013 年)
从事数据分析的公司、研究机构等应该首先分析一般情况下必须完成的具体任务,然后根据以下方面的硬件/软件架构做出决策:
扩展
使用具有标准 CPU 和相对较低内存的许多商品节点的集群
扩展
使用一台或多台强大的服务器,配备多核 CPU,可能还有 GPU 甚至 TPU,当机器学习和深度学习发挥作用时,并拥有大量内存。
扩展硬件规模并应用适当的实现方法可能会显著影响性能。下一章将更多地涉及性能。
# 进一步阅读
本章开头引用的论文以及“结论”部分是一篇不错的文章,也是思考金融分析硬件架构的良好起点:
+   Appuswamy,Raja 等人(2013 年):“`没有人因为购买集群而被解雇。`”微软研究,英格兰剑桥,[*http://research.microsoft.com/apps/pubs/default.aspx?id=179615*](http://research.microsoft.com/apps/pubs/default.aspx?id=179615)。
通常情况下,网络提供了许多有关本章涵盖主题的宝贵资源:
+   对于使用`pickle`对 Python 对象进行序列化,请参阅文档:[*http://docs.python.org/3/library/pickle.html*](http://docs.python.org/3/library/pickle.html)。
+   关于`NumPy`的 I/O 功能概述可在`SciPy`网站上找到:[*http://docs.scipy.org/doc/numpy/reference/routines.io.html*](http://docs.scipy.org/doc/numpy/reference/routines.io.html)。
+   对于使用`pandas`进行 I/O,请参阅在线文档中的相应部分:[*http://pandas.pydata.org/pandas-docs/stable/io.html*](http://pandas.pydata.org/pandas-docs/stable/io.html)。
+   `PyTables`首页提供了教程和详细文档:[*http://www.pytables.org*](http://www.pytables.org)。
+   `TsTables` 的 Github 页面位于[*https://github.com/afiedler/tstables*](https://github.com/afiedler/tstables)。
¹ 这里,我们不区分不同级别的 RAM 和处理器缓存。当前内存架构的最佳使用是一个独立的主题。
² 要了解 Python 可用的数据库连接器的概述,请访问[*https://wiki.python.org/moin/DatabaseInterfaces*](https://wiki.python.org/moin/DatabaseInterfaces)。与直接使用关系型数据库不同,对象关系映射器,例如[SQLAlchemy](https://www.sqlalchemy.org/),通常非常有用。它们引入了一个抽象层,允许更加 Pythonic、面向对象的代码。它们还允许更容易地在后端将一个关系型数据库更换为另一个。
³ 请参阅[*https://www.sqlite.org/lang.html*](https://www.sqlite.org/lang.html)以了解 `SQLite3` 语言方言的概述。
⁴ 请参阅[*http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html*](http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html)。
⁵ 许多其他数据库需要服务器-客户端架构。对于交互式数据和金融分析,基于文件的数据库在一般情况下会更加方便,也足够满足大多数目的。
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
9天前
|
存储 数据挖掘 开发者
Python编程入门:从零到英雄
在这篇文章中,我们将一起踏上Python编程的奇幻之旅。无论你是编程新手,还是希望拓展技能的开发者,本教程都将为你提供一条清晰的道路,引导你从基础语法走向实际应用。通过精心设计的代码示例和练习,你将学会如何用Python解决实际问题,并准备好迎接更复杂的编程挑战。让我们一起探索这个强大的语言,开启你的编程生涯吧!
|
2天前
|
Python
Python编程入门:从零开始的代码旅程
本文是一篇针对Python编程初学者的入门指南,将介绍Python的基本语法、数据类型、控制结构以及函数等概念。文章旨在帮助读者快速掌握Python编程的基础知识,并能够编写简单的Python程序。通过本文的学习,读者将能够理解Python代码的基本结构和逻辑,为进一步深入学习打下坚实的基础。
|
6天前
|
数据采集 存储 数据处理
Python中的多线程编程及其在数据处理中的应用
本文深入探讨了Python中多线程编程的概念、原理和实现方法,并详细介绍了其在数据处理领域的应用。通过对比单线程与多线程的性能差异,展示了多线程编程在提升程序运行效率方面的显著优势。文章还提供了实际案例,帮助读者更好地理解和掌握多线程编程技术。
|
9天前
|
存储 人工智能 数据挖掘
Python编程入门:打造你的第一个程序
本文旨在为初学者提供Python编程的初步指导,通过介绍Python语言的基础概念、开发环境的搭建以及一个简单的代码示例,帮助读者快速入门。文章将引导你理解编程思维,学会如何编写、运行和调试Python代码,从而开启编程之旅。
34 2
|
10天前
|
存储 Python
Python编程入门:理解基础语法与编写简单程序
本文旨在为初学者提供一个关于如何开始使用Python编程语言的指南。我们将从安装Python环境开始,逐步介绍变量、数据类型、控制结构、函数和模块等基本概念。通过实例演示和练习,读者将学会如何编写简单的Python程序,并了解如何解决常见的编程问题。文章最后将提供一些资源,以供进一步学习和实践。
22 1
|
13天前
|
存储 网络协议 IDE
从零起步学习Python编程
从零起步学习Python编程
|
11天前
|
机器学习/深度学习 存储 数据挖掘
Python 编程入门:理解变量、数据类型和基本运算
【10月更文挑战第43天】在编程的海洋中,Python是一艘易于驾驭的小船。本文将带你启航,探索Python编程的基础:变量的声明与使用、丰富的数据类型以及如何通过基本运算符来操作它们。我们将从浅显易懂的例子出发,逐步深入到代码示例,确保即使是零基础的读者也能跟上步伐。准备好了吗?让我们开始吧!
23 0
|
2月前
|
安全 测试技术 数据库
Python编程--sys模块及OS模块简单用例
Python编程--sys模块及OS模块简单用例
|
2月前
|
JSON 数据格式 Python
Python编程:利用JSON模块编程验证用户
Python编程:利用JSON模块编程验证用户
|
2月前
|
数据处理 Python
Python编程-利用datetime模块生成当前年份之前指定的间隔所有年份的日期列表和csv文件
Python编程-利用datetime模块生成当前年份之前指定的间隔所有年份的日期列表和csv文件