一、列表与数组
Python的自带数据类型中是不存在数组
这一种类型的,而是自带了一种和数组相类似的列表
类型。
从某种程度上来说,列表仿佛比数组更加“强大”,因为列表里的元素可以是任意类型的;并且类似于“多维数组”的概念我们也可以用“列表套列表”的方式实现。
不过,上述所谓的“强大”在数组的眼中只不过是极度的“不规范”。我们需要一种新的数据类型数组
,来保证其中所有的元素都是数
,这样我们才可以定义元素之间的四则运算,才可以定义数组之间的向量乘法、矩阵乘法等。这些事情是一个数据类型混杂的列表所不能完成的。
我们一般使用第三方库NumPy
中定义的numpy.array
类作为我们的数组类型。
二、NumPy库的使用
导入库
NumPy库是一个第三方库,所以使用前需要先导入(大家一般将其重命名为np
)
import numpy as np
实例化一个数组对象
要生成一个数组,无非就是要知道两件事情:1.这个数组的名字是什么? 2.这个数组里面的数是什么?
所以生成一个数组最简单的方法便是数组名 = np.ndarray(列表)
其中等号的右边便是数组对象名,左边括号里填的是一个列表对象,列表里的元素就转换为数组里的元素了。
array1 = np.array([1,2,3,4])
print(array1)
[1 2 3 4]
同样地,如果要生成一个多维数组的话,我们只需要“列表套列表”就行了
list2 = [[11,12],[21,22]] #最外层列表里面又嵌套了一层列表
array2 = np.array(list2) #所以生成的是一个二维数组
print(array2)
print('array2的维度是:', array2.ndim)
[[11 12]
[21 22]]
array2的维度是: 2
list3 = [[[111,112,113],[121,122,123],[131,132,133]],
[[211,212,213],[221,222,223],[231,232,233]],
[[311,312,313],[321,322,323],[331,332,333]]] #最外层列表里面嵌套了一层列表又套了一层列表
array3 = np.array(list3) #所以生成的是一个三维数组
print(array3)
print('array3的维度是:', array3.ndim)
[[[111 112 113]
[121 122 123]
[131 132 133]]
[[211 212 213]
[221 222 223]
[231 232 233]]
[[311 312 313]
[321 322 323]
[331 332 333]]]
array3的维度是: 3
array4 = np.arange(0,16).reshape(2,2,2,2) #用arange()和reshape()函数生成一个4维数组
print(list4)
print('array4的维度是:', array4.ndim)
[[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]]
[[[ 8 9]
[10 11]]
[[12 13]
[14 15]]]]
array4的维度是: 4
NumPy对高维度的数组有着很好的支持。从上面的例子中我们可以看到数组的显示也是很直观的:不论维度有多高,它都会用方括号来严格表示层级关系,并且对于二维数组来说,它会自动排列成一个二维的表格;对于更高维的数组来说,它会把最内层的两个维度排成二维表格,然后再用中括号以区分层级。
常用的函数、属性
表一 常用库函数
函数 | 作用 |
---|---|
np.array(列表) | 通过列表创建一个数组对象 |
np.arange(起始, 结束, 步长) | 创建一个等差数组(注意区间是左闭右开的) |
np.zeros( (m, n) ) | 创建一个m 行n 列的全零数组 |
np.ones( (m, n) ) | 创建一个m 行n 列的全一数组 |
np.eye(m) | 创建一个m 阶单位方阵 |
表二 常用对象属性
属性 | 作用 |
---|---|
my_array.ndim | 返回my_array 的维数 |
my_array.size | 返回my_array 的总元素数 |
my_array.shape | 以元组形式返回my_array 的(行, 列) |
my_array.dtype | 返回my_array 中元素的数据类型 |
*注意库函数和对象属性的不同,表一中np.
是固定的,指的是numpy库
;而表二中my_array.xxx()
中的my_array
要改成你对应的数组的名字(即实例名)。
切片
我们将选出一个数组的某一行、某一列或者某一个位置上的元素的操作成为“切片”
我们先来讨论二维数组的切片:
最基本的格式是:my_array[m, n]
,其中m
和n
可以为整数
列表
还可以是冒号:
当m
和n
是整数时,表示选取m
行n
列的那个数。
当m
和n
其中一个是冒号的时候,表明选中对应的所有行或列。例如my_array[ :, n]
表示选择整个第n
列
特别需要注意的是,当m
和n
是列表时,设m
和n
的长度是k
,则我们选取的是k
个坐标分别为(mi, ni)的散点(而不是k2个交叉点)如:
arr = np.arange(1,10).reshape(3,3)
print('切片前:')
print(arr)
m = [0,1]
n = [1,2]
print('切片后:')
print(arr[m, n])
切片前:
[[1 2 3]
[4 5 6]
[7 8 9]]
切片后:
[2 6]
我们可以看到,我们选取了的是位于(0,1)和(1,2)位置的两个数2
和6
,而不是位于0行
1行
和1列
2列
交叉点处的4个数2
,3
,5
,6
那么如果我想选出指定行和指定列的交叉点所在的数该怎么办呢?
我们需要通过“二次切片”来实现。如:
print('二次切片:')
print(arr[ m, : ][ :, n ]
二次切片:
[[2 3]
[5 6]]
这时候我们就得到了0行
1行
和1列
2列
交叉点处的4个数2
,3
,5
,6
三、小结
这一期博客我们首先讨论了数组与列表的关系及异同。数组的特点在于其中的元素的数据类型是统一的,这使得我们能够方便地进行后期的数据处理。
在Python中我们一般使用NumPy库来创建数组,它给我们提供了很多的库函数、方法、属性,让我们在对数组进行操作的时候更加方便。
然后我们介绍了如何创建一个数组,并且也看到了NumPy对高维度的数组有着很好的支持。
我们还对常用的函数、属性总结成了两个表格,方便大家查阅。
最后我们介绍了“切片”这一对于数组来说最基本也是最重要的操作。
关于数组的更多的操作和例子我们放到下一期博客中,通过讲解书上的例题和课后习题来一起讨论。
如果你正在学习/复习“数据分析与智能计算”这门课,或者是想要入门大数据、人工智能的同学,欢迎订阅本专栏~
觉得有用的话,不要忘了点赞、关注、分享哦~大家多多包涵,有任何问题欢迎指正、讨论。
本文基于CC-BY-NC-SA 4.0协议,请规范转载。
(博客看累了?去我的B站瞧一瞧?)