Skip to content

数学运算和函数

在这一章中,我们将深入学习 NumPy 的数学运算和函数,包括基本算术运算、三角函数、统计函数、线性代数等。

基本算术运算

元素级运算

python
import numpy as np

# 创建示例数组
array1 = np.array([1, 2, 3, 4, 5])
array2 = np.array([10, 20, 30, 40, 50])

print("数组1:", array1)
print("数组2:", array2)
print()

# 基本算术运算
print("加法 array1 + array2:", array1 + array2)
print("减法 array2 - array1:", array2 - array1)
print("乘法 array1 * array2:", array1 * array2)
print("除法 array2 / array1:", array2 / array1)
print("整数除法 array2 // array1:", array2 // array1)
print("取余 array2 % array1:", array2 % array1)
print("幂运算 array1 ** 2:", array1 ** 2)
print()

# 与标量的运算
scalar = 10
print(f"数组加标量 array1 + {scalar}:", array1 + scalar)
print(f"数组乘标量 array1 * {scalar}:", array1 * scalar)
print(f"数组除标量 array1 / {scalar}:", array1 / scalar)
print(f"标量减数组 {scalar} - array1:", scalar - array1)

输出结果:

数组1: [1 2 3 4 5]
数组2: [10 20 30 40 50]

加法 array1 + array2: [11 22 33 44 55]
减法 array2 - array1: [ 9 18 27 36 45]
乘法 array1 * array2: [ 10  40  90 160 250]
除法 array2 / array1: [10. 10. 10. 10. 10.]
整数除法 array2 // array1: [10 10 10 10 10]
取余 array2 % array1: [0 0 0 0 0]
幂运算 array1 ** 2: [ 1  4  9 16 25]

数组加标量 array1 + 10: [11 12 13 14 15]
数组乘标量 array1 * 10: [10 20 30 40 50]
数组除标量 array1 / 10: [0.1 0.2 0.3 0.4 0.5]
标量减数组 10 - array1: [9 8 7 6 5]

数学函数

python
import numpy as np

# 创建测试数组
array = np.array([1, 4, 9, 16, 25])
print("原始数组:", array)
print()

# 基本数学函数
print("平方根 np.sqrt():", np.sqrt(array))
print("立方根 np.cbrt():", np.cbrt(array))
print("平方 np.square():", np.square(array))
print("绝对值 np.abs():", np.abs(array - 10))
print()

# 指数和对数函数
small_array = np.array([1, 2, 3, 4, 5])
print("小数组:", small_array)
print("自然指数 np.exp():", np.exp(small_array))
print("以2为底的指数 np.exp2():", np.exp2(small_array))
print("自然对数 np.log():", np.log(small_array))
print("以10为底的对数 np.log10():", np.log10(small_array))
print("以2为底的对数 np.log2():", np.log2(small_array))
print()

# 取整函数
float_array = np.array([1.2, 2.7, -1.5, -2.8, 3.0])
print("浮点数组:", float_array)
print("向下取整 np.floor():", np.floor(float_array))
print("向上取整 np.ceil():", np.ceil(float_array))
print("四舍五入 np.round():", np.round(float_array))
print("截断取整 np.trunc():", np.trunc(float_array))

输出结果:

原始数组: [ 1  4  9 16 25]

平方根 np.sqrt(): [1. 2. 3. 4. 5.]
立方根 np.cbrt(): [1.         1.58740105 2.08008382 2.51984210 2.92401774]
平方 np.square(): [  1  16  81 256 625]
绝对值 np.abs(): [ 9  6  1  6 15]

小数组: [1 2 3 4 5]
自然指数 np.exp(): [  2.71828183   7.3890561   20.08553692  54.59815003 148.4131591 ]
以2为底的指数 np.exp2(): [ 2.  4.  8. 16. 32.]
自然对数 np.log(): [0.         0.69314718 1.09861229 1.38629436 1.60943791]
以10为底的对数 np.log10(): [0.         0.30103    0.47712125 0.60205999 0.69897   ]
以2为底的对数 np.log2(): [0.        1.        1.5849625 2.        2.321928 ]

浮点数组: [ 1.2  2.7 -1.5 -2.8  3. ]
向下取整 np.floor(): [ 1.  2. -2. -3.  3.]
向上取整 np.ceil(): [ 2.  3. -1. -2.  3.]
四舍五入 np.round(): [ 1.  3. -2. -3.  3.]
截断取整 np.trunc(): [ 1.  2. -1. -2.  3.]

三角函数

基本三角函数

python
import numpy as np

# 创建角度数组(弧度)
angles_rad = np.array([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2, np.pi])
print("角度(弧度):", angles_rad)
print("角度(度):", np.degrees(angles_rad))
print()

# 基本三角函数
print("正弦值 np.sin():", np.sin(angles_rad))
print("余弦值 np.cos():", np.cos(angles_rad))
print("正切值 np.tan():", np.tan(angles_rad))
print()

# 反三角函数
values = np.array([0, 0.5, 0.707, 0.866, 1.0])
print("数值:", values)
print("反正弦 np.arcsin():", np.arcsin(values))
print("反余弦 np.arccos():", np.arccos(values))
print("反正切 np.arctan():", np.arctan(values))
print()

# 双曲函数
print("双曲正弦 np.sinh():", np.sinh([0, 1, 2]))
print("双曲余弦 np.cosh():", np.cosh([0, 1, 2]))
print("双曲正切 np.tanh():", np.tanh([0, 1, 2]))

输出结果:

角度(弧度): [0.         0.52359878 0.78539816 1.04719755 1.57079633 3.14159265]
角度(度): [ 0. 30. 45. 60. 90. 180.]

正弦值 np.sin(): [0.0000000e+00 5.0000000e-01 7.0710678e-01 8.6602540e-01
 1.0000000e+00 1.2246468e-16]
余弦值 np.cos(): [ 1.00000000e+00  8.66025404e-01  7.07106781e-01  5.00000000e-01
  6.12323400e-17 -1.00000000e+00]
正切值 np.tan(): [ 0.00000000e+00  5.77350269e-01  1.00000000e+00  1.73205081e+00
  1.63312394e+16 -1.22464680e-16]

数值: [0.    0.5   0.707 0.866 1.   ]
反正弦 np.arcsin(): [0.         0.52359878 0.78539816 1.04719755 1.57079633]
反余弦 np.arccos(): [1.57079633 1.04719755 0.78539816 0.52359878 0.        ]
反正切 np.arctan(): [0.         0.46364761 0.61072596 0.71882999 0.78539816]

双曲正弦 np.sinh(): [0.         1.17520119 3.62686041]
双曲余弦 np.cosh(): [1.         1.54308063 3.76219569]
双曲正切 np.tanh(): [0.         0.76159416 0.96402758]

角度转换和特殊三角函数

python
import numpy as np

# 角度和弧度转换
degrees = np.array([0, 30, 45, 60, 90, 180])
radians = np.radians(degrees)

print("角度:", degrees)
print("转换为弧度:", radians)
print("再转换回角度:", np.degrees(radians))
print()

# 特殊三角函数
x = np.array([1, 2, 3])
y = np.array([1, 1, 4])

print("x:", x)
print("y:", y)
print("atan2(y, x):", np.arctan2(y, x))  # 考虑象限的反正切
print("hypot(x, y):", np.hypot(x, y))    # 计算 sqrt(x²+y²)
print()

# 角度标准化
angles = np.array([0, 90, 180, 270, 360, 450, -90])
print("原始角度:", angles)
print("标准化到[0, 360):", angles % 360)
print("标准化到[-180, 180):", ((angles + 180) % 360) - 180)

输出结果:

角度: [  0  30  45  60  90 180]
转换为弧度: [0.         0.52359878 0.78539816 1.04719755 1.57079633 3.14159265]
再转换回角度: [  0.  30.  45.  60.  90. 180.]

x: [1 2 3]
y: [1 1 4]
atan2(y, x): [0.78539816 0.46364761 0.92729522]
hypot(x, y): [1.41421356 2.23606798 5.        ]

原始角度: [  0  90 180 270 360 450 -90]
标准化到[0, 360): [  0  90 180 270   0  90 270]
标准化到[-180, 180): [   0   90  180  -90    0   90  -90]

统计函数

基本统计量

python
import numpy as np

# 创建测试数据
np.random.seed(42)
data = np.random.normal(50, 10, 20)  # 均值50,标准差10的正态分布
print("测试数据:")
print(data)
print()

# 基本统计量
print(f"平均值 np.mean(): {np.mean(data):.2f}")
print(f"中位数 np.median(): {np.median(data):.2f}")
print(f"标准差 np.std(): {np.std(data):.2f}")
print(f"方差 np.var(): {np.var(data):.2f}")
print(f"最小值 np.min(): {np.min(data):.2f}")
print(f"最大值 np.max(): {np.max(data):.2f}")
print(f"范围 np.ptp(): {np.ptp(data):.2f}")  # peak to peak
print(f"总和 np.sum(): {np.sum(data):.2f}")
print(f"乘积 np.prod(): {np.prod(data):.2e}")
print()

# 分位数
percentiles = [25, 50, 75, 90, 95]
print("分位数:")
for p in percentiles:
    value = np.percentile(data, p)
    print(f"  {p}%分位数: {value:.2f}")

输出结果:

测试数据:
[54.96714153 64.86122569 64.76885381 52.23372036 47.34039287 49.73203647
 56.2107513  49.65142404 46.38895758 47.06651113 65.30378733 65.68660102
 51.32424518 39.48885394 56.84136338 55.23211949 53.19891788 42.36548819
 64.58941131 43.75872113]

平均值 np.mean(): 53.94
中位数 np.median(): 53.60
标准差 np.std(): 8.60
方差 np.var(): 73.98
最小值 np.min(): 39.49
最大值 np.max(): 65.69
范围 np.ptp(): 26.20
总和 np.sum(): 1078.88
乘积 np.prod(): 1.26e+35

分位数:
  25%分位数: 47.20
  50%分位数: 53.60
  75%分位数: 60.43
  90%分位数: 64.82
  95%分位数: 65.49

多维数组统计

python
import numpy as np

# 创建二维数组
array_2d = np.random.randint(1, 10, (4, 5))
print("二维数组:")
print(array_2d)
print()

# 全局统计
print(f"全局平均值: {np.mean(array_2d):.2f}")
print(f"全局标准差: {np.std(array_2d):.2f}")
print()

# 按轴统计
print("按行统计(axis=1):")
print(f"  每行平均值: {np.mean(array_2d, axis=1)}")
print(f"  每行最大值: {np.max(array_2d, axis=1)}")
print(f"  每行最小值: {np.min(array_2d, axis=1)}")
print()

print("按列统计(axis=0):")
print(f"  每列平均值: {np.mean(array_2d, axis=0)}")
print(f"  每列最大值: {np.max(array_2d, axis=0)}")
print(f"  每列最小值: {np.min(array_2d, axis=0)}")
print()

# 累积统计
print("累积和 np.cumsum():")
print(np.cumsum(array_2d, axis=1))  # 按行累积
print()

print("累积乘积 np.cumprod():")
print(np.cumprod(array_2d, axis=0))  # 按列累积

相关性和协方差

python
import numpy as np

# 创建相关的数据
np.random.seed(42)
x = np.random.normal(0, 1, 100)
y = 2 * x + np.random.normal(0, 0.5, 100)  # y与x相关
z = np.random.normal(0, 1, 100)  # z与x、y无关

data = np.column_stack([x, y, z])
print(f"数据形状: {data.shape}")
print("前5行数据:")
print(data[:5])
print()

# 相关系数矩阵
corr_matrix = np.corrcoef(data.T)
print("相关系数矩阵:")
print(corr_matrix)
print()

# 协方差矩阵
cov_matrix = np.cov(data.T)
print("协方差矩阵:")
print(cov_matrix)
print()

# 两个变量之间的相关系数
corr_xy = np.corrcoef(x, y)[0, 1]
print(f"x和y的相关系数: {corr_xy:.3f}")
print(f"x和z的相关系数: {np.corrcoef(x, z)[0, 1]:.3f}")
print(f"y和z的相关系数: {np.corrcoef(y, z)[0, 1]:.3f}")

线性代数

基本矩阵运算

python
import numpy as np

# 创建矩阵
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
B = np.array([[9, 8, 7], [6, 5, 4], [3, 2, 1]])
v = np.array([1, 2, 3])

print("矩阵A:")
print(A)
print("矩阵B:")
print(B)
print("向量v:", v)
print()

# 矩阵乘法
print("矩阵乘法 A @ B:")
print(A @ B)
print()

print("矩阵乘法 np.dot(A, B):")
print(np.dot(A, B))
print()

# 矩阵与向量乘法
print("矩阵向量乘法 A @ v:")
print(A @ v)
print()

# 转置
print("A的转置:")
print(A.T)
print()

# 迹(对角线元素之和)
print(f"A的迹: {np.trace(A)}")
print(f"B的迹: {np.trace(B)}")

输出结果:

矩阵A:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
矩阵B:
[[9 8 7]
 [6 5 4]
 [3 2 1]]
向量v: [1 2 3]

矩阵乘法 A @ B:
[[ 30  24  18]
 [ 84  69  54]
 [138 114  90]]

矩阵乘法 np.dot(A, B):
[[ 30  24  18]
 [ 84  69  54]
 [138 114  90]]

矩阵向量乘法 A @ v:
[14 32 50]

A的转置:
[[1 4 7]
 [2 5 8]
 [3 6 9]]

A的迹: 15
B的迹: 15

高级线性代数运算

python
import numpy as np

# 创建可逆矩阵
A = np.array([[2, 1, 1], [1, 3, 2], [1, 0, 0]])
print("矩阵A:")
print(A)
print()

# 行列式
det_A = np.linalg.det(A)
print(f"行列式 det(A): {det_A:.3f}")
print()

# 矩阵的逆
if det_A != 0:
    A_inv = np.linalg.inv(A)
    print("A的逆矩阵:")
    print(A_inv)
    print()
    
    # 验证 A * A^(-1) = I
    identity = A @ A_inv
    print("A @ A^(-1) (应该是单位矩阵):")
    print(identity)
    print()

# 特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
print("特征值:")
print(eigenvalues)
print("特征向量:")
print(eigenvectors)
print()

# 矩阵的秩
rank_A = np.linalg.matrix_rank(A)
print(f"矩阵的秩: {rank_A}")
print()

# 奇异值分解
U, s, Vt = np.linalg.svd(A)
print("奇异值分解:")
print(f"U形状: {U.shape}")
print(f"奇异值: {s}")
print(f"Vt形状: {Vt.shape}")

解线性方程组

python
import numpy as np

# 解线性方程组 Ax = b
# 例如:2x + y + z = 8
#      x + 3y + 2z = 20
#      x + 0y + 0z = 2

A = np.array([[2, 1, 1], [1, 3, 2], [1, 0, 0]])
b = np.array([8, 20, 2])

print("系数矩阵A:")
print(A)
print("常数向量b:", b)
print()

# 使用 solve 求解
x = np.linalg.solve(A, b)
print("解向量x:", x)
print()

# 验证解
verification = A @ x
print("验证 A @ x:", verification)
print("原始 b:", b)
print("误差:", np.abs(verification - b))
print()

# 最小二乘解(当方程组超定时)
# 添加一个额外的方程使系统超定
A_over = np.array([[2, 1, 1], [1, 3, 2], [1, 0, 0], [0, 1, 1]])
b_over = np.array([8, 20, 2, 5])

print("超定系统:")
print("A_over:")
print(A_over)
print("b_over:", b_over)

# 最小二乘解
x_lstsq = np.linalg.lstsq(A_over, b_over, rcond=None)[0]
print("最小二乘解:", x_lstsq)

# 计算残差
residual = A_over @ x_lstsq - b_over
print("残差:", residual)
print(f"残差平方和: {np.sum(residual**2):.6f}")

复数运算

复数基础

python
import numpy as np

# 创建复数数组
complex_array = np.array([1+2j, 3-4j, 5+0j, 0+6j])
print("复数数组:", complex_array)
print("数据类型:", complex_array.dtype)
print()

# 复数的属性
print("实部 np.real():", np.real(complex_array))
print("虚部 np.imag():", np.imag(complex_array))
print("模长 np.abs():", np.abs(complex_array))
print("相位角 np.angle():", np.angle(complex_array))
print("共轭 np.conj():", np.conj(complex_array))
print()

# 复数运算
z1 = 3 + 4j
z2 = 1 - 2j

print(f"z1 = {z1}")
print(f"z2 = {z2}")
print(f"z1 + z2 = {z1 + z2}")
print(f"z1 * z2 = {z1 * z2}")
print(f"z1 / z2 = {z1 / z2}")
print(f"|z1| = {abs(z1)}")
print(f"z1* = {np.conj(z1)}")

输出结果:

复数数组: [1.+2.j 3.-4.j 5.+0.j 0.+6.j]
数据类型: complex128

实部 np.real(): [1. 3. 5. 0.]
虚部 np.imag(): [ 2. -4.  0.  6.]
模长 np.abs(): [2.23606798 5.         5.         6.        ]
相位角 np.angle(): [ 1.10714871 -0.92729522  0.          1.57079633]
共轭 np.conj(): [1.-2.j 3.+4.j 5.-0.j 0.-6.j]

z1 = (3+4j)
z2 = (1-2j)
z1 + z2 = (4+2j)
z1 * z2 = (11+2j)
z1 / z2 = (-1+2j)
|z1| = 5.0
z1* = (3-4j)

广播机制

理解广播

python
import numpy as np

# 不同形状数组的运算
array_2d = np.array([[1, 2, 3], [4, 5, 6]])
array_1d = np.array([10, 20, 30])
scalar = 100

print("二维数组:")
print(array_2d)
print(f"形状: {array_2d.shape}")
print()

print("一维数组:", array_1d)
print(f"形状: {array_1d.shape}")
print()

print(f"标量: {scalar}")
print()

# 广播运算
print("二维数组 + 一维数组:")
result_2d_1d = array_2d + array_1d
print(result_2d_1d)
print(f"结果形状: {result_2d_1d.shape}")
print()

print("二维数组 + 标量:")
result_2d_scalar = array_2d + scalar
print(result_2d_scalar)
print(f"结果形状: {result_2d_scalar.shape}")
print()

# 列向量广播
column_vector = np.array([[1], [10]])
print("列向量:")
print(column_vector)
print(f"形状: {column_vector.shape}")

print("二维数组 * 列向量:")
result_col = array_2d * column_vector
print(result_col)
print(f"结果形状: {result_col.shape}")

输出结果:

二维数组:
[[1 2 3]
 [4 5 6]]
形状: (2, 3)

一维数组: [10 20 30]
形状: (3,)

标量: 100

二维数组 + 一维数组:
[[11 22 33]
 [14 25 36]]
结果形状: (2, 3)

二维数组 + 标量:
[[101 102 103]
 [104 105 106]]
结果形状: (2, 3)

列向量:
[[ 1]
 [10]]
形状: (2, 1)
二维数组 * 列向量:
[[ 1  2  3]
 [40 50 60]]
结果形状: (2, 3)

实际应用示例

示例1:信号处理

python
import numpy as np

# 生成信号
t = np.linspace(0, 1, 1000)  # 时间轴
frequency1 = 5  # 5Hz
frequency2 = 10  # 10Hz

# 组合信号
signal = np.sin(2 * np.pi * frequency1 * t) + 0.5 * np.sin(2 * np.pi * frequency2 * t)
noise = 0.2 * np.random.normal(0, 1, len(t))
noisy_signal = signal + noise

print(f"信号长度: {len(signal)}")
print(f"信号统计:")
print(f"  均值: {np.mean(noisy_signal):.4f}")
print(f"  标准差: {np.std(noisy_signal):.4f}")
print(f"  最大值: {np.max(noisy_signal):.4f}")
print(f"  最小值: {np.min(noisy_signal):.4f}")
print()

# 简单的滤波(移动平均)
window_size = 10
filtered_signal = np.convolve(noisy_signal, np.ones(window_size)/window_size, mode='same')

print("滤波后统计:")
print(f"  标准差: {np.std(filtered_signal):.4f}")
print(f"  信噪比改善: {np.std(noisy_signal)/np.std(filtered_signal):.2f}x")
print()

# 频域分析(简单的功率谱)
fft_result = np.fft.fft(signal)
power_spectrum = np.abs(fft_result)**2
frequencies = np.fft.fftfreq(len(signal), t[1] - t[0])

# 找到主要频率成分
positive_freq_idx = frequencies > 0
positive_freqs = frequencies[positive_freq_idx]
positive_power = power_spectrum[positive_freq_idx]

# 找到功率最大的频率
max_power_idx = np.argmax(positive_power)
dominant_frequency = positive_freqs[max_power_idx]

print(f"主要频率成分: {dominant_frequency:.1f} Hz")

示例2:图像处理

python
import numpy as np

# 创建简单的"图像"
image = np.random.randint(0, 256, (8, 8), dtype=np.uint8)
print("原始图像:")
print(image)
print()

# 图像统计
print(f"图像统计:")
print(f"  平均亮度: {np.mean(image):.1f}")
print(f"  亮度标准差: {np.std(image):.1f}")
print(f"  最亮像素: {np.max(image)}")
print(f"  最暗像素: {np.min(image)}")
print()

# 图像增强
# 1. 对比度拉伸
min_val, max_val = np.min(image), np.max(image)
stretched = ((image - min_val) / (max_val - min_val) * 255).astype(np.uint8)

print("对比度拉伸后:")
print(f"  新的范围: {np.min(stretched)} - {np.max(stretched)}")
print()

# 2. 直方图均衡化(简化版)
histogram, bins = np.histogram(image.flatten(), bins=256, range=(0, 256))
cdf = np.cumsum(histogram)
cdf_normalized = (cdf - cdf.min()) * 255 / (cdf.max() - cdf.min())
cdf_normalized = cdf_normalized.astype(np.uint8)
equalized = cdf_normalized[image]

print("直方图均衡化后:")
print(f"  平均亮度: {np.mean(equalized):.1f}")
print(f"  亮度标准差: {np.std(equalized):.1f}")
print()

# 3. 简单的边缘检测(Sobel算子)
sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])

# 简化的卷积(只处理中心部分)
edges_x = np.zeros_like(image, dtype=np.float32)
edges_y = np.zeros_like(image, dtype=np.float32)

for i in range(1, image.shape[0]-1):
    for j in range(1, image.shape[1]-1):
        region = image[i-1:i+2, j-1:j+2].astype(np.float32)
        edges_x[i, j] = np.sum(region * sobel_x)
        edges_y[i, j] = np.sum(region * sobel_y)

edge_magnitude = np.sqrt(edges_x**2 + edges_y**2)
print(f"边缘强度统计:")
print(f"  平均边缘强度: {np.mean(edge_magnitude):.1f}")
print(f"  最大边缘强度: {np.max(edge_magnitude):.1f}")

示例3:金融数据分析

python
import numpy as np

# 模拟股价数据
np.random.seed(42)
days = 252  # 一年的交易日
initial_price = 100
daily_returns = np.random.normal(0.001, 0.02, days)  # 日收益率
prices = initial_price * np.cumprod(1 + daily_returns)

print(f"股价数据分析({days}个交易日):")
print(f"  初始价格: ${initial_price:.2f}")
print(f"  最终价格: ${prices[-1]:.2f}")
print(f"  总收益率: {(prices[-1]/initial_price - 1)*100:.2f}%")
print()

# 收益率统计
print("日收益率统计:")
print(f"  平均日收益率: {np.mean(daily_returns)*100:.3f}%")
print(f"  收益率标准差: {np.std(daily_returns)*100:.3f}%")
print(f"  最大单日涨幅: {np.max(daily_returns)*100:.2f}%")
print(f"  最大单日跌幅: {np.min(daily_returns)*100:.2f}%")
print()

# 风险指标
# 1. 波动率(年化)
annual_volatility = np.std(daily_returns) * np.sqrt(252)
print(f"年化波动率: {annual_volatility*100:.2f}%")

# 2. 最大回撤
running_max = np.maximum.accumulate(prices)
drawdown = (prices - running_max) / running_max
max_drawdown = np.min(drawdown)
print(f"最大回撤: {max_drawdown*100:.2f}%")

# 3. 夏普比率(假设无风险利率为2%)
risk_free_rate = 0.02
excess_returns = daily_returns - risk_free_rate/252
sharpe_ratio = np.mean(excess_returns) / np.std(excess_returns) * np.sqrt(252)
print(f"夏普比率: {sharpe_ratio:.3f}")
print()

# 移动平均线
window_short = 20  # 20日移动平均
window_long = 50   # 50日移动平均

ma_short = np.convolve(prices, np.ones(window_short)/window_short, mode='valid')
ma_long = np.convolve(prices, np.ones(window_long)/window_long, mode='valid')

print(f"技术指标:")
print(f"  当前价格: ${prices[-1]:.2f}")
print(f"  20日均线: ${ma_short[-1]:.2f}")
print(f"  50日均线: ${ma_long[-1]:.2f}")

# 简单的交易信号
if len(ma_short) > 0 and len(ma_long) > 0:
    if ma_short[-1] > ma_long[-1]:
        signal = "买入信号"
    else:
        signal = "卖出信号"
    print(f"  交易信号: {signal}")

性能优化

向量化 vs 循环

python
import numpy as np
import time

# 比较向量化和循环的性能
size = 1000000
array1 = np.random.random(size)
array2 = np.random.random(size)

# 使用循环
start_time = time.time()
result_loop = np.zeros(size)
for i in range(size):
    result_loop[i] = array1[i] * array2[i] + np.sin(array1[i])
loop_time = time.time() - start_time

# 使用向量化
start_time = time.time()
result_vectorized = array1 * array2 + np.sin(array1)
vectorized_time = time.time() - start_time

print(f"数组大小: {size:,}")
print(f"循环方法时间: {loop_time:.4f}秒")
print(f"向量化方法时间: {vectorized_time:.4f}秒")
print(f"性能提升: {loop_time/vectorized_time:.1f}x")
print(f"结果是否相同: {np.allclose(result_loop, result_vectorized)}")

本章小结

在这一章中,我们深入学习了:

  • 基本算术运算和数学函数
  • 三角函数和反三角函数
  • 统计函数和描述性统计
  • 线性代数运算
  • 复数运算
  • 广播机制
  • 实际应用示例(信号处理、图像处理、金融分析)
  • 性能优化技巧

下一步

在下一章中,我们将学习 NumPy 的高级功能,包括随机数生成、多项式、傅里叶变换等。

练习题

  1. 创建一个函数计算数组的标准化分数(z-score)
  2. 实现一个简单的移动平均滤波器
  3. 编写一个函数计算两个向量的余弦相似度
  4. 使用线性代数求解多元线性回归问题
  5. 实现一个简单的图像卷积函数

本站内容仅供学习和研究使用。