-
ndarray数组对象
NumPy定义了一个n维数组对象,简称ndarray对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块
ndarray 对象采用了数组的索引机制
,将数组中的每个元素映射
到内存块上,并且按照一定的布局对内存块进行排列(行或列).1.1 ndarray基本数据类型
1.2 numpy.array()创建数组
格式:
numpy.array(object,dtype=None,copy = True, order = None,subok - False, ndmin = 0)
参数说明:
参数 | 参数说明 |
---|---|
object | 表示要传入一个数组序列,传入参数可以是:列表\元组\ndarray数组\迭代对象\生成器,当传入序列有不同类型的元素时,将保留存储空间最大的类型 |
dtype | 可选参数,通过它更改数组的数据类型 |
copy | 可选参数,当数据源是ndarray是,表示数组是被能被复制,默认是True |
order | 可选参数,以哪种内存布局创建你数组,有3个可选值:C(行序列)/F(列序列)/A(任意方向,默认) |
ndmin | 可选参数,指定数组的纬度 |
subok | 可选参数,类型为bool,默认为Fasle.当为False时,使用ndarray数组的数据类型;为True时,使用obeject内部数据类型 |
代码示例:
# subok参数
import numpy as np
# 创建一个矩阵
a = np.mat([1,2,3,4])
print(type(a))#<class 'numpy.matrix'>
# 如果既要复制一份副本又要保持原类型,那么subk = True
b = np.array(a,subok=True)
c = np.array(c,subok=False)#默认
print(type(b),type(c))#<class 'numpy.matrix'> <class 'numpy.ndarray'>
1.3 numpy.empty()创建未初始化数组
创建指定形状的数组,元素随机填充
格式:
np.empty(shape,dtype =float,order =“C”)
示例代码:
import numpy as np
a = np.empty((3,3),dtype='int')
print(a)
"""
[[1 2 3]
[4 5 6]
[0 0 0]]
"""
注意:
− 数组元素为随机值,因为它们未初始化
1.4 numpy.zeros() 创建0填充的指定大小的数组
创建指定形状的数组,数组元素以0填充
格式:
np.zeros(shape,dtype=float,order =“C”)
1.5 numpy.ones() 创建1填充的指定大小的数组
创建指定形状的数组,数组元素以 1 来填充
格式:
np.ones(shape,dtype=None,order=‘C’)
1.6 numpy.asarray()
numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。
格式:
np.asarray(a,dtype=None,order=None)
注意:
- 跟array类似,参数a可以是任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
1.7 numpy.arange()用区间创建数组
格式:
numpy.arange(start,stop,step,dtype)
代码示例:
import numpy as np
a = np.arange(1,11,dtype=float)
print(a)
b = np.arange(3.1)
print(b)
c = np.arange(20,3)
print(c)
Tip:
如何防止float不精确影响numpy.arange,代码案列:
ceil((stop-start)/step),确定项目数,小浮点不精确(stop = .400000001)可以向列表中添加意外值。
import numpy as np
a = np.arange(.1,.4,.1)
print(a)#按理说应该是[0.1,0.2,0.3],但实际打印的确实[0.1 0.2 0.3 0.4]
因为浮点数在转换为二进制进行运算的时候会产生误差
1.8 numpy.linsapce()创建等差数列
返回在区间[start,stop]内num个均匀间隔的样本.数组是一个等差数列.
格式:
np.linespace(start,stop,num=50,endpoint=True,retstep=False,dtype=None)\
参数描述:
参数 | 功能描述 |
---|---|
start | 必填项,序列起始下标 |
stop | 必填项,序列终止下标,如果endpoint为True时,包含末尾的stop |
num | 生成等步长的样本数量,默认值是50 |
endpoint | 默认为True,为True时,包含末尾的stop.反之,则不包含 |
retstep | 默认为False,为True时会显示生成的数组元素的间距,反之,则不显示 |
dtype | ndarray的数据类型 |
代码示例:
import numpy as np
a = np.linspace(1,50)
print(a)
b = np.linspace(1,50,retstep=True)
print(b)
1.9 numpy.logspace 生成等比数列
返回在区间[start,stop]上计算的num个均匀间隔的样本.数据是一个等比数列构成.
格式:
np.logspace(start,stop,num = 50,endpoint =True,base = 10.0,dtype = None)
参数描述:
参数 | 功能描述 |
---|---|
start | 必填项,序列起始下标 |
stop | 必填项,序列终止下标,如果endpoint为True时,包含末尾的stop |
num | 生成等步长的样本数量,默认值是50 |
endpoint | 默认为True,为True时,包含末尾的stop.反之,则不包含 |
retstep | 默认为False,为True时会显示生成的数组元素的间距,反之,则不显示 |
base | 对数log的底数 |
dtype | ndarray的数据类型 |
参数解释:
np.logspace(A,B,C,base = D)
注:
- A:生成数组的起始值为D的A次方
- B:生成数组的结束值为D的B次方
- C:总共生成C个数
- D:指数型数组的底数为D,当省略base=D时,默认底数为10
import numpy as np
a = np.logspace(1,10,10,base=2)
print(a)#[ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]
b = np.logspace(1,10,10)
print(b)#[1.e+01 1.e+02 1.e+03 1.e+04 1.e+05 1.e+06 1.e+07 1.e+08 1.e+09 1.e+10]
1.5 ndarray数组的重要属性和方法
numpy中比较重要的ndarray数组对象属性
有:
属性 | 说明 |
---|---|
ndarray.ndim | 数组的维度 |
ndarray.shape | 数组的形状,对于矩阵,m行n列 |
ndarray.size | 数组元素的总个数,相等于shape打印形状的(m,n)中的m*n |
ndarray.dtype | ndarray数组对象的元素类似 |
ndarray.itemsize | ndarray数组对象中每个元素的大小,以字节为单位.例如,一个float64展64bit,每个字节长度为8,共占64/8=8字节 |
ndarray.flags | ndarray对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
numpy中比较重要的ndarray数组对象方法
有:
方法名 | 作用 |
---|---|
ndarray.reshape(new_shape) | 不改变原ndarray的基础上,返回调整形状之后的副本.注意,调整之后总个数要保持不变 |
ndarray.resize(a,new_shape) | 如果新数组大于原始数组,则新数组将填充a的重复副本,注意:ndarray.resize(new_shape),是用0填充,而不是用重复的a填充 |
ndarray.astype() | numpy数据类型转换,调用astype返回数据类型修改后的数据,但是源数据的类型不会变 |
代码示例:
import numpy as np
a = np.array([1,2,.3,.5])
print(a.dtype)#float64
# 修改a的元素类型
b = a.astype('float32')
print(b.dtype)#float32
print(b.astype('int64').dtype)#int64
-
切片和索引
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
注意:
数组切片是原始数组视图(这就意味着,如果做任何修改,原始都会跟着更改)。这也意味着,如果不想更改原始数组,我们需要进行显式的复制,从而得到它的副本(.copy())。
格式:
ndarray[start:stop:step(不被包含)]
注意:
切片还可以使用省略号’…',如果在行位置使用省略号,俺么返回值将包含所有行元素,反之则包含所有列元素
格式:
ndarray[…,列切片操作]/ndarray[行切片操作,…]
ndarray[…][行切片操作]
代码示例:
a = np.array([
[1,2,3,4],
[2,3,4,5],
[4,5,6,7]
],dtype='float')
print(a)
print(a[...,1])#[2. 3. 5.]
print(a[...,1:])
# [[2. 3. 4.]
# [3. 4. 5.]
# [5. 6. 7.]]
print(a[...][1])#[2. 3. 4. 5.]
Tip:
为什么切片和区间会忽略最后一个元素?
计算机科学家edsger w.djkstra(艾兹格·W·迪科斯彻),delattr这一风格的解释应该是比较好的:
- 当只有最后一个位置信息时,我们可以快速看出切片和区间里有几个元素: range(3)和my_list[:3]
- 当起始位置信息都可见时,我们可以快速计算出切片和区间的长度,用有一个数减去第一个下表(stop-start)即可
- 这样做也让我们可以利用任意一个下标把序列分割成不重叠的两部分,只要写成my_list[x]和my_list[x:]就可以了。
除了常规的索引方式,NumPy 比一般的 Python 序列提供更多的索引方式。 除了之前看到的用整数和切片的索引外,数组可以由整数数组索引
、布尔索引
及花式索引
.
2.1 整数数组索引
格式:
ndarray[[行索引],[列索引]] / ndarray[行切片,列切片]
注意:也可以索引跟切片混合使用
代码示例
:获取(1,0),(2,1),(0,0)元素为例
import numpy as np
a = np.arange(16)
b = a.reshape((4,4))
# 获取四个角上的值
print(b)
print(b[[0,0,3,3],[0,3,0,3]])
print(b[...,[0,0]])
print(b[1:3,[0]])
2.2 布尔索引
当输出的结果需要经过布尔运算(如比较运算)时,此时会使用到另一种高级索引方式,即布尔数组索引。下面示例返回数组中大于6的的所有元素:
代码示例:
import numpy as np
import numpy as np
a = np.arange(9)
b = a.reshape((3,3))
c = np.arange(start=9,stop=0,step=-1)
d = c.reshape((3,3))
print(b)
print(b[b>6])
print(d)
print(b[b>d])
#[[0 1 2]
# [3 4 5]
# [6 7 8]]
#[7 8]
#[[9 8 7]
# [6 5 4]
# [3 2 1]]
#[5 6 7 8]
拓展:
布尔索引实现的是通过一维数组中的每个元素的布尔型数值对一个与一维数组有着同样行数或列数的矩阵进行符合匹配。这种作用,其实是把一维数组中布尔值为True的相应行或列给抽取了出来
(注意:一维数组的长度必须和想要切片的维度或轴的长度一致)。
2.3 花式索引
花式索引指的是利用整数数组进行索引。
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。
对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素,如果目标是二维数组,那么就是对应下标的行
代码示例:
import numpy as np
# 花式索引
a = np.arange(9)
print(a)
print(a[[0,6]])
b =a.reshape((3,3))
print(b)
print(b[[2,1,0]])
3.1 numpy的广播机制(Broadcast)
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
但如果两个数组形状不同,那它们之间如何进行算数运算呢?
当运算中的 两 个数组的形状不同时,numpy 将自动触发广播机制。
这种机制 的核心是对形状较小的数组,在横向或者纵向上进行一定次数的重复,与其形状较大的数组拥有相同的纬度.
如下图所示,展示了数组a与数组b是如何利用广播机制兼容:
4*3 的二维数组a与长为 3 的一维数组b相加,等效于把b在二维上重复4次后,再进行运算.
广播机制的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加1补齐
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为1时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为1时,沿着此维度运算时都用此维度上的第一组值。
规则理解:
数组a大小为(2,1,3)
数组b大小为(4,1)
首先右对齐:
2 1 3
4 1
3 跟 1 匹配,1 跟 4 匹配,此时就能做运算
从上面的就能看出:
- 两个数组右对齐以后,对应纬度里的数值要么相等,要么为1
- 此外就不能运算,下面这种就不能运算
数组a大小为(2,1,3)
数组b大小为(4,2)
首先右对齐:
2 1 3
4 2
2 跟 3 不匹配,此时就不能做运算
3.2 迭代数组
NumPy 迭代对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
迭代器最基本的任务的可以完成对数组元素的访问。
格式:
i for i in np.nditer(ndarray,order = “C”)
代码示例:
import numpy as np
a = np.arange(0,60,5).reshape((3,4))
print(a)
print('以C顺序打印')
for i in np.nditer(a,order='C'):
print(i)
print('以F顺序打印')
for i in np.nditer(a,order='F'):
print(i)
3.3 numpy的数组操作
Numpy中包含一些函数用于处理数组,大概可分为用一下几类:
-
修改数组形状
-
翻转数组
-
修改数组维度
-
连接数组
-
分割数组
-
数组元素的添加与删除
3.3.1 修改数组形状
(1)np.reshape:返回新形状数组,不影响原数组
格式:
np.reshape(ndarray,newshape,order=“c”)
参数解释:
参数名 作用 ndarray 要修改形状的数组 newshape 整数或者整数数组,新的形状应该兼容原有形状 order ‘C’-按行,‘F’-按列,‘A’-原顺序,‘K’ (2)np.ndarray.flatten: 返回一份展平的数组拷贝,对拷贝所做的修改不会影响原始数组
格式:
ndarray.flatten(order=‘C’)
实例代码:
import numpy as np a = np.arange(8).reshape((2,4)) print(a) print(a.flatten(order='C')) # print(a.flatten(order='F')) # print(a.flatten(order='K')) # # print(a.flatten(order='A')) # [[0 1 2 3] # [4 5 6 7]] # [0 1 2 3 4 5 6 7] # [0 4 1 5 2 6 3 7] # [0 1 2 3 4 5 6 7] # [0 1 2 3 4 5 6 7]
3.3.2 翻转数组
(1)np.transpo:返回对换维度的数组
格式:
np.transpose(ndarray,axes): #axes:整数列表,对应维度,通常所有维度都会对换。
实例代码:
import numpy as np a = np.arange(12).reshape(3,4) print(a) print(np.transpose(a)) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # [[ 0 4 8] # [ 1 5 9] # [ 2 6 10] # [ 3 7 11]]
(2)np.swapaxes:返回交换数组的两个轴新数组
格式:
np.swapaxes(ndarray,axis1,aixs2)
参数解释:
参数名 作用 ndarray 要修改形状的数组 axis1 对应第一个轴的整数 axis2 对应第二个轴的整数 代码示例:
import numpy as np a = np.arange(8).reshape(2,2,2) print(a) # 现在交换轴 0(深度方向)到轴 2(宽度方向) print(np.swapaxes(a,2,0)) # [[[0 1] # [2 3]] # [[4 5] # [6 7]]] # [[[0 4] # [2 6]] # [[1 5] # [3 7]]]
3.3.3修改数组维度
(1)np.expand_dims:返回在指定位置插入新的轴来扩展数组形状的新数组
格式:
np.expand_dims(ndarray,axis)#新轴的插入
代码示例:
import numpy as np a = np.arange(1,5).reshape(2,2) b = np.expand_dims(a,axis=0) print(a.shape,b.shape) print(a,b,sep='\n') # (2, 2) (1, 2, 2) # [[1 2] # [3 4]] # [[[1 2] # [3 4]]]
(2)np.squeeze:返回从给定数组的形状中删除一维的条目的新数组
格式:
np.squeeze(arr,axis)
代码演示:
import numpy as np a = np.arange(9).reshape(1,3,3) b= np.squeeze(a) print(a.shape,b.shape) print(a,b,sep='\n') # (1, 3, 3) (3, 3) # [[[0 1 2] # [3 4 5] # [6 7 8]]] # [[0 1 2] # [3 4 5] # [6 7 8]]
3.3.4 连接数组
(1)np.concatenate:沿指定轴连接相同形状的两个或多个数组
格式:
numpy.concatenate((a1, a2, …), axis)
参数解释:
参数名 描述 a1, a2, … 相同类型的数组 axis 沿着它连接数组的轴,默认为 0 代码演示:
import numpy as np a = np.array([[1,2],[3,4]]) b = np.array([[5,6],[7,8]]) # 沿着0轴连接两个数组 c = np.concatenate((a,b)) # 沿着1轴连接两个数组 d = np.concatenate((a,b),axis=1) print(a.shape,b.shape,c.shape,d.shape,sep='\n') print(a,b,c,d,sep='\n') """ (2, 2) (2, 2) (4, 2) (2, 4) [[1 2] [3 4]] [[5 6] [7 8]] [[1 2] [3 4] [5 6] [7 8]] [[1 2 5 6] [3 4 7 8]] """
(2)np.stack:用于沿新轴连接数组序列
格式:
np.stack((ndarray1,ndarray2),axis)
参数解释:
参数名 描述 ndarray1,ndarray2, … 相同类型的数组 axis 返回数组中的轴,输入数组沿着它来堆叠 代码演示:
import numpy as np a = np.array([[1,2],[3,4]]) b = np.array([[5,6],[7,8]]) print(a,b,sep='\n') print ('沿轴 0 堆叠两个数组:') c = np.stack((a,b),0) print(c) print ('沿轴 1 堆叠两个数组:') d = np.stack((a,b),1) print (d) print(a.shape,b.shape,c.shape,d.shape,sep='\n') # [[1 2] # [3 4]] # [[5 6] # [7 8]] # 沿轴 0 堆叠两个数组: # [[[1 2] # [3 4]] # [[5 6] # [7 8]]] # 沿轴 1 堆叠两个数组: # [[[1 2] # [5 6]] # [[3 4] # [7 8]]] # (2, 2) # (2, 2) # (2, 2, 2) # (2, 2, 2)
(3)np.hstack:是 numpy.stack 函数的变体,它通过水平堆叠来生成数组
代码演示:
import numpy as np a = np.array([[1,2],[3,4]]) b = np.array([[5,6],[7,8]]) print(a,b,sep='\n') print('水平堆放:') c = np.hstack((a,b)) print(c) # [[1 2] # [3 4]] # [[5 6] # [7 8]] # 水平堆放: # [[1 2 5 6] # [3 4 7 8]]
(4)np.vstack:是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组
代码演示:
import numpy as np a = np.array([[1,2],[3,4]]) b = np.array([[5,6],[7,8]]) print(a,b,sep='\n') print('垂直堆放:') c = np.vstack((a,b)) print(c) # [[1 2] # [3 4]] # [[5 6] # [7 8]] # 垂直堆放: # [[1 2] # [3 4] # [5 6] # [7 8]]
3.3.5 分割数组
(1) np.split:沿特定的轴将数组分割为子数组
格式:
np.split(ndarray,indices_or_sections,axis)
参数解释
参数名 描述 ndarray 被分割的数组 indices_or_sections 如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭) axis 设置沿着哪个方向进行切分,默认为 0,横向切分,即水平方向。为 1 时,纵向切分,即竖直方向。 代码演示:
import numpy as np a = np.arange(9) print(a) print('将数组分为三个大小相等的子数组:') b = np.split(a,3) print(b) print('将数组在以为数组中表明的位置分割:') b = np.split(a,[4,7]) print(b) # [0 1 2 3 4 5 6 7 8] # 将数组分为三个大小相等的子数组: # [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])] # 将数组在以为数组中表明的位置分割: # [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
3.3.6 数组元素的添加与删除
(1)np.append:在数组的末尾添加值
追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。
append 函数返回的始终是一个一维数组。
格式:
numpy.append(ndarray, values, axis=None)
参数描述:
参数名 描述 ndarray 输入数组 ndarray 要向arr添加的值,需要和arr形状相同(除了要添加的轴) axis 默认为 None。当axis无定义时,是横向加成,返回总是为一维数组!当axis有定义的时候,分别为0和1的时候。当axis有定义的时候,分别为0和1的时候(列数要相同)。当axis为1时,数组是加在右边(行数要相同)。 代码演示:
import numpy as np a = np.array([[1,2,3],[4,5,6]]) print(a) b = np.append(a,[7,8,9]) print(b) print('沿0轴添加元素:') print(np.append(a,[[7,8,9]],axis=0)) print('沿1轴添加元素:') print(np.append(a,[[3,3,3],[7,8,9]],axis=1)) # [[1 2 3] # [4 5 6]] # [1 2 3 4 5 6 7 8 9] # 沿0轴添加元素: # [[1 2 3] # [4 5 6] # [7 8 9]] # 沿1轴添加元素: # [[1 2 3 3 3 3] # [4 5 6 7 8 9]]
(2)np.insert:在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
格式:
np.insert(ndarray, obj, values, axis)
参数说明:
参数名 描述 ndarray 输入数组 obj 在其之前插入值的索引 values 要插入的值 axis 沿着它插入的轴,如果未提供,则输入数组会被展开 代码演示:
import numpy as np a = np.array([[1,2],[3,4],[5,6]]) print(a) print('未传递axis参数.插入之前输入数组会被展开') print(np.insert(a,3,[11,12])) print('传递了axis参数.会使用广播值数组来匹配输入数组') print('沿轴0广播') print(np.insert(a,1,[11],axis=0)) print('沿轴1广播') print(np.insert(a,1,11,axis=1)) '''[[1 2] [3 4] [5 6]] 未传递axis参数.插入之前输入数组会被展开 [ 1 2 3 11 12 4 5 6] 传递了axis参数.会使用广播值数组来匹配输入数组 沿轴0广播 [[ 1 2] [11 11] [ 3 4] [ 5 6]] 沿轴1广播 [[ 1 11 2] [ 3 11 4] [ 5 11 6]]'''
(3) np.delete:返回从输入数组中删除指定子数组的新数组。
函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开
格式:
numpy.delete(ndarray, obj, axis)
参数说明:
参数名 描述 ndarray 输入数组 obj 可以被切片,整数或者整数数组,表明要从输入数组删除的子数组 axis 沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开 代码演示:
import numpy as np a = np.arange(12).reshape(3,4) print(a) print ('未传递 Axis 参数。 在插入之前输入数组会被展开。') print (np.delete(a,5)) print('删除第二列:') print(np.delete(a,1,axis=1)) print('包含从数组中删除的替代值的切片:') a = np.arange(1,11) print(a) print(np.delete(a,np.s_[::2]))
4.1 Numpy字符串函数
4.2 Numpy数字函数
NumPy 包含大量的各种数学运算的函数,包括三角函数,算术运算的函数,复数处理函数等。
4.2.1 三角函数
NumPy 提供了标准的三角函数:sin()、cos()、tan(),以及arcsin,arccos,和 arctan 函数返回给定角度的 sin,cos 和 tan 的反三角函数。
代码示例:
import numpy as np
a = np.array([0,30,45,60,90])
print('不同角度的正弦值:')
# 通过乘pi/180转换为弧度
print(np.sin(a*np.pi/180))
print('数组角度的余弦值:')
print(np.cos(a*np.pi/180))
print('数组角度的正切值:')
print(np.tan(a*np.pi/180))
4.2.2 舍入函数
- numpy.around(ndarray,decimals = 0):返回指定数字的四舍五入值;decimals: 舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
- numpy.floor():返回小于或者等于指定表达式的最大整数,即向下取整
- numpy.ceil():返回大于或者等于指定表达式的最小整数,即向上取整
代码演示:
import numpy as np
a = np.array([1.0,5.55,123,0.5673,25.5342])
print(a)
print('四舍五入后:')
print(np.around(a))
print(np.around(a,decimals=1))
print(np.around(a,decimals=-1))
# 向上取整
print(np.floor(a))
# 向下取整
print(np.ceil(a))
4.3 Numpy统计函数
NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等。 函数说明如下:
4.3.1 numpy.amin() 和 numpy.amax()
numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
numpy.amax() 用于计算数组中的元素沿指定轴的最大值。
代码演示:
import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print(a)
print('调用amin()')
print(np.amin(a,0))
print('调用amax()')
print(np.amax(a))
print("再次调用amax()")
print(np.amax(a,axis=0))
4.3.1 numpy.percentile()
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。
格式:
numpy.percentile(ndarray,q,axis)
参数说明:
参数名 | 描述 |
---|---|
ndarray | 输入数组 |
q | 要计算的百分位数,在 0 ~ 100 之间 |
axis | 沿着它计算百分位数的轴 |
首先明确百分位数:
第 p 个百分位数是这样一个值,它使得至少有 p% 的数据项小于或等于这个值,且至少有 (100-p)% 的数据项大于或等于这个值。
举个例子:高等院校的入学考试成绩经常以百分位数的形式报告。比如,假设某个考生在入学考试中的语文部分的原始分数为 54 分。相对于参加同一考试的其他学生来说,他的成绩如何并不容易知道。但是如果原始分数54分恰好对应的是第70百分位数,我们就能知道大约70%的学生的考分比他低,而约30%的学生考分比他高。p=70
代码演示:
import numpy as np
a = np.array([[10,7,4],[3,2,1]])
print(a)
print('调用percentile()函数:')
# 注意:50%的分位数,就是在a里面排序之后的中位数
print(np.percentile(a,50))
# aixs为0 ,在纵列上求
print(np.percentile(a,50,axis=0))
# aixs为1 ,在横行上求
print(np.percentile(a,50,axis=1))
# 保持维度不变
print(np.percentile(a,50,axis=1,keepdims=True))
'''
[[10 7 4]
[ 3 2 1]]
调用percentile()函数:
3.5
[6.5 4.5 2.5]
[7. 2.]
[[7.]
[2.]]
'''
4.3.2 numpy.median()
numpy.median(a, axis) 函数用于计算数组 a 中元素的中位数(中值)
4.3.3 numpy.mean()
numpy.mean(a, axis) 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。算术平均值是沿轴的元素的总和除以元素的数量。
4.3.4 numpy.average()
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。
该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。
加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。
例如:
数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。
import numpy as np
a = np.array([1,2,3,4])
print(a)#[1 2 3 4]
# 不指定权重时相当于mean()函数
print(np.average(a))#2.5
# 当指定权重时才相当于加权平均数
wts = np.array([4,3,2,1])
print(np.average(a,weights=wts))#2.0
# 加权平均值相当于
print((1*4+2*3+3*2+4*1)/(4+3+2+1))#2.0
4.3.5 标准差numpy.std()
标准差是一组数据平均值分散程度的一种度量。 标准差是方差的算术平方根。
公式:
std = sqrt(mean((x - x.mean())**2))
代码:
import numpy as np
print(np.std([1,2,3,4]))
4.3.6 方差numpy.var()
统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即 mean((x - x.mean())** 2)。 换句话说,标准差是方差的平方根。
代码:
import numpy as np
print (np.var([1,2,3,4]))
4.3.6 numpy.sort():函数返回输入数组的排序副本
格式:
numpy.sort(ndarray,axis,kind,order)
参数解释
:
参数名 | 作用 |
---|---|
ndarray | 要排序的数组 |
axis | 沿着它排序数组的轴, axis=0 按列排序,axis=1 按行排序 |
kind | 默认为’quicksort’(快速排序) |
order | 如果数组包含字段,则是要排序的字段 |
代码演示:
import numpy as np
a = np.array([[3,7],[9,1]])
print(a)
# 按列排序
print(np.sort(a,axis=0))
# 按行排列
print(np.sort(a,axis=1))
4.3.7 numpy.argsort()
numpy.argsort() 函数返回的是数组值从小到大的索引值。
4.3.8 numpy.argmax() 和 numpy.argmin()
numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。
4.3.9 numpy.where():返回输入数组中满足给定条件的元素的索引
代码演示:
import numpy as np
a = np.arange(9.).reshape(3,3)
print(a)
print('元素值大于3的索引:')
b = np.where(a>3)
print(b)
print('使用这些索引来获取满足条件的元素:')
print(a[b])
'''
[[0. 1. 2.]
[3. 4. 5.]
[6. 7. 8.]]
元素值大于3的索引:
(array([1, 1, 2, 2, 2], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))
使用这些索引来获取满足条件的元素:
[4. 5. 6. 7. 8.]
'''
4.3.10 numpy.extract():根据某个条件从数组中抽取元素,返回满条件的元素
代码演示:
import numpy as np
a = np.arange(9.).reshape(3,3)
print(a)
# 定义选择偶数元素的条件
condition = np.mod(a,2) == 0
print('每个元素是否符合的的条件值:')
print(condition)
print('使用条件提取元素:')
print(np.extract(condition,a))
'''
[[0. 1. 2.]
[3. 4. 5.]
[6. 7. 8.]]
每个元素是否符合的的条件值:
[[ True False True]
[False True False]
[ True False True]]
使用条件提取元素:
[0. 2. 4. 6. 8.]
'''
4.4 Numpy副本与视图
副本
是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响
到原始数据,物理内存不在同一位置
。
视图是数据的一个别称或引用
,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响
到原始数据,物理内存在同一位置
。
视图
一般发生在:
(1). numpy 的切片操作
返回原数据的视图。
(2). 调用 ndarray 的 view() 函数产生一个视图。
副本
一般发生在:
(1). Python 序列
的切片操作,调用deepCopy()函数。
(2). 调用 ndarray 的 copy() 函数产生一个副本。
赋值操作:
简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()来访问它。 id()返回 Python 对象的通用标识符,类似于 C 中的指针。
因此,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。
代码演示:
import numpy as np
a = np.arange(6)
print(a)
b = a
print('a:',id(a),'b:',id(b),sep='\n')
b.shape = 2,3
# b的形状改变了,a的形状也跟着改变了
print(a.shape)
4.4.1 视图或浅拷贝
ndarray.view() 方会创建一个新的数组对象,该方法创建的新数组的维数变化不会改变原始数据的维数。
代码演示:
import numpy as np
a = np.arange(6).reshape(3,2)
print(a)
print('a的视图:')
b = a.view()
print(b)
print(id(a),id(b))
print('修改b的形状,a并不会被改变')
b.shape = 2,3
print(a.shape)
print(b.shape)
# [[0 1]
# [2 3]
# [4 5]]
# a的视图:
# [[0 1]
# [2 3]
# [4 5]]
# 2068573437072 2068573432752
# 修改b的形状,a并不会被改变
# (3, 2)
# (2, 3)
而使用切片创建视图修改数据会影响到原始数组,代码示例如下:
import numpy as np
a = np.arange(12)
print(a)#[ 0 1 2 3 4 5 6 7 8 9 10 11]
print('创建切片:')#创建切片:
a1 = a[3:]
a2 = a[3:]
a1[1] = 23
a2[2] = 45
print(a)#[ 0 1 2 3 23 45 6 7 8 9 10 11]
print(id(a),id(a1),id(a2))#2068543592496 2068543596912 2068543596240
解释:
变量 a,b 都是 arr 的一部分视图,对视图的修改会直接反映到原数据中。但是我们观察 a,b 的 id,他们是不同的,也就是说,视图虽然指向原数据,但是他们和赋值引用还是有区别的。
4.4.2 副本或深拷贝
ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。
代码演示:
import numpy as np
a = np.array([[10,10],[2,3],[7,8]])
print(a)
print('创建a的副本:')
b = a.copy()
print(b)
# a 与 b 是完全不想关的,不能通过修改b来让a也被修改
b[1,1] = 1000
print('修改b之后:')
print(b)
print(a)
loadtxt读取txt文本,csv文件,返回从文件中读取的数组
格式:
loadtxt(fname,dtype=,coomments = “#”,delimiter = None,converters = None,skiprows =0,usercols =None,unpack = False,ndmin=0,encoding = ‘bytes’)
参数解释:
参数名 | 作用 |
---|---|
fname | 指定文件名称或路径.支持压缩文件,包括.gz.bz格式 |
dtype | 元素数据类型.默认float |
comments | 表示注释字符集开始的标志,默认为#.参数类型为字符串或字符串组成的列表. |
delimiter | 分隔符,字符串 |
converters | 字典.将特定列的数据转换为字典中对应函数的浮点型数据,默认为空.例如,将空值替换为0 |
skiprows | 跳过特定行数据,默认为0.例如,跳过可能是注释或标题的第一行 |
usecols | 用来指定要读取数据的列,默认为空.第一列为0,列如(1,3,5) |
unpack | 指定是否转置数组,如果为True则转置,默认为Fasle |
ndmin | 整数型.指定返回的数组至少包含特定的数组.值域为0\1\2,默认为0 |
encoding | 编码格式,确定文件是用utf-8还会gbk等 |
原数据中。但是我们观察 a,b 的 id,他们是不同的,也就是说,视图虽然指向原数据,但是他们和赋值引用还是有区别的。
4.4.2 副本或深拷贝
ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。
代码演示:
import numpy as np
a = np.array([[10,10],[2,3],[7,8]])
print(a)
print('创建a的副本:')
b = a.copy()
print(b)
# a 与 b 是完全不想关的,不能通过修改b来让a也被修改
b[1,1] = 1000
print('修改b之后:')
print(b)
print(a)
loadtxt读取txt文本,csv文件,返回从文件中读取的数组
格式:
loadtxt(fname,dtype=,coomments = “#”,delimiter = None,converters = None,skiprows =0,usercols =None,unpack = False,ndmin=0,encoding = ‘bytes’)
参数解释:
参数名 | 作用 |
---|---|
fname | 指定文件名称或路径.支持压缩文件,包括.gz.bz格式 |
dtype | 元素数据类型.默认float |
comments | 表示注释字符集开始的标志,默认为#.参数类型为字符串或字符串组成的列表. |
delimiter | 分隔符,字符串 |
converters | 字典.将特定列的数据转换为字典中对应函数的浮点型数据,默认为空.例如,将空值替换为0 |
skiprows | 跳过特定行数据,默认为0.例如,跳过可能是注释或标题的第一行 |
usecols | 用来指定要读取数据的列,默认为空.第一列为0,列如(1,3,5) |
unpack | 指定是否转置数组,如果为True则转置,默认为Fasle |
ndmin | 整数型.指定返回的数组至少包含特定的数组.值域为0\1\2,默认为0 |
encoding | 编码格式,确定文件是用utf-8还会gbk等 |