python气象信息系统工程 第三章

第3章 NumPy:Python数值计算之源

3.3 多维数组的特征

3.3.2 轴与维度

1
2
3
4
5
6
7
8
9
10
11
#一维至三维数组的创建
import numpy as np
vector = np.array([1, 2, 3])
matrix = np.array([[1, 2, 3], [4, 5, 6]])
tensor = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])
print('\n---向量---\n')
print(vector) # 向量
print('\n---矩阵---\n')
print(matrix) # 矩阵
print('\n---张量---\n')
print(tensor) # 张量
---向量---

[1 2 3]

---矩阵---

[[1 2 3]
 [4 5 6]]

---张量---

[[[1 2 3]
  [4 5 6]]

 [[1 2 3]
  [4 5 6]]]
1
2
3
4
# 查看数组的相关维度属性
print(matrix.ndim)
print(matrix.shape)
print(matrix.size)
2
(2, 3)
6

3.4 创建N维数组

3.4.1 np.array()——直接创建

1
2
3
4
5
6
7
8
9
10
# 使用np.array()创建数组
import numpy as np

a = np.array([1, 2, 3])
b = np.array([1, 2, 3], dtype=np.float_)

print(a)
print(a.dtype)
print(b)
print(b.dtype)
[1 2 3]
int64
[1. 2. 3.]
float64

3.4.2 np.zeros()——根据shape参数创建数组

1
2
3
4
5
6
7
8
# 使用np.zeros()创建数组
import numpy as np
a = np.zeros((2, 3))
b = np.zeros((2, 3), dtype=np.int_)
print(a)
print(a.dtype)
print(b)
print(b.dtype)
[[0. 0. 0.]
 [0. 0. 0.]]
float64
[[0 0 0]
 [0 0 0]]
int64

3.4.3 np.arange()——根据起点、终点和步长创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 使用np.arange()创建数组
import numpy as np
a = np.arange(5)
b = np.arange(3, 5)
c = np.arange(3, 5, 0.5)
d = np.arange(3, 5, 0.5, dtype=np.float32)
print(a)
print(a.dtype)
print(b)
print(b.dtype)
print(c)
print(c.dtype)
print(d)
print(d.dtype)
[0 1 2 3 4]
int64
[3 4]
int64
[3.  3.5 4.  4.5]
float64
[3.  3.5 4.  4.5]
float32

3.4.4 np.linspace()——根据起点、终点和元素数量创建

1
2
3
4
5
6
7
8
# 使用np.linspace()创建数组
import numpy as np
a = np.linspace(3, 5, 4)
b = np.linspace(3, 5, 4, dtype=np.float32)
print(a)
print(a.dtype)
print(b)
print(b.dtype)
[3.         3.66666667 4.33333333 5.        ]
float64
[3.        3.6666667 4.3333335 5.       ]
float32

3.4.5 np.random.randn()——生成符合标准正态分布的随机N维数组

1
2
3
4
# 使用np.random.randn()创建数组
import numpy as np
a = np.random.randn(3, 3)
print(a)
[[ 0.22266599 -1.8125634  -0.64368513]
 [-0.26829134  1.26109384 -0.72892426]
 [-2.33863096 -0.39083497  0.61973089]]

3.5 数组间运算和广播运算

1
2
3
4
5
6
7
8
#形状相同的数组之间的计算
import numpy as np
a = np.array([1, 2, 3])
b = np.array([2, 4, 6])
print(a + b)
print(a - b)
print(a * b)
print(a / b)
[3 6 9]
[-1 -2 -3]
[ 2  8 18]
[0.5 0.5 0.5]
1
2
3
4
5
6
7
#对于N维数组和标量的广播运算
import numpy as np
a = np.array([1, 2, 3])
print(a + 2)
print(a - 2)
print(a * 2)
print(a / 2)
[3 4 5]
[-1  0  1]
[2 4 6]
[0.5 1.  1.5]
1
2
3
4
5
6
7
8
9
10
11
12
13
# 对于一维数组和二维数组之间的运算
import numpy as np
a = np.array([1, 2, 3])
b = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0, 1, 2],
[3, 4, 5]])
print(a.shape)
print(b.shape)
c = a + b
print(c)
print(c.shape)
(3,)
(5, 3)
[[ 2  4  6]
 [ 5  7  9]
 [ 8 10 12]
 [ 1  3  5]
 [ 4  6  8]]
(5, 3)
1
2
3
4
5
6
7
8
9
10
11
12
13
# 对于两个维度相同的N维数组之间的运算
import numpy as np
a = np.array([[1, 2, 3]])
b = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0, 1, 2],
[3, 4, 5]])
print(a.shape)
print(b.shape)
c = a + b
print(c)
print(c.shape)
(1, 3)
(5, 3)
[[ 2  4  6]
 [ 5  7  9]
 [ 8 10 12]
 [ 1  3  5]
 [ 4  6  8]]
(5, 3)
1
2
3
4
5
6
7
8
# 将向量化用于两个场之间的运算
import numpy as np
t1 = np.array([[10.5, 13, 16.3],
[12, 12.5, 15.5]])
t2 = np.array([[8.4, 7.2, 5.5],
[7.1, 7.0, 6.0]])
t_mean = (t1 + t2) / 2
print(t_mean)
[[ 9.45 10.1  10.9 ]
 [ 9.55  9.75 10.75]]
1
2
3
4
5
# 多位数组的比较运算
import numpy as np
t1 = np.array([[10.5, 13, 16.3],
[12, 12.5, 15.5]])
print(t1 > 12)
[[False  True  True]
 [False  True  True]]
1
2
3
4
5
6
# 多维数组的逻辑运算
import numpy as np
t1 = np.array([[10.5, 13, 16.3],
[12, 12.5, 15.5]])
print((t1 > 12)| (t1 < 11))
print((t1 > 12)& (t1 < 13))
[[ True  True  True]
 [False  True  True]]
[[False False False]
 [False  True False]]

3.6 多维数组的索引和切片

3.6.1 普通索引和切片

1
2
3
4
5
6
7
8
9
10
# 通过索引获得需要的值
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a[0], '第一个维度索引为0的序列')
print(a[:, 0], '第二个维度索引为0的序列')
print(a[:2], '第一个维度索引为0、1的序列')
print(a[:2, :2], '第一个维度索引为0、1且第二个维度索引为0、1的序列')
print(a[::2, :], '第一个维度索引间隔2的序列')
[1 2 3] 第一个维度索引为0的序列
[1 4 7] 第二个维度索引为0的序列
[[1 2 3]
 [4 5 6]] 第一个维度索引为0、1的序列
[[1 2]
 [4 5]] 第一个维度索引为0、1且第二个维度索引为0、1的序列
[[1 2 3]
 [7 8 9]] 第一个维度索引间隔2的序列
1
2
3
4
5
6
7
# 用于对索引位置赋值
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
a[1, 1] = 0
print(a)
[[1 2 3]
 [4 0 6]
 [7 8 9]]
1
2
3
4
5
6
7
# 应用广播运算使用标量对切片赋值
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
a[::2, :] = 0
print(a)
[[0 0 0]
 [4 5 6]
 [0 0 0]]
1
2
3
4
5
6
# 将数组所有元素修改为特定值
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
a[:] = 0

3.6.2 高级索引

1
2
3
4
5
6
7
# 利用逻辑索引取出符合条件的元素
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a[a>4])
print(a[(a>4) & (a<8)])
[5 6 7 8 9]
[5 6 7]
1
2
3
4
5
6
7
# 花式索引
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a[[0, 2]])
print(a[[0, 2], [1, 2]])
[[1 2 3]
 [7 8 9]]
[2 9]

3.7 N维数组对象的方法

3.7.1 reshape()——改变数组形状

1
2
3
4
5
6
7
8
9
10
11
# 尝试修改一个一维向量的形状
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
print(a)
print(a.shape)
b = a.reshape(2, 3)
print(b)
print(b.shape)
c = a.reshape(6, 1)
print(c)
print(c.shape)
[1 2 3 4 5 6]
(6,)
[[1 2 3]
 [4 5 6]]
(2, 3)
[[1]
 [2]
 [3]
 [4]
 [5]
 [6]]
(6, 1)
1
2
3
4
5
6
7
8
# 利用特殊值-1自动计算长度
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
print(a)
print(a.shape)
b = a.reshape(2, -1)
print(b)
print(b.shape)
[1 2 3 4 5 6]
(6,)
[[1 2 3]
 [4 5 6]]
(2, 3)
1
2
3
4
5
6
7
8
9
10
# 利用特殊值-1展开数组
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a)
print(a.shape)
b = a.reshape(-1)
print(b)
print(b.shape)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
(3, 3)
[1 2 3 4 5 6 7 8 9]
(9,)

3.7.2 transpose()——交换轴

1
2
3
4
5
6
# 默认参数下的交换
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a.transpose())
[[1 4 7]
 [2 5 8]
 [3 6 9]]
1
2
3
4
5
6
# 指定顺序的交换
import numpy as np
a = np.zeros((10, 15, 25))
print(a.shape)
b = a.transpose(1, 0, 2)
print(b.shape)
(10, 15, 25)
(15, 10, 25)

3.7.3 mean()——计算平均值

1
2
3
4
5
6
7
8
9
10
# 计算数组均值
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a.mean())
print(a.mean(axis=(0, 1)))
print('由于数组a只有两个维度,所以axis=(0, 1)等价于对所有维度取平均值')
print(a.mean(axis=0))
print(a.mean(axis=1))
5.0
5.0
由于数组a只有两个维度,所以axis=(0, 1)等价于对所有维度取平均值
[4. 5. 6.]
[2. 5. 8.]

3.7.4 sum()——计算元素和

1
2
3
4
5
6
7
8
# 计算数组元素之和
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a.sum())
print(a.sum(axis=(0, 1)))
print(a.sum(axis=0))
45
45
[12 15 18]
1
2
3
4
5
6
7
8
# 计算数组元素标准差
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a.std())
print(a.std(axis=(0, 1)))
print(a.std(axis=0))
2.581988897471611
2.581988897471611
[2.44948974 2.44948974 2.44948974]

3.7.6 min()——取最小值/max()——取最大值

1
2
3
4
5
6
7
8
9
10
11
# 获取元素最大和最小值
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a.max())
print(a.max(axis=(0, 1)))
print(a.max(axis=0))
print(a.min())
print(a.min(axis=(0, 1)))
print(a.min(axis=0))
9
9
[7 8 9]
1
1
[1 2 3]

3.7.7 round()——进行四舍五入

1
2
3
4
5
6
7
# 对数组四舍五入
import numpy as np
a = np.array([[1.12, 2.25, 2.15],
[4.03, 5.48, 6.75],
[7.25, 7.35, 9.22]])
print(a.round())
print(a.round(1))
[[1. 2. 2.]
 [4. 5. 7.]
 [7. 7. 9.]]
[[1.1 2.2 2.2]
 [4.  5.5 6.8]
 [7.2 7.4 9.2]]

3.7.8 dot()——执行向量/矩阵乘法

1
2
3
4
5
6
7
8
9
10
11
# 矩阵乘法
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([[1, 2],
[3, 4],
[5, 6]])
print('shape_a=', a.shape)
print('shape_b=', b.shape)
c = a.dot(b) # A×B
print(c)
shape_a= (2, 3)
shape_b= (3, 2)
[[22 28]
 [49 64]]
1
2
3
4
5
6
#向量乘法
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = a.dot(b)
print(c)
32

3.7.9 astype()——转换数值类型

1
2
3
4
5
6
7
8
9
# 使用astype()方法根据需要生成新数据类型的多维数组
import numpy as np
a = np.array([1.2, 2.4, 3.5])
print(a.dtype)
b = a.astype(np.float32)
print(b.dtype)
c = a.astype(np.int)
print(c.dtype)
print(c)
float64
float32
int64
[1 2 3]

3.10 文件读写

3.10.1 文本格式文件的读取

1
2
3
4
5
6
7
8
#读取没有列明的csv文件
import numpy as np
a = np.genfromtxt('/home/mw/project/save_csv.csv', delimiter=',')
print(a)
# 读取空格作为分隔符的文件
import numpy as np
a = np.genfromtxt('/home/mw/project/save_txt.txt', delimiter=' ')
print(a)
[[10.5 13.  16.3]
 [12.  12.5 15.5]]
[[10.5 13.  16.3]
 [12.  12.5 15.5]]

3.10.2 文本格式文件的写入

1
2
3
4
5
6
7
8
9
10
# 保存为csv文件
import numpy as np
a = np.array([[10.5, 13, 16.3],
[12, 12.5, 15.5]])
np.savetxt('save_csv.csv', a, delimiter=',')
# 保存为空格作为分隔符的txt文件
import numpy as np
a = np.array([[10.5, 13, 16.3],
[12, 12.5, 15.5]])
np.savetxt('save_txt.txt', a, delimiter=' ')

3.10.3 顺序二进制文件的读写

1
2
3
4
5
6
# 二进制文件的读入
import numpy as np
a = np.fromfile('/home/mw/project/binary_raw.bin', dtype=np.float64)
print(a)
a = a.reshape((3, 3))
print(a)
[10.5 13.  16.3 12.  12.5 15.5 11.3 12.2 15.4]
[[10.5 13.  16.3]
 [12.  12.5 15.5]
 [11.3 12.2 15.4]]
1
2
3
4
5
6
7
# 二进制文件的写入
import numpy as np
a = np.array([[10.5, 13, 16.3],
[12, 12.5, 15.5],
[11.3, 12.2, 15.4]])
print(a.dtype) #输出结果为float64
a.tofile('binary_raw.bin')
float64