无法播放?请 点击这里 跳转到Youtube
切换视频源:

这个系列的课件会存在这里,如需要下载请参阅课件下载指南

上一章我们介绍了NumPy的重要性,并通过代码演示了一些NumPy好用的功能。从这一章起就正式开始NumPy的学习,这一章先来学习创建NumPy数组常用的函数。

首先复习一下如何创建NumPy数组:

import numpy as np
np_array = np.array([1, 2, 3])
print(type(np_array)) # <class 'numpy.ndarray'>
print(np_array.shape) # (3,)

用来创建NumPy数组常用的函数:

zero_array = np.zeros((5)) # [0. 0. 0. 0. 0.]
one_array = np.ones((4,4))
"""
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]
"""
full_array = np.full((3,3), 7)
"""
[[7 7 7]
 [7 7 7]
 [7 7 7]]
"""
empty_array = np.empty((2, 3)) # 无法预测其数值,内存里有什么就是什么
"""
[[1.94830084e-316 0.00000000e+000 0.00000000e+000]
 [0.00000000e+000 0.00000000e+000 0.00000000e+000]]
"""

Axis and Data Type

在接下去学习之前,我们也来了解一下NumPy中一些重要的概念,其中一个重要的名词叫 axis,也就是NumPy数组中的维度。axis 的数量叫做 rank,比如一个矩阵的尺寸是3×4,那么这个数组的rank就是2,代表这是个二维的矩阵,而一维的数组rank自然就是1。NumPy数组的shape则是用一个包含了所有axis长度的数组组成,而一个数组的大小(size)指的是一个数组中有多少元素,将所有axis的长度相乘即可。

zero_array = np.zeros((3, 4))
zero_array 
"""
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
"""
zero_array.shape # (3, 4)
zero_array.ndim # 2
zero_array.size # 12

每个NumPy数组由一串相同数据类型的元素组成,NumPy可用构建多种数据类型的数组。当你在创建NumPy数组时,NumPy会自动为你安排特定的数据类型,而你也能显性地定义数据类型:

int_array = np.array([1, 2])
int_array.dtype # int64
float_array = np.array([1.0, 2.0])
float_array.dtype # float64
float_array.itemsize # 每个元素的大小 8
float32_array = np.array([1, 2], dtype=np.float32)
float32_array.dtype # float64
float32_array.itemsize # 4

一个数组的形状(shape)是能被改变的,但是要保证改变之后的大小(size 元素的个数)不能变:

x = np.array([[1, 2, 3], [4, 5, 6]])
x.ndim # 2
x.shape = (6,) # Change its shape in place
x.ndim # 1

np.reshape和ravel可以创建出指向相同数据的新数组:

y = np.reshape(x, (3, 2)) # 创建形状不同的新数组,此数组指向相同的数据
y[0, 0] = 1000
print(x) # [1000, 2, 3, 4, 5, 6]
z = y.ravel() # 指向相同数组的新数组
z[0] = 2000
print(x) # [2000, 2, 3, 4, 5, 6]

如果要复制NumPy数组,可以使用copy函数创建新数组,新数据的改变不会影响原数组:

array1 = np.arange(4)
array2 = array1.copy()
array2[0] = 2000
array1 # [0, 1, 2, 3]

Arithmetic Operations

NumPy数组也支持一些常用的算数运算:

array1 = np.array([1, 2, 3, 4])
array2 = np.array([5, 6, 7, 8])
print(array1 + array2) # [6, 8, 10, 12]
print(array1 - array2) # [-4, -4, -4, -4]
print(array1 * array2) # [5, 12, 21, 32]
print(array1 / array2) # [0.2, 0.33333333, 0.42857143, 0.5]
print(array1 // array2) # [0, 0, 0, 0]
print(array1 % array2) # [1, 2, 3, 4]
print(array1 ** array2) # [1, 64, 2187, 65536]

Useful Functions

创建由随机数生成的数组:

np.random.random((5, 5)) # 创建数值在0~1之间的随机数数组
[[9.90294681e-01 6.51182438e-02 5.48551064e-02 4.13554785e-01 2.77916852e-02]
 [2.82902321e-01 3.82854818e-01 9.72110582e-01 6.41764840e-02 2.29831744e-01]
 [4.23048152e-01 8.07057740e-01 5.42399825e-01 4.56243935e-01 5.35099209e-01]
 [9.25518420e-01 6.01543526e-02 5.92246756e-01 5.86704977e-01 2.16448787e-01]
 [1.69499508e-01 2.13986897e-01 4.70516150e-04 9.32854954e-01 6.37419153e-01]]
np.random.randint(100, size=(5)) # 创建5个数值范围在0~100之间的随机整数
np.random.rand(3, 4) # 创建一个形状为(3,4),数值范围在0~1之间的矩阵
np.random.randn(10) # 创建一个长度为10,数值范围能构成正态分布(normal distribution)的数组

可以用eye函数创建一个对角线为1其他为0的矩阵:

eye_array = np.eye(4)
"""
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
"""

使用arange创建等差的数组:

np.arange(1,5) # [1, 2, 3, 4]
np.arange(1.0, 5.0) # [1.0, 2.0, 3.0, 4.0]
np.arnage(1, 5, 0.5) # (最小值, 最大值, 步长) [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5]

linspace 可以用来创建等分线段型的数据:

np.linspace(0, 5, 10) # 起点是0,终点是5,将0~5的区间内平均分为10个数据,从小到大存到一个数组中

除了用这些常见的NumPy函数创建数组,我们还能使用fromfunction函数,自定义NumPy数据的创建:

np.fromfunction(lambda i, j: i == j, (2, 3), dtype=int)
[[True, False, False],
 [False, True, False]]

np.fromfunction(lambda i, j: i + j, (2, 3), dtype=int)
[[0, 1, 2],
 [1, 2, 3]]

def my_function(z, y, x):
    return x * y + z
np.fromfunction(my_function, (3, 2, 10))
array([[[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]],

       [[ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
        [ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]],

       [[ 2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.],
        [ 2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11.]]])

本章函数整理

np.array # 创建NumPy数组
np.zeros(array_shape) # 创建只包含0的数组
np.ones(array_shape) # 创建只包含1的数组
np.full(array_shape, number) # 创建只包含一个数值的数组
np.empty(array_shape) # 创建一个不赋值的数组

np_array.shape # 包含各个维度大小的Tuple
np_array.ndim # 数据的rank数量
np_array.size # 包含元素的数量

np.array(python_list, dtype=<numpy_data_type>) # 创建指定数据类型的NumPy数组
np.reshape(original_array, new_shape) # 创建一个不同形状的数组
numpy_array.ravel() # 指向相同数据的新数组
numpy_array.copy() # 复制一个NumPy数组

np_array1 + np_array2 # 相加
np_array1 - np_array2 # 相减
np_array1 * np_array2 # 相乘
np_array1 / np_array2 # 相除
np_array1 // np_array2 # 取整除
np_array1 % np_array2 # 取余
np_array1 ** np_array2 # 幂运算

np.random.randint(number_range, size=shape) # 创建一个取值范围在0~number_range之间的数组
np.random.rand(shape) # 创建一个数值范围在0~1之间,形状为shape的数组
np.random.randn(shape) # 创建一个数值范围能形成正态分布,形状为shape的数组

np.eye(matrix_length) # 创建对角线是1,形状是(matrix_length, matrix_length)的矩阵
np.arange(min_value, max_value, step) # 创建有固定步长,取值范围在min_value和max_value之间的数组
np.linspace(start, end, items_num) # 创建一个起点是start, 终点是end,被等分成items_num数量的数组
np.fromfunction(function, numpy_array_shape) # 使用自定义函数创建numpy数组