numpy

数组的创建与操作

数组的创建

通过numpy模块中的array函数实现数组的创建,如果向函数中传入一个列表或元组,将构造简单的一维数组;如果传入多个嵌套的列表或元组,则可以构造一个二维数组。构成数组的元素都是同质的,即数组中的每一个值都具有相同的数据类型,下面分别构造一个一维数组和二维数组。

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. ]]

数组元素的获取

# 一维数组元素的获取
print(arr1[[2,3,5,7]])

[ 8  7 11 72]

[]内,左右为行和列索引,若[]内有一个[],即行列表索引

# 二维数组按行取
print(arr2[[1,2]])

[[1.5 3.  5.4 7.3 9. ]
 [3.2 3.  3.8 3.  3. ]]
# 第2行第3列元素
print(arr2[1,2])

5.4
# 第3行所有元素
print(arr2[2,:])


[3.2 3.  3.8 3.  3. ]
# 第2列所有元素
print(arr2[:,1])

[ 6.   3.   3.  13.4]
# 第2至4行,2至5行
print(arr2[1:4,1:5])

[[ 3.   5.4  7.3  9. ]
 [ 3.   3.8  3.   3. ]
 [13.4 15.6 17.8 19. ]]

在一维数组中,列表的所有索引方法都可以使用在数组上,而且还可以将任意位置的索引组装为列表,用作对应元素的获取;在二维数组中,位置索引必须写成[rows,cols]的形式,方括号的前半部分用于控制二维数组的行引,后半部分用于控制数组的列索引。如果需要获取所有的行或列元素,那么,对应的行索引或列索引需要用英文状态的冒号表示。但是,要是从数组中取出某几行和某几列,通过[rows,cols]的索引方法就不太有效了

# 第一行、最后一行和第二列、第四列构成的数组
print(arr2[[0,-1],[1,3]])
# 第一行、最后一行和第一列、第三列、第四列构成的数组
print(arr2[[0,-1],[1,2,3]])

[ 6.  17.8]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
C:\WINDOWS\TEMP/ipykernel_5992/3795221112.py in <module>
      2 print(arr2[[0,-1],[1,3]])
      3 # 第一行、最后一行和第一列、第三列、第四列构成的数组
----> 4 print(arr2[[0,-1],[1,2,3]])

IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,) 

第一个打印结果并不是2×2的数组,而是含两个元素的一维数组,这是因
为numpy将[[0,-1],[1,3]]组合的理解为了[0,1]和[-1,3];同样,在第二个元素索引中,numpy仍然将[[0,-1],[1,2,3]]组合理解为拆分单独的[rows,cols]形式,最终导致结果中的错误信息。实际上,numpy的理解是错误的,第二个输出应该是一个2×3的数组。为了克服[rows,cols]索引方法的弊端,建议读者使用ix_函数

ix_

# 第一行、最后一行和第二列、第四列构成的数组
print(arr2[np.ix_([0,-1],[1,3])])
# 第一行、最后一行和第一列、第三列、第四列构成的数组
print(arr2[np.ix_([0,-1],[0,2,3])])

[[ 6.   2. ]
 [13.4 17.8]]
[[ 8.5  4.1  2. ]
 [11.2 15.6 17.8]]

数组常用属性

在numpy模块中,可以通过genfromtxt函数读取外部文本文件的数据,这里的文本文件主要为csv文件和txt文件

genfromtxt

np.genfromtxt(fname, dtype=<classfloat>, comments=#’, delimiter=None, skip_header=0,skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None,
names=None,)
fname:指定需要读入数据的文件路径。
dtype:指定读入数据的数据类型,默认为浮点型,如果原数据集中含有字符型数据,必
须指定数据类型为“str”。
comments:指定注释符,默认为“#”,如果原数据的行首有“#”,将忽略这些行的读入。
delimiter:指定数据集的列分割符。
skip_header:是否跳过数据集的首行,默认不跳过。
skip_footer:是否跳过数据集的脚注,默认不跳过。
converters:将指定列的数据转换成其他数值。
miss_values:指定缺失值的标记,如果原数据集含指定的标记,读入后这样的数据就为
缺失值。
filling_values:指定缺失值的填充值。
usecols:指定需要读入哪些列。
names:为读入数据的列设置列名称。
math	english	chinese	history	physics
76	59	100	78	71
75	94	83	63	65
83	76	92	73	82
64	81	100	70	78
# 查看数据结构
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

数组的形状处理

reshape、resize、

ravel、flatten、reshape

vstack、hstack、row_stack和colum_stack

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)

# 使用resize方法更改数组的形状
print(arr3.resize(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)

虽然reshape和resize都是用来改变数组形状的“方法”,但是reshape方法只
是返回改变形状后的预览,但并未真正改变数组arr3的形状;而resize方法则不会返回预览,而是会直接改变数组arr3的形状
将多维数组降为一维数组,利用ravel、flatten和reshape三种方法

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'))

arr4 = np.array([[1,10,100],[2,20,50],[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  50]
 [  3  30 300]]
数组降维:
 [  1  10 100   2  20  50   3  30 300]
[  1  10 100   2  20  50   3  30 300]
[  1  10 100   2  20  50   3  30 300]
[  1   2   3  10  20  30 100  50 300]
[  1   2   3  10  20  30 100  50 300]
[  1   2   3  10  20  30 100  50 300]

在默认情况下,优先按照数组的行顺序,逐个将元素降至一维(见数组降
维的前三行打印结果);如果按原始数组的列顺序,将数组降为一维的话,需要设置order参数为“F”(见数组降维的后三行打印结果)

# 更改预览值
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  50]
 [  3  30 300]]
ravel方法:
 [[   1 1000  100]
 [   2   20   50]
 [   3   30  300]]
reshape方法:
 [[   1 1000 3000]
 [   2   20   50]
 [   3   30  300]]

通过flatten方法实现的降维返回的是复制,因为对降维后的元素做修改,并没有影响到原数组arr4的结果;相反,ravel方法与reshape方法返回的则是视图,通过对视图的改变,是会影响到原数组arr4的。vstack用于垂直方向(纵向)的数组堆叠,其功能与row_stack函数一致,而hstack则用于水平方向(横向)的数组合并,其功能与colum_stack函数一致

arr5 = np.array([1,2,3])
print('vstack纵向合并数组:\n',np.vstack([arr4,arr5]))
print('row_stack纵向合并数组:\n',np.row_stack([arr4,arr5]))

vstack纵向合并数组:
 [[   1 1000 3000]
 [   2   20   50]
 [   3   30  300]
 [   1    2    3]]
row_stack纵向合并数组:
 [[   1 1000 3000]
 [   2   20   50]
 [   3   30  300]
 [   1    2    3]]
arr6 = np.array([[5],[15],[25]])
print('hstack横向合并数组:\n',np.hstack([arr4,arr6]))
print('column_stack横向合并数组:\n',np.column_stack([arr4,arr6]))

hstack横向合并数组:
 [[   1 1000 3000    5]
 [   2   20   50   15]
 [   3   30  300   25]]
column_stack横向合并数组:
 [[   1 1000 3000    5]
 [   2   20   50   15]
 [   3   30  300   25]]

数组基本运算符

在numpy模块中,实现四则运算的计算既可以使用运算符号,也可以使用函数

print(arr4)
print('垂直方向计算数组的和:\n',np.sum(arr4,axis = 0))
print('水平方向计算数组的和:\n',np.sum(arr4, axis = 1))

print(arr4)
print('垂直方向计算数组的和:\n',np.sum(arr4,axis = 0))
print('水平方向计算数组的和:\n',np.sum(arr4, axis = 1))
# 加法运算
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)

# 除法运算
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)

# 加法运算
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)

# 除法运算
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)

np.add、np. subtract、np.multiply和np.divide

± * / %、//、**

四则运算中的符号分别是“±*/”,对应的numpy模块函数分别是np.add、np. subtract、np.multiply和np.divide。需要注意的是,函数只能接受两个对象的运算,如果需要多个对象的运算,就得使用嵌套方法,如上所示的符号加法和符号除法。不管是符号方法还是函数方法,都必须保证操作的数组具有相同的形状,除了数组与标量之间的运算(如除法中的身高与100的商)。另外,还有三个数学运算符,分别是余数、整除和指数:可以使用“%、//、**”计算数组元素之间商的余数、整除部分以及数组元素之间的指数。

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)

数组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]]
# 取子集
# 从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]

运用bool索引,将满足条件的元素从数组中挑选出来,但不管是一维数组还是多维数组,通过bool索引返回的都是一维数组;np.where函数与Excel中的if函数一样,就是根据判定条件执行不同的分支语句。

广播

前面所介绍的各种数学运算符都是基于相同形状的数组,当数组形状不同时,也能够进行数学运算的功能称为数组的广播。但是数组的广播功能是有规则的,如果不满足这些规则,运算时就会出错。数组的广播规则是:

各输入数组的维度可以不相等,但必须确保从右到左的对应维度值相等。
如果对应维度值不相等,就必须保证其中一个为1。
各输入数组都向其shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐。

# 各输入数组维度不一致,对应维度值相等
arr12 = np.arange(60).reshape(5,4,3)
arr10 = np.arange(12).reshape(4,3)
print('arr12\n',arr12)
print('\n')
print('arr10\n',arr10)
print('维数不一致,但末尾的维度值一致:\n',arr12 + arr10)

arr12
 [[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]

 [[24 25 26]
  [27 28 29]
  [30 31 32]
  [33 34 35]]

 [[36 37 38]
  [39 40 41]
  [42 43 44]
  [45 46 47]]

 [[48 49 50]
  [51 52 53]
  [54 55 56]
  [57 58 59]]]


arr10
 [[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
维数不一致,但末尾的维度值一致:
 [[[ 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
arr12 = np.arange(60).reshape(5,4,3)
arr13 = np.arange(4).reshape(4,1)
print('arr12\n',arr12)
print('\n')
print('arr13\n',arr13)
print('维数不一致,维度值也不一致,但维度值至少一个为1:\n',arr12 + arr13)
# 加1补齐
arr14 = np.array([5,15,25])
print('arr10\n',arr10)
print('arr14的维度自动补齐为(1,3):\n',arr10 + arr14)

arr12
 [[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]

 [[24 25 26]
  [27 28 29]
  [30 31 32]
  [33 34 35]]

 [[36 37 38]
  [39 40 41]
  [42 43 44]
  [45 46 47]]

 [[48 49 50]
  [51 52 53]
  [54 55 56]
  [57 58 59]]]


arr13
 [[0]
 [1]
 [2]
 [3]]
维数不一致,维度值也不一致,但维度值至少一个为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]]]
arr10
 [[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
arr14的维度自动补齐为(1,3)[[ 5 16 27]
 [ 8 19 30]
 [11 22 33]
 [14 25 36]]

如上结果所示,第一个打印结果其实并没有用到数组的广播,因为这两个数组具有同形状;第二个打印结果是三维数组和两维数组的和,虽然维数不一样,但末尾的两个维度值是一样的,都是4和3,最终得到5×4×3的数组;第三个打印中的两个数组维数和维度值均不一样,但末尾的两个维度值中必须含一个1,且另一个必须相同,都为4,相加之后得到5×4×3的数组;第四个打印结果反映的是4×3的二维数组和(3,)的一维数组的和,两个数组维度不一致,为了能够运算,广播功能会自动将(3,)的一维数组补齐为(1,3)的二维数组,进而得到4×3的数组。
在这里插入图片描述
如果axis=1,则表示按水平方向计算统计值,即计算每一行的统计值;如果axis=0,则表示按垂直方向计算统计值,即计算每一列的统计值。

linalg

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值