020机器学习数据科学包-numpy基本操作1

Numpy

NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

numpy是一个用python实现的科学计算,包括:
1、一个强大的N维数组对象Array;
2、比较成熟的(广播)函数库;
3、用于整合C/C++和Fortran代码的工具包;
4、实用的线性代数、傅里叶变换和随机数生成函数。numpy和稀疏矩阵运算包scipy配合使用更加方便。
NumPy(Numeric Python)提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。

Numpy属性

定义一个array,其中的长宽、维数等等都是numpy的属性。

import numpy as np

array = np.array( [[1,2,3],
                  [3,4,5]] )
print(array)

以上就是一个简单创建和输出array的代码

print('number of dim:',array.ndim)#输出矩阵的维数
print('shape:',array.shape)#输出矩阵的行数和列数
print('size',array.size)#输出矩阵元素个数

通过array的内置函数,可以输出矩阵的维数,矩阵的行列数以及矩阵元素的个数等等。这些都是矩阵的基本属性。需要提醒的是,shape输出结果,第一位元素代表行数,第二位元素代表列数。

Numpy数据类型

numpy中可以创建各种各样的矩阵和数组。在创建array时,可以定义这个矩阵的数据类型(type)。那numpy有哪些数据类型?

名称描述
bool_布尔型数据类型(True 或者 False)
int_默认的整数类型(类似于 C 语言中的 long,int32 或 int64
intc与 C 的 int 类型一样,一般是 int32 或 int 64
intp用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8字节(-128 to 127)
int16整数(-32768 to 32767)
int32整数(-2147483648 to 2147483647)
int64整数(-9223372036854775808 to 9223372036854775807)
uint8无符号整数(0 to 255)
uint16无符号整数(0 to 65535)
uint32无符号整数(0 to 4294967295)
uint64无符号整数(0 to 18446744073709551615)
float_float64 类型的简写
float16半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_complex128 类型的简写,即 128 位复数
complex64复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128复数,表示双 64 位浮点数(实数部分和虚数部分)

numpy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符,包括 np.bool_,np.int32,np.float32,等等。

a=np.array([1,2,3],dtype=np.int)
print(a.dtype)#输出a的数据类型
#int默认是64位整型

通常位数更小,所占内存就越小,但运算速度就会越慢。

Numpy创建array

numpy中生成数组的方法有很多:

  • 生成一个空的数组(其实是一个几乎为0的数组):empty(shape[, dtype, order])
a = np.empty((3,4))#参数需要是元组形式
  • 生成一个所有元素全为0的数组(np.zeros((行数,列数))):zeros(shape[, dtype, order])
b = np.zeros((3,4))
  • 生成一个所有元素都为1的数组:ones(shape[, dtype, order])
c = np.ones((3,4),dtype=np.int16)
#可以直接在后面对数组元素的数据类型进行定义
  • 生成有序的序列或矩阵,需要起始值和终止值
d = np.arange(10,20,2)#起始为10,终止为20,步长为2的元素组成的序列

如果想要获得一个矩阵,就需要重写序列的shape:

d = np.arange(12).reshape((3,4))
  • 生成线段,比如说从最开始的数值1到10,最后一个给定参数是需要在这个区间需要多少段。第一个参数是起始值,第二个参数是终止值,第三个参数是我们需要多少这样的线段,他会根据需要的线段数量来自动确定步长。
e = np.linspace(1,10,20)#起始值是1,终止值是10,要获得20条线段

当然,生成线段,也可以更改数组的shape。
除此之外,numpy还有很多生成数组的方法:

  • empty(shape[, dtype, order])
  • empty_like(a[, dtype, order, subok])
  • eye(N[, M, k, dtype, order])
  • identity(n[, dtype])
  • ones(shape[, dtype, order])
  • ones_like(a[, dtype, order, subok])
  • zeros(shape[, dtype, order])
  • zeros_like(a[, dtype, order, subok])
  • full(shape, fill_value[, dtype, order])
  • full_like(a, fill_value[, dtype, order, subok])

Numpy基础运算

1.array减法

a = np.array([10,20,30,40])
b = np.arange(4)

print(a,b)
c = a - b#array减法
print(c)

2.array加法

a = np.array([10,20,30,40])
b = np.arange(4)

print(a,b)
c = a + b#array加法
print(c)

3.array乘法(都是相似的)

b = np.arange(4)

c = b**2#b数组的平方:每个元素分别平方,组成c
print(c)

4.求三角函数,需要调用numpy中的内置函数

a = np.array([10,20,30,40])
c = 10*np.sin(a)#求余弦
print(c)

5.判断array中有多少个元素大(小)于指定元素,即比较大小

b = np.arange(4)

print(b)
print(b<3)#布尔型返回True or False

#运行结果:
#[0 1 2 3]
#[ True  True  True False]

6.矩阵运算
numpy中乘法分两种,一个是逐个相乘,一个是矩阵乘法。逐个相乘:c=a*b,和矩阵乘法,需要调用numpy中的dot()函数。

a = np.array([[1,1],
             [0,1]])
b = np.arange(4).reshape((2,2))

print('a:',a)
print('b:',b)

c = a*b#矩阵元素逐个相乘
c_dot = np.dot(a,b)
c_dot_2 = a.dot(b)#矩阵乘法的两种表达形式
print('c:',c)
print('dot1:',c_dot)
print('dot2:',c_dot_2)

7.在随机生成的array中最大/小值,以及求和

a = np.random.random((2,4))#后一个random就是reshape的作用
print(a)
print(np.sum(a))#求和
print(np.min(a))#求最小值
print(np.max(a))#求最大值

8.最大/最小值索引;平均值;中位数

a = np.arange(2,14).reshape((3,4))

print(a)
print(np.argmin(a))#计算最小值的索引(是下标)
print(np.argmax(a))#计算最大值的索引
print(np.mean(a))
print(a.mean())#计算矩阵的平均值(两种形式)
print(np.median(a))#计算中位数

9.矩阵逐步累加

a = np.arange(2,14).reshape((3,4))

print(a)
print(np.cumsum(a))#每一位都是前位元素累加而成

10.矩阵逐步累差
矩阵逐步累差的过程,原矩阵本来是3行4列,累差以后是3行3列的矩阵。因为四个数,每两个数相差的话,只会输出三个值。

a = np.arange(2,14).reshape((3,4))

print(a)
print(np.diff(a))

11.找出非0数
使用nonzero输出的是两组array,一组表示非0元素所在行数,一组表示非0元素所在列数。

a = np.arange(2,14).reshape((3,4))

print(a)
print(np.nonzero(a))

12.矩阵排序
矩阵排序需要定义步长,并且排序是逐行进行的。

a = np.arange(14,2,-1).reshape((3,4))
print(a)
print(np.sort(a))#分别对每行进行排序
'''
运行结果:
原矩阵: [[14 13 12 11]
 [10  9  8  7]
 [ 6  5  4  3]]
排序后: [[11 12 13 14]
 [ 7  8  9 10]
 [ 3  4  5  6]]
 '''

13.矩阵相乘
numpy中计算矩阵相乘,需要先计算矩阵的转置。

a = np.arange(14,2,-1).reshape((3,4))
print('原矩阵',a)
print('a的转置:',np.transpose(a))
print('a的转置:',a.T)#求矩阵的转置
print('矩阵乘法:',(a.T).dot(a))#矩阵乘法(a的转置乘以a)

14.clip函数
numpy.clip(a, a_min, a_max, out=None);其实就是把数组a的元素限制到[a_min, a_max]区间内。
给定最小值和最大值,这个array中所有小于最小值的元素,都让他们等于最小值;所有大于最大值的元素,都让他们等于最大值,中间元素不变。

a = np.arange(14,2,-1).reshape((3,4))
print(a)
print(np.clip(a,5,9))#限制元素值域,最小值为5,最大值为9

注意:

  • numpy的所有指令都可以指定需要对行计算还是对列计算(axis=‘ ’,0对行操作,纵向的操作,1对列操作,横向的操作)
  • numpy中还有其他运算,这里没有全部罗列

Numpy的索引

如何在numpy中根据他的位置找到他的值?
1.在一维array中,元素的下标就是其索引。

a = np.arange(3,15)
print(a)

在二维的array中,

a = np.arange(3,15).reshape((3,4))
print(a)
print(a[2])#输出是一行数据,不是单个数据

想要输出指定的某个元素,需要指定他的位置(行和列)。

print(a[2][1])
print(a[2,1])#两种通过索引指定元素的表达方式

也可以用冒号来表示某一行的所有数A[2,:],或者某一列的所有数A[:,1]

print(a[11:2])
#表示第一列从位置1到位置2的值(不包含结尾位置)

2.可以通过for循环来输出每行元素。

a = np.arange(3,15).reshape((3,4))
print(a)
for row in a:
    print(row)#输出的数矩阵中的每一行

在numpy中没有遍历输出每一列的操作,通过转置来迭代转置矩阵的行,其实就是原来矩阵的列。

for column in a.T:
    print(column)

3.如果想要通过迭代来print出他的项目应怎么做呢?如果直接在a中去遍历,迭代的是a中的行;要想迭代项目,需要先将array的格式进行转变。

print(a.flatten())#flatten()一个函数,返回了一个被改变的array
for item in a.flat:#flat是一个迭代器
    print(item)#输出的是array中的一个一个元素

Numpy的array合并

array的合并要分为按行或列合并
1.两个array上下合并

a = np.array([1,1,1])
b = np.array([2,2,2])

print(np.vstack((a,b)))#vertical stack,对两个array上下进行合并
#vstack()函数的参数是元组形式

两个array进行上下合并后,就称为一个矩阵。

a = np.array([1,1,1])
b = np.array([2,2,2])

c = np.vstack((a,b))
print(a.shape,c.shape)#输出a和c的结构
'''
运行结果:
(3,) (2, 3)
由此可知,a是一个一维序列,c是2行3列的二维序列
'''

2.两个array左右合并

d = np.hstack((a,b))#horizontal stack
print(d)
print(a.shape,d.shape)
'''
运行结果:
[1 1 1 2 2 2]
(3,) (6,)
由此可知,a,b两个序列左右合并后得到的是还是一个一维的序列
'''

但需要注意的是,我们不能通过transpose这个方法去改变序列的方向(即,不能将横向的序列改变成竖向的序列),这个方法只适用于矩阵。那么如何实现将一个横向的数列变成竖向的数列呢?需要调用numpy的newaxis方法[np.newaxis,:],对araay新加一个维度(冒号在后,是多加了一个行的维度;冒号在前,是多加了一个列的维度)。

a = np.array([1,1,1])[:,np.newaxis]
b = np.array([2,2,2])[:,np.newaxis]#冒号在前就是多加了一个列的维度

d = np.hstack((a,b))#horizontal stack
print(d)
print(a.shape,d.shape)
'''
运行结果:
[[1 2]
 [1 2]
 [1 2]]
(3, 1) (3, 2)
由此可知,在经过newaxis方法后,a,b两个序列都增加了一个列的维度,在左右合并了以后就成为了一个3行2列矩阵,相当于a,b两个序列转置后,再合并。
'''

3.多个array纵向或横向的合并

a = np.array([1,1,1])[:,np.newaxis]
b = np.array([2,2,2])[:,np.newaxis]#冒号在前就是多加了一个列的维度

print(np.hstack((a,a,b)))#多个array进行左右合并
c = np.concatenate((a,b,b,a))
#concatenate可以设置在哪一个维度进行合并,默认axis=0,上下合并
print(c)

concatenate方法中,设置axis=1,左右合并。

c = np.concatenate((a,b,b,a),axis=1)
'''
运行结果:
[[1 2 2 1]
 [1 2 2 1]
 [1 2 2 1]]
'''

Numpy的array分割

1.将array分割成不同的片段(也分横向/纵向的分割),要用到numpy中的split方法,其中第一个参数为目标array,第二个参数为分割数目,第三个参数axis设置分割方向。

a = np.arange(12).reshape((3,4))
print(a)

print(np.split(a,2,axis=1))#a这个序列,分割成2个片段,按照列分割(左右分割)
'''
运行结果:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2,  3],
       [ 6,  7],
       [10, 11]])]
'''

需要注意的是,上述示例可以对行进行分割分成3个片段,因为有3行。但是不可以对列进行分割成3个片段,因为array只能进行相等的分割,4列不可以分成3份。
2.那如何实现不等量的分割呢?在numpy中进行不等量的分割:

print(a)
print(np.array_split(a,3,axis=1))
'''
运行结果:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2],
       [ 6],
       [10]]), array([[ 3],
       [ 7],
       [11]])]
由此可见,在对array进行不等量分割时,首先将前两列分为一块,第三列为一块,最后一列为一块
'''

3.分割函数

  • 纵向的分割(对行操作)
print(np.vsplit(a,3))
'''
运行结果:
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8,  9, 10, 11]])]
'''
  • 横向的分割(对列操作)
print(np.hsplit(a,2))
'''
运行结果:
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2,  3],
       [ 6,  7],
       [10, 11]])]
'''

Numpy的copy和deep copy

在对numpy进行赋值时,值具有传递性。

a = np.arange(4)
print(a)
b = a
c = a
d = b

a[0] = 11#改变a中的元素,同时也改变了b中的元素
print(b is a)
#因为前面a=b=c=d,因此改变其中任意个array中的元素,其他array也会发生变化
d[1:3] = [22,33]#对d中第2/3个元素进行修改,a中元素也会修改
print('d:',d)
print('a:',a)
'''
运行结果:
[0 1 2 3]
True
d: [11 22 33  3]
a: [11 22 33  3]
'''

如果想要a的值,但是不想要关联a序列,就需要用到copy函数:

a = np.arange(4)
print(a)
b = a.copy()#deep copy,只获得a中的值,但没有关联a
print(b)
a[3] = 44#修改a中元素
print('a:',a)
print('b:',b)#不会跟随a的修改而修改其中的元素
'''
运行结果:
[0 1 2 3]
[0 1 2 3]
a: [ 0  1  2 44]
b: [0 1 2 3]
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值