数组的创建与操作(参照刘顺祥著《从零开始学数据分析与挖掘》)
1.数组的创建
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数说明

numpy数组属性 numpy创建数组 NumPy 从已有的数组创建数组
numpy数据类型
# 导入模块,并重命名为np
import numpy as np
# 单个列表创建一维数组
arr1 = np.array([3,10,8,7,34,11,28,72])
# 嵌套元组创建二维数组
arr2 = np.array(((8.5,6,4.1,2,0.7),(1.5,3,5.4,7.3,9),(3.2,3,3.8,3,3),(11.2,13.4,15.6,17.8,19)))
print('一维数组:\n',arr1)
print('二维数组:\n',arr2)
# 运行结果
一维数组:
[ 3 10 8 7 34 11 28 72]
二维数组:
[[ 8.5 6. 4.1 2. 0.7]
[ 1.5 3. 5.4 7.3 9. ]
[ 3.2 3. 3.8 3. 3. ]
[11.2 13.4 15.6 17.8 19. ]]
2.数组元素的获取
注意:如果要在数组中取出某几行和某几列需使用ix_函数
# 一维数组元素的获取
print(arr1[[2,3,5,7]])
# 二维数组元素的获取
# 第2行第3列元素
print(arr2[1,2])
# 第3行所有元素
print(arr2[2,:])
# 第2列所有元素
print(arr2[:,1])
# 第2至4行,2至5行
print(arr2[1:4,1:5])
# 第一行、最后一行和第二列、第四列构成的数组
print(arr2[[0,-1],[1,3]])
# 第一行、最后一行和第一列、第三列、第四列构成的数组
print(arr2[[0,-1],[1,2,3]])
# 第一行、最后一行和第二列、第四列构成的数组
print(arr2[np.ix_([0,-1],[1,3])])
# 第一行、最后一行和第一列、第三列、第四列构成的数组
print(arr2[np.ix_([0,-1],[1,2,3])])
3.数组的常用属性
读取外部文本文件数据
在numpy模块中,可以通过genfromtxt函数读取外部文本文件的数据(主要是csv文件和txt文件)
# 读入数据
stu_score = np.genfromtxt(fname = r'C:\Users\Administrator\Desktop\stu_socre.txt',delimiter='\t',skip_header=1)
# 查看数据结构
print(type(stu_score))
# 查看数据维数
print(stu_score.ndim)
# 查看数据行列数
print(stu_score.shape)
# 查看数组元素的数据类型
print(stu_score.dtype)
# 查看数组元素个数
print(stu_score.size)
# 运行结果
<class 'numpy.ndarray'>
2
(1380, 5)
float64
6900
4.数组的形状处理
改变数组形状
如下所示,虽然reshape和resize都是用来改变数组形状的“方法”,但是reshape方法知识返回改变形状后的预览,但并未真正改变数组arr3的形状;而resize方法则不会返回预览,而是会改变数组arr3的形状,从前后两次打印的形状可发现两者的区别。
arr3 = np.array([[1,5,7],[3,6,1],[2,4,8],[5,8,9],[1,5,9],[8,5,2]])
# 数组的行列数
print(arr3.shape)
# 使用reshape方法更改数组的形状
print(arr3.reshape(2,9))
# 打印数组arr3的行列数
print(arr3.shape)
# 运行结果
(6, 3)
[[1 5 7 3 6 1 2 4 8]
[5 8 9 1 5 9 8 5 2]]
(6, 3)
None
(2, 9)
将多维数组降为一维数组
利用ravel、flatten、reshape
如下所示,在默认情况下,优先按照数组的行顺序,逐个将元素降至一维;如果按原始数组的列顺序将数组降为一维的话,需要设置order参数为“F”,尽管三者的功能一致,但还是有区别的。
arr4 = np.array([[1,10,100],[2,20,200],[3,30,300]])
print('原数组:\n',arr4)
# 默认排序降维
print('数组降维:\n',arr4.ravel())
print(arr4.flatten())
print(arr4.reshape(-1))
# 改变排序模式的降维
print(arr4.ravel(order = 'F'))
print(arr4.flatten(order = 'F'))
print(arr4.reshape(-1, order = 'F'))
# 运行结果
原数组:
[[ 1 10 100]
[ 2 20 200]
[ 3 30 300]]
数组降维:
[ 1 10 100 2 20 200 3 30 300]
[ 1 10 100 2 20 200 3 30 300]
[ 1 10 100 2 20 200 3 30 300]
[ 1 2 3 10 20 30 100 200 300]
[ 1 2 3 10 20 30 100 200 300]
[ 1 2 3 10 20 30 100 200 300]
如下结果所示,通过flatten方法实现的降维返回的是复制,因为对降维后的元素做修改,并没有影响到原数组arr4的结果,相反,ravel方法与reshape方法返回的则是视图,通过对视图的改变是会影响到原数组的。
# 更改预览值
arr4.flatten()[0] = 2000
print('flatten方法:\n',arr4)
arr4.ravel()[1] = 1000
print('ravel方法:\n',arr4)
arr4.reshape(-1)[2] = 3000
print('reshape方法:\n',arr4)
# 运行结果
flatten方法:
[[ 1 10 100]
[ 2 20 200]
[ 3 30 300]]
ravel方法:
[[ 1 1000 100]
[ 2 20 200]
[ 3 30 300]]
reshape方法:
[[ 1 1000 3000]
[ 2 20 200]
[ 3 30 300]]
vstack用于垂直方向(纵向)的数组堆叠,其功能与row_stack函数一致,而hstack则用于水平方向(横向)的数组合并,其功能与colum_stack函数一致,下面通过具体例子对这四种函数的用法和差异加以说明,如下所示,前两个输出是纵向堆叠的效果,后两个则是横向合并的效果。如果是多个数组的纵向堆叠,必须保证每个数组的列数相同;如果将多个数组按横向合并的话则每个数组的行数必须相同。
arr4 = np.array([[1,10,100],[2,20,200],[3,30,300]])
arr5 = np.array([1,2,3])
print('vstack纵向合并数组:\n',np.vstack([arr4,arr5]))
print('row_stack纵向合并数组:\n',np.row_stack([arr4,arr5]))
arr6 = np.array([[5],[15],[25]])
print('hstack横向合并数组:\n',np.hstack([arr4,arr6]))
print('column_stack横向合并数组:\n',np.column_stack([arr4,arr6]))
# 计算数组的和
print('垂直方向计算数组的和:\n',np.sum(arr4,axis = 0))
print('水平方向计算数组的和:\n',np.sum(arr4, axis = 1))
# 运行结果
vstack纵向合并数组:
[[ 1 10 100]
[ 2 20 200]
[ 3 30 300]
[ 1 2 3]]
row_stack纵向合并数组:
[[ 1 10 100]
[ 2 20 200]
[ 3 30 300]
[ 1 2 3]]
hstack横向合并数组:
[[ 1 10 100 5]
[ 2 20 200 15]
[ 3 30 300 25]]
column_stack横向合并数组:
[[ 1 10 100 5]
[ 2 20 200 15]
[ 3 30 300 25]]
垂直方向计算数组的和:
[ 6 60 600]
水平方向计算数组的和:
[111 222 333]
数组的基本运算符
1.四则运算
在numpy模块中。实现四则运算的计算既可以使用运算符号,也可以使用函数,具体如下 四则运算中的符号分别是“+-*/”,对应的numpy模块函数分别是np.add、np.subtract、np.multiply和np.divide。
注意:函数只能接受两个对象的运算,如果需要多个对象的运算,就得使用嵌套方法。另外还有三个数学运算符:余数、整除和指数。
可以使用“%、//、**”计算数组元素之间商的余数、整除部分以及数组元素之间的指数。如果使用函数则用np.fmod、np.modf、np.power。但是整除的函数应用稍微复杂,需写成np.modf(arr7/arr8)[1],因为modf可以返回数值的小数部分和整数部分,而整数部分就是要取的整除值。
# 加法运算
math = np.array([98,83,86,92,67,82])
english = np.array([68,74,66,82,75,89])
chinese = np.array([92,83,76,85,87,77])
tot_symbol = math+english+chinese
tot_fun = np.add(np.add(math,english),chinese)
print('符号加法:\n',tot_symbol)
print('函数加法:\n',tot_fun)
# 运行结果
符号加法:
[258 240 228 259 229 248]
函数加法:
[258 240 228 259 229 248]
# 除法运算
height = np.array([165,177,158,169,173])
weight = np.array([62,73,59,72,80])
BMI_symbol = weight/(height/100)**2
BMI_fun = np.divide(weight,np.divide(height,100)**2)
print('符号除法:\n',BMI_symbol)
print('函数除法:\n',BMI_fun)
arr7 = np.array([[1,2,10],[10,8,3],[7,6,5]])
arr8 = np.array([[2,2,2],[3,3,3],[4,4,4]])
print('数组arr7:\n',arr7)
print('数组arr8:\n',arr8)
# 求余数
print('计算余数:\n',arr7 % arr8)
# 求整除
print('计算整除:\n',arr7 // arr8)
# 求指数
print('计算指数:\n',arr7 ** arr8)
# 整除部分
print('整除部分:\n',np.modf(arr7/arr8)[1])
# 运行结果
符号除法:
[22.77318641 23.30109483 23.63403301 25.20920136 26.7299275 ]
函数除法:
[22.77318641 23.30109483 23.63403301 25.20920136 26.7299275 ]
数组arr7:
[[ 1 2 10]
[10 8 3]
[ 7 6 5]]
数组arr8:
[[2 2 2]
[3 3 3]
[4 4 4]]
计算余数:
[[1 0 0]
[1 2 0]
[3 2 1]]
计算整除:
[[0 1 5]
[3 2 1]
[1 1 1]]
计算指数:
[[ 1 4 100]
[1000 512 27]
[2401 1296 625]]
整除部分:
[[0. 1. 5.]
[3. 2. 1.]
[1. 1. 1.]]
2.比较运算
运用比较运算符可以返回bool类型的值,即True和False。
arr7 = np.array([[1,2,10],[10,8,3],[7,6,5]])
arr8 = np.array([[2,2,2],[3,3,3],[4,4,4]])
# 取子集
# 从arr7中取出arr7大于arr8的所有元素
print(arr7)
print('满足条件的二维数组元素获取:\n',arr7[arr7>arr8])
# 从arr9中取出大于10的元素
arr9 = np.array([3,10,23,7,16,9,17,22,4,8,15])
print('满足条件的一维数组元素获取:\n',arr9[arr9>10])
# 判断操作
# 将arr7中大于7的元素改成5,其余的不变
print('二维数组的条件操作:\n',np.where(arr7>7,5,arr7))
# 将arr9中大于10 的元素改为1,否则改为0
print('一维数组的条件操作:\n',np.where(arr9>10,1,0))
# 运行结果
[[ 1 2 10]
[10 8 3]
[ 7 6 5]]
满足条件的二维数组元素获取:
[10 10 8 7 6 5]
满足条件的一维数组元素获取:
[23 16 17 22 15]
二维数组的条件操作:
[[1 2 5]
[5 5 3]
[7 6 5]]
一维数组的条件操作:
[0 0 1 0 1 0 1 1 0 0 1]
3.广播运算
当数组形状不想同时,也能够进行数学运算的功能称为数组的广播。但是数组的广播功能是有规则的,如果不满足这些规则,运算时会出错
- 各输入数组的维度可以不相等,但必须确保从右到左的对应维度值相等。
- 如果对应维度值不相等,就必须保证其中一个为1.
- 各输入数组都向其shape最长的数组看齐,shape中不足的部分都通过在前面加一补齐。
# 各输入数组维度一致,对应维度值相等
arr10 = np.arange(12).reshape(3,4)
arr11 = np.arange(101,113).reshape(3,4)
print('3×4的二维矩阵运算:\n',arr10 + arr11)
# 各输入数组维度不一致,对应维度值相等
arr12 = np.arange(60).reshape(5,4,3)
arr10 = np.arange(12).reshape(4,3)
print('维数不一致,但末尾的维度值一致:\n',arr12 + arr10)
# 各输入数组维度不一致,对应维度值不相等,但其中有一个为1
arr12 = np.arange(60).reshape(5,4,3)
arr13 = np.arange(4).reshape(4,1)
print('维数不一致,维度值也不一致,但维度值至少一个为1:\n',arr12 + arr13)
# 加1补齐
arr14 = np.array([5,15,25])
print('arr14的维度自动补齐为(1,3):\n',arr10 + arr14)
# 运行结果
3×4的二维矩阵运算:
[[101 103 105 107]
[109 111 113 115]
[117 119 121 123]]
维数不一致,但末尾的维度值一致:
[[[ 0 2 4]
[ 6 8 10]
[12 14 16]
[18 20 22]]
[[12 14 16]
[18 20 22]
[24 26 28]
[30 32 34]]
[[24 26 28]
[30 32 34]
[36 38 40]
[42 44 46]]
[[36 38 40]
[42 44 46]
[48 50 52]
[54 56 58]]
[[48 50 52]
[54 56 58]
[60 62 64]
[66 68 70]]]
维数不一致,维度值也不一致,但维度值至少一个为1:
[[[ 0 1 2]
[ 4 5 6]
[ 8 9 10]
[12 13 14]]
[[12 13 14]
[16 17 18]
[20 21 22]
[24 25 26]]
[[24 25 26]
[28 29 30]
[32 33 34]
[36 37 38]]
[[36 37 38]
[40 41 42]
[44 45 46]
[48 49 50]]
[[48 49 50]
[52 53 54]
[56 57 58]
[60 61 62]]]
arr14的维度自动补齐为(1,3):
[[ 5 16 27]
[ 8 19 30]
[11 22 33]
[14 25 36]]
常用的数学和统计函数
统计函数都有axis参数,该参数的目的是在统计数组元素时需要按照不同的轴方向计算,如果axis=1,则按水平方向计算统计值,即计算每一行的统计值;如果axis=0,则表示按垂直方向计算统计值,即计算每一列的统计值。
arr4 = np.array([[1,10,100],[2,20,200],[3,30,300]])
print(arr4)
print('垂直方向计算数组的和:\n',np.sum(arr4,axis = 0))
print('水平方向计算数组的和:\n',np.sum(arr4, axis = 1))
# 运行结果
[[ 1 10 100]
[ 2 20 200]
[ 3 30 300]]
垂直方向计算数组的和:
[ 6 60 600]
水平方向计算数组的和:
[111 222 333]
线性代数的相关计算

矩阵乘法
点积函数dot,使用在两个一维数组中,实际上是计算两个向量的乘积,返回一个标量;使用在两个二维数组中,即矩阵的乘法,矩阵乘法要求第一个矩阵的列数等于第二个矩阵的行数,否则会报错。
相关知识点:矩阵乘法