数学运算和函数
在这一章中,我们将深入学习 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 的高级功能,包括随机数生成、多项式、傅里叶变换等。
练习题
- 创建一个函数计算数组的标准化分数(z-score)
- 实现一个简单的移动平均滤波器
- 编写一个函数计算两个向量的余弦相似度
- 使用线性代数求解多元线性回归问题
- 实现一个简单的图像卷积函数