NumPy总结(二):基本的NumPy数组操作
注:转载请注明出处
文章目录
1 NumPy数组的属性
(1)随机种子值: np.random.seed( ):使用NumPy的随机数生成器时进行设置,以确保每次都可以生成同样的随机数组。
np.random.seed(0) #设置随机数种子
x1 = np.random.randint(10, size = 6) #一维数组
x2 = np.random.randint(10, size = (3, 4)) #二维数组
x3 = np.random.randint(10, size = (3, 4, 5)) #二维数组
(2)数组的维度:.ndim;每个维度的大小:.shape;数组的总大小:.size。
print('x3 ndim: ', x3.ndim)
print('x3 shape: ', x3.shape)
print('x3 size: ', x3.size)
x3 ndim: 3
x3 shape: (3, 4, 5)
x3 size: 60
(3)数组的数据类型: .dtype。
print('x3 type: ', x3.dtype)
x3 type: int32
(4)每个元素字节大小: .itemsize;总字节大小: .nbytes
print('x3 itemsize: ', x3.itemsize)
print('x3 nbytes: ', x3.nbytes)
x3 itemsize: 4
x3 nbytes: 240
2 数组索引:获取单个元素
(1)正向索引单个元素。
print(x1[0])
5
(2)从末尾索引单个元素。
print(x1[-1])
9
(3)多维数组索引用逗号隔开。
print(x2[1, 0])
print(x3[2, 1, 0])
7
7
也可直接修改元素的值
x2[1, 0] = 1
print(x2)
[[3 5 2 4]
[1 6 8 8]
[1 6 7 7]]
注意
NumPy数组是固定类型的,所以将一个浮点值插入一个整型数组时,浮点值会被截短成整型,如:
x2[1, 0] = 3.14
print(x2)
[[3 5 2 4]
[3 6 8 8]
[1 6 7 7]]
3 数组切片(slice):获取子数组
切片符号通常用冒号(:)表示。NumPy切片语法和Python列表切片的语法相同。标准形式为:
x[start:stop:stop]
如果以上3个参数都未指定,那么它们会被设置为默认值:
- start = 0
- stop = 维度的大小(size of dimension)
- step = 1
(1)对于一维子数组。
x = np.arange(10)
x[:5] #前五个元素
array([0, 1, 2, 3, 4])
x[5:] #5之后的元素
array([5, 6, 7, 8, 9])
x[::2] #每隔一个元素
array([0, 2, 4, 6, 8])
x[::-1] #逆序
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
x[5::-2] #从索引5开始每隔一个元素逆序
array([5, 3, 1])
(2)对于多维子数组。
多维情况下每一维与一维相同,不同维之间用逗号分隔。
x2[:2, :3] #前两行,前三列
array([[3, 5, 2],
[3, 6, 8]])
x2[:, ::2] #所有行,每隔一列
array([[3, 2],
[3, 8],
[1, 7]])
x2[::-1, ::-1] #逆序
array([[7, 7, 6, 1],
[8, 8, 6, 3],
[4, 2, 5, 3]])
(3)获取数组的行和列。
常见的需求是获取数组的单行和单列,可以通过将索引和切片组合来实现此功能,用一个冒号(:)来表示空切片。
print(x2[:, 0]) #第一列
print(x2[0, :]) #第一行
[3 3 1]
[3 5 2 4]
在获取行时,处于简洁性考虑,可以省略空的切片。如:
print(x2[0]) #等价于x2[0, :]
[3 5 2 4]
注意
1.对于切片而言,NumPy数组切片返回的是数组数据的视图,改变切片的值,则原数组的值也会相应改变,而Python列表返回的是副本,区别如:
list1 = [1, 2, 3, 4, 5]
array1 = np.array(list1)
sub_list = list1[1:4]
sub_array = array1[1:4]
sub_list[0] = 99
sub_array[0] = 99
print('Python列表改变后:', list1)
print('NumPy数组改变后:', array1)
Python列表改变后: [1, 2, 3, 4, 5]
NumPy数组改变后: [ 1 99 3 4 5]
有时不希望如此,则可使用.copy()方法进行复制,如:
list1 = [1, 2, 3, 4, 5]
array1 = np.array(list1)
sub_array = array1[1:4].copy()
sub_array[0] = 99
print('NumPy数组改变后:', array1)
NumPy数组改变后: [1 2 3 4 5]
4 数组的变形
数组的变形通过reshape()函数来实现。
如将数字1~9放入3×3的矩阵中,可采用如下方法:
grid = np.arange(1, 10).reshape((3, 3))
print(grid)
[[1 2 3]
[4 5 6]
[7 8 9]]
注意
1.对于reshape()函数,原始数组的大小必须和**变形后的数组大小(即size)**一致。
另外,还有常见的用法,将一维数组变为二维的行或列。这可以通过reshape()函数来实现,也可通过newaxis关键字来实现。
x = np.array([1, 2, 3])
print(x.reshape((1,3))) #通过变形变为行向量
print(x[np.newaxis,:]) #通过newaxis变为行向量
print(x[:, np.newaxis]) #通过newaxis变为列向量
[[1 2 3]]
[[1 2 3]]
[[1]
[2]
[3]]
5 数组的拼接和分裂
5.1 数组的拼接
(1)np.concatenate
拼接两个数组为一个:
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
x_y = np.concatenate([x, y])
print(x_y)
[1 2 3 4 5 6]
拼接多个数组为一个:
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
z = np.array([7, 8, 9])
x_y_z = np.concatenate([x, y, z])
print(x_y_z)
[1 2 3 4 5 6 7 8 9]
对于二维数组进行拼接:
x = np.array([[1, 2, 3], [1, 2, 3]])
y = np.array([[4, 5, 6], [4, 5, 6]])
x_y = np.concatenate([x, y])
print(x_y)
[[1 2 3]
[1 2 3]
[4 5 6]
[4 5 6]]
对于二维数组沿特定轴进行拼接:
x = np.array([[1, 2, 3], [1, 2, 3]])
y = np.array([[4, 5, 6], [4, 5, 6]])
x_y = np.concatenate([x, y], axis = 1) #axis从0开始索引
print(x_y)
[[1 2 3 4 5 6]
[1 2 3 4 5 6]]
(2)np.vstack(垂直栈)和np.hstack(水平栈)
当沿着固定维度处理数据时,使用np.vstack(垂直栈)和np.hstack水平栈会更简洁。
#vstack
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(np.vstack([x, y]))
[[1 2 3]
[4 5 6]]
#hstack
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(np.hstack([x, y]))
[1 2 3 4 5 6]
此外,还有np.dstack沿着第三个维度拼接数组:
#dstack
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(np.dstack([x, y]))
[[[1 4]
[2 5]
[3 6]]]
5.2 数组的分裂
具体思想为设置一个索引列表作为参数,记录分裂点的位置:
(1)np.split
x = np.arange(1, 10)
x1, x2, x3 = np.split(x, [3, 5]) #此时3,5即为分裂点的位置
print(x1, x2, x3)
[1 2 3] [4 5] [6 7 8 9]
(2)np.hsplit
x = np.arange(16).reshape((4, 4))
upper, lower = np.hsplit(x, [2])
print('up:',upper, '\n','low:',lower)
up: [[ 0 1]
[ 4 5]
[ 8 9]
[12 13]]
low: [[ 2 3]
[ 6 7]
[10 11]
[14 15]]
(3)np.vsplit
x = np.arange(16).reshape((4, 4))
left, right = np.vsplit(x, [2])
print('left:',left, '\n','right:',right)
left: [[0 1 2 3]
[4 5 6 7]]
right: [[ 8 9 10 11]
[12 13 14 15]]
同样,np.dsplit会将数组沿着第三个维度分裂(这在三维数组中会用到,低维数组中不会用到)
以上便是NumPy最基础的概述以及其创建方法,本节的Jupyter notebook代码与readme文件已上传至GitHub,此外,还有英文版的《PythonDataScienceHandbook》的Jupyter notebook文件也已经开源,Github代码点击则可查阅。
相关参考资料
- bilibili视频可参考:
数据分析——numpy、pandas、matplotlib
莫烦 Python 数据处理教程- 相关书籍可参考:
《Python数据科学手册》