28、数学游戏与科学可视化:NumPy与SciPy的应用

数学游戏与科学可视化:NumPy与SciPy的应用

1. NumPy数组的方法和属性

在Python的数值计算领域,NumPy是一个强大的工具。数组作为NumPy中的重要对象,具有方法(函数)和属性(变量)。我们可以使用IPython通过Tab键的字符补全功能列出对象的方法和属性,也可以使用以下代码:

import numpy
[m for m in dir(numpy.ndarray) if not(m.startswith('__'))]

运行上述代码后,会得到一串数组的方法和属性列表,如 ['T', 'all', 'any', 'argmax', ... , 'view'] 。下面我们来详细介绍部分常用的方法和属性,它们被分为不同的类别,方便查看。

1.1 逻辑类方法

函数 描述 示例
all() 如果数组 a 的所有元素都为真(非零),则返回 True arange(10).all() 返回 False ,因为第一个元素是零; arange(-5, -2).all() 返回 True
any() 如果数组 a 中至少有一个元素为真(非零),则返回 True arange(10).any() 返回 True
nonzero() 返回数组 a 中非零元素的索引元组 arange(3).nonzero() 返回 (array([1, 2], dtype=int64),)

1.2 索引类方法

函数 描述 示例
sort() 对数组 a 中的元素进行排序 a = arange(3, 0, -1) a 设置为 array([3, 2, 1]) a.sort() a 变为 array([1, 2, 3])
searchsorted(x) 返回插入 x 的索引,以保持数组的顺序,假设数组 a 已经排序 arange(4).searchsorted(1.5) 返回 2

1.3 修改类方法

函数 描述 示例
clip(min, max) 如果数组 a 的元素小于 min ,则返回 min ;如果大于 max ,则返回 max ;否则返回该元素 arange(5).clip(1, 3) 返回 array([1, 1, 2, 3, 3])
compress(cond) 返回一个数组,其元素满足 cond 指定的条件,等同于 a[cond] a = arange(10) a.compress(a > 5) 返回 array([6, 7, 8, 9]) a[a > 5] 也返回 array([6, 7, 8, 9])
fill(x) 将数组的所有值设置为 x ,等同于 a[:] = x a = zeros([2, 2]) a[:] = -1 a 设置为 array([[-1., -1.], [-1., -1.]])

1.4 数学类方法

假设 a = array([1, 1j, -1]) ,也可以表示为 a = exp(1j*pi*arange(3)/2)
| 函数 | 描述 | 示例 |
| — | — | — |
| cumprod() | 累积乘积,每个元素是数组中前面元素的乘积 | a.cumprod() 返回 array([ 1.+0.j, 0.+1.j, 0.-1.j]) |
| cumsum() | 累积求和,每个元素是数组中前面元素的和 | a.cumsum() 返回 array([ 1.+0.j, 1.+1.j, 0.+1.j]) |
| real & imag | 数组 a 中元素的实部和虚部 | a.imag 返回 array([ 0., 1., 0.]) a.real 返回 array([ 1., 0., -1.]) |
| conj() | 数组 a 的复共轭(虚部取反,行列转置) | a[1].conj() 返回 -1j |
| max(), min() | 数组 a 的最大值和最小值(仅对实部进行操作) | a.max() 返回 (1+0j) a.min() 返回 (-1+0j) |
| mean() | 数组 a 的平均值 | a.mean() 返回 0.33333333333333331j (1j/3) |
| prod() | 数组 a 中所有值的乘积 | a.prod() 返回 -1j ,且 a.prod() 等于 a.cumprod()[-1] |
| ptp() | 数组 a 的峰峰值,等同于 a.max()-a.min() | a.ptp() 返回 (2+0j) |
| round() | 数组 a 的四舍五入值 | exp(a).round() 返回 array([ 3.+0.j, 1.+1.j, 0.+0.j]) |
| std() | 数组 a 中元素的标准差 | arange(2).std() 返回 0.5 |
| sum() | 数组 a 中所有值的和 | a.sum() 返回 1j ,且 a.sum() 等于 a.cumsum()[-1] |
| trace([n]) | 二维数组的对角线元素之和,如果提供 n ,则对偏移对角线求和 | eye(10).trace() 返回 10 |
| var() | 数组 a 中元素的方差 | arange(2).var() 返回 0.25 |

1.5 形状相关方法和属性

函数/属性 描述 示例
flatten() 将数组 a 的值转换为一维数组 eye(2).flatten() 返回 array([ 1., 0., 0., 1.])
ndim 数组 a 的维度数 eye(4, 5).ndim 返回 2
repeat(n) 将数组 a 复制 n 次并展平 eye(2).repeat(2) 返回 array([ 1., 1., 0., 0., 0., 0., 1., 1.])
reshape(d1, d2, …) 生成一个大小为 (d1, d2, ...) 的新数组 arange(4).reshape(2, 2) 返回 array([[0, 1], [2, 3]])
resize(d1, d2, …) 将当前数组的大小调整为 (d1, d2, ...) a = arange(4) a.resize(2, 2) a 设置为 array([[0, 1], [2, 3]])
shape 表示数组 a 形状的元组 eye(3, 4).shape 返回 (3, 4)
transpose() 转置矩阵,等同于共轭但不否定虚部 eye(2, 3).transpose() 返回 array([[ 1., 0.], [ 0., 1.], [ 0., 0.]])

1.6 转换类方法

函数 描述 示例
tofile(fname) 将数组写入文件(二进制) eye(2).tofile('eye2.bin')
fromfile(fid) 从文件(二进制)中读取数组 a = fromfile(open('eye2.bin'))
tolist() 将数组转换为列表 eye(2).tolist() 返回 [[1.0, 0.0], [0.0, 1.0]]

2. 幻方示例

幻方是一种特殊的正方形,其每行、每列的元素之和都相等,且通常不允许数字重复。我们可以使用De la Loubère方法(也称为暹罗方法)来生成幻方,该方法仅适用于奇数阶的幻方。

2.1 算法步骤

  1. 将数字 1 放在顶部中间的列。
  2. 后续数字沿对角线向上和向右放置。
  3. 如果超出正方形的边界,则将其环绕到最底行(如果超出顶部)或第一列(如果超出右侧)或两者。
  4. 如果单元格已被占用,则将数字向下移动一行(必要时进行环绕)。

2.2 代码实现

from pylab import *

def magicsq(n=3):
    """Returns a magic square of size n; n must be odd"""
    if n % 2 != 1:
        raise ValueError("Magic(n) requires n to be odd")
    m, row, col = zeros([n, n]), 0, n//2
    for num in range(1, n**2+1):
        m[row, col] = num      # fill the cell
        col = (col+1) % n
        row = (row-1) % n
        if m[row, col]:
            col = (col-1) % n
            row = (row+2) % n
    return m

def testmagicsq(m):
    """Returns True if m is a magic square."""
    msum = sum(m[0, :])
    return all(m.sum(0) == msum) and all(m.sum(1) == msum)

2.3 代码解释

  • magicsq 函数中,使用 for 循环按照算法规则填充幻方。通过取模运算符 % 来处理边界情况,避免了复杂的条件判断。
  • testmagicsq 函数中,通过比较每行和每列的和是否相等来判断是否为幻方。

2.4 测试示例

>>> exec(open('magic_square.py').read())
>>> a = eye(2, 3)
>>> a
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])
>>> a.sum(0)
array([ 1.,  1.,  0.])
>>> a.sum(1)
array([ 1.,  1.])
>>> m = magicsq(5)
>>> m.sum(0)
array([ 65.,  65.,  65.,  65.,  65.])
>>> m.sum(1)
array([ 65.,  65.,  65.,  65.,  65.])
>>> testmagicsq(m)
True

通过上述测试可以看到,生成的幻方满足每行、每列的和都相等的条件。

3. 其他有用的数组函数

除了 ndarray 的属性和方法外,NumPy还提供了一些操作数组的函数,这些函数不属于 ndarray 对象类。可以使用以下代码查看所有这些函数:

import numpy
dir(numpy)

这些函数涵盖了多个领域,具体如下:
- 向量运算 convolve() cross() correlate() vdot()
- 矩阵运算 diag() trace()
- 统计函数 cov() var() std() mean() histogram()
- 金融函数 fv() pv() pmt()
- 多项式运算 polyadd() polymul() polydiv() polyfit() polyder() polyint() roots()
- 改变向量和矩阵大小和方向的操作 flipud() fliplr() rot90()
- 生成滤波窗口的函数 hamming() hanning() bartlett() blackman() kaiser()

3.1 numpy.diff 函数示例

>>> help(numpy.diff)
Help on function diff in module numpy.lib.function_base:

diff(a, n=1, axis=-1)
    Calculate the n-th order discrete difference along given axis.

    The first order difference is given by ``out[n] = a[n+1] - a[n]`` along
    the given axis, higher order differences are calculated by using 'diff'
    recursively.

    Parameters
    ----------
    a : array_like
        Input array
    n : int, optional
        The number of times values are differenced.
    axis : int, optional
        The axis along which the difference is taken, default is the last
        axis.
    Returns
    -------
    diff : ndarray
        The 'n' order differences. The shape of the output is the same as 'a'
        except along 'axis' where the dimension is smaller by 'n'.

diff() 函数用于计算数组中两个连续元素之间的差值。在之前的示例中,如“Adding Arrows to a Graph”,以及可以修改朋友见面的示例来使用 diff() 函数替代列表推导式。

4. 数值分析与信号处理概述

数值分析和信号处理是许多科学领域(如数学、计算机科学、工程学等)中重要的主题。从简单的角度来看,数值分析关注能产生数值结果的算法,例如求解非线性方程的解、计算圆周率的十进制表示等。而信号处理则处理随时间变化的信号,包括信号的检测和滤波等。

虽然很多高校都开设了相关的本科课程,但即使没有工程或计算机科学背景,也能理解和运用这些方法和思想。对于有数值分析和信号处理基础的人来说,这里可以作为在Python中应用这些知识的起点;对于初学者,也能通过这里的介绍和示例,结合相关科学文献进一步学习。

5. NumPy的辅助函数

5.1 who() 函数

在交互式环境中工作时,我们会不断定义变量,很难记住定义了哪些变量以及它们的含义。 who() 函数可以打印出当前的NumPy数组列表。

>>> from pylab import *
>>> who()
Upper bound on total bytes  =       0
>>> up, down = arange(10), arange(10, 0, -1) 
>>> who()
Name            Shape            Bytes            Type
===========================================================
up              10               40               int32
down            10               40               int32 
Upper bound on total bytes  =       80 

5.2 lookfor() 函数

lookfor() 函数非常适合在文档字符串中进行搜索。例如,要查找执行数值积分的函数,可以使用以下代码:

>>> lookfor('integrate')
Search results for 'integrate'
------------------------------
numpy.trapz
    Integrate along the given axis using the composite trapezoidal rule. 

6. SciPy库介绍

6.1 SciPy概述

SciPy(http://www.scipy.org/)是一个用于Python的开源科学库,其理念类似于Octave - Forge(http://octave.sourceforge.net/)为GNU - Octave(http://www.octave.org)提供额外包,以及为MATLAB(http://www.mathworks.com)提供增强工具箱。SciPy构建在NumPy之上,因此需要NumPy才能正常工作。

6.2 SciPy的模块

SciPy被组织成多个模块,部分模块如下表所示:
| 模块 | 说明 |
| — | — |
| 未详细列出的模块 | 涵盖了数值分析、信号处理等多个领域的功能 |

7. 总结

本文介绍了NumPy数组的各种方法和属性,包括逻辑、索引、修改、数学、形状相关和转换等类别,通过详细的表格和示例代码展示了它们的使用方法。还讲解了幻方的生成算法及代码实现,以及NumPy中其他有用的数组函数。此外,对数值分析和信号处理的概念进行了概述,并介绍了NumPy的辅助函数 who() lookfor() ,最后引入了SciPy库。

通过这些内容,我们可以利用Python中的NumPy和SciPy库进行更高效的数值计算和科学分析。在实际应用中,可以根据具体需求选择合适的函数和方法,对代码进行修改和扩展,以解决各种实际问题。

下面是一个简单的mermaid流程图,展示了幻方生成的主要步骤:

graph TD;
    A[开始] --> B[初始化幻方矩阵、行和列];
    B --> C[循环填充数字];
    C --> D[填充当前单元格];
    D --> E[计算下一个列和行的位置];
    E --> F{下一个位置是否已占用};
    F -- 是 --> G[调整列和行的位置];
    F -- 否 --> C;
    G --> C;
    C --> H{是否填充完所有数字};
    H -- 是 --> I[返回幻方矩阵];
    H -- 否 --> C;
    I --> J[结束];

同时,我们可以将NumPy数组方法和属性的类别总结成如下列表:
1. 逻辑类方法: all() any() nonzero()
2. 索引类方法: sort() searchsorted()
3. 修改类方法: clip() compress() fill()
4. 数学类方法: cumprod() cumsum() real imag
5. 形状相关方法和属性: flatten() ndim repeat()
6. 转换类方法: tofile() fromfile() tolist()

这些总结和图表有助于我们更好地理解和记忆相关知识,在实际编程中能够更快速地选择和使用合适的函数。

本地跟单专家顾问(EA)是一种专为MetaTrader 4平台设计的自动化交易工具。该版本强调其无限制特性,允许用户在任何时段、不同地理区域及各类账户上自由部署,从而为交易者提供了高度灵活的操作空间。其核心机制采用同向复制策略,即接收端会完全模仿发送端的交易方向操作,适合那些信赖信号源稳定性的用户,以期通过跟随策略实现相近的投资回报。 系统架构包含两个独立模块:信号发送端信号接收端。发送端安装于主导交易决策的账户,接收端则配置于需同步执行的账户,二者协同工作,实现了交易指令的自动传递执行,有效减少了人工干预的需求。此外,该工具特别注重MT4服务器时间的同步,确保交易执行时点的精确性,避免因时区偏差可能引发的操作失误,这对于依赖时间敏感性的外汇市场尤为重要。 文件标识中的特定代号可能指向开发者的内部版本标记或某种定制化交易逻辑,具体含义需结合进一步的技术文档予以确认。整体而言,该EA为多账户管理策略复制提供了一个集成化解决方案,有助于提升交易执行的效率并降低操作风险。但需注意,市场环境处于持续变动中,任何自动化工具均需经过充分验证适应性测试,历史表现不能作为未来收益的保证。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值