1. NumPy ndarray对象
NumPy 定义了一个 n 维数组对象,简称 ndarray 对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块,您可以使用索引或切片的方式获取数组中的每个元素。
ndarray 对象采用了数组的索引机制,将数组中的每个元素映射到内存块上,并且按照一定的布局对内存块进行排列,常用的布局方式有两种,即按行或者按列。
1.1创建ndarray对象
通过 NumPy 的内置函数 array() 可以创建 ndarray 对象,其语法格式如下:
numpy.array(object, dtype = None, copy = True, order = None,ndmin = 0)
下面表格对其参数做了说明:
序号 | 参数 | 描述说明 |
---|---|---|
1 | object | 表示一个序列。 |
2 | dtype | 可选参数,通过它可以更改数组的数据类型。 |
3 | copy | 可选参数,表示数组能否被复制,默认是 True。 |
4 | order | 以哪种内存布局创建数组,有 3 个可选值,分别是 C(行序列)/F(列序列)/A(默认)。 |
5 | ndmin | 用于指定数组的维度。 |
import numpy
a=numpy.array([1,2,3])#使用列表构建一维数组
print(a)
[1 2 3]
print(type(a))
#ndarray数组类型
<class 'numpy.ndarray'>
b=numpy.array([[1,2,3],[4,5,6]])
print(b)
[[1 2 3]
[4 5 6]]
如果要改变数组元素的数据类型,可以使用通过设置 dtype,如下所示:
c=numpy.array([2,4,6,8],dtype="数据类型名称")
现在将 c 数组中的元素类型变成了复数类型:
c=numpy.array([2,4,6,8],dtype="complex")
print(c)
[2.+0.j 4.+0.j 6.+0.j 8.+0.j]
1.2ndim查看数组维数
通过 ndim 可以查看数组的维度:
import numpy as np
arr = np.array([[1, 2, 3, 4], [4, 5, 6, 7], [9, 10, 11, 23]])
print(arr.ndim)
2
您也可以使用 ndim 参数创建不同维度的数组:
#输出一个二维数组
import numpy as np
#ndim参数会报错,应改为ndmin
a = np.array([1, 2,3,4,5], ndmin = 2)
print(a)
输出结果如下:
[[1 2 3 4 5]]
2. NumPy数据类型
序号 | 数据类型 | 语言描述 |
---|---|---|
1 | bool_ | 布尔型数据类型(True 或者 False) |
2 | int_ | 默认整数类型,类似于 C 语言中的 long,取值为 int32 或 int64 |
3 | intc | 和 C 语言的 int 类型一样,一般是 int32 或 int 64 |
4 | intp | 用于索引的整数类型(类似于 C 的 ssize_t,通常为 int32 或 int64) |
5 | int8 | 代表与1字节相同的8位整数。值的范围是-128到127。 |
6 | int16 | 代表 2 字节(16位)的整数。范围是-32768至32767。 |
7 | int32 | 代表 4 字节(32位)整数。范围是-2147483648至2147483647。 |
8 | int64 | 表示 8 字节(64位)整数。范围是-9223372036854775808至9223372036854775807。 |
9 | uint8 | 代表1字节(8位)无符号整数。 |
10 | uint16 | 2 字节(16位)无符号整数。 |
11 | uint32 | 4 字节(32位)的无符号整数。 |
12 | uint64 | 8 字节(64位)的无符号整数。 |
13 | float_ | float64 类型的简写。 |
14 | float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10个尾数位。 |
15 | float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23个尾数位。 |
16 | float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52个尾数位。 |
17 | complex_ | 复数类型,与 complex128 类型相同。 |
18 | complex64 | 表示实部和虚部共享 32 位的复数。 |
19 | complex128 | 表示实部和虚部共享 64 位的复数。 |
20 | str_ | 表示字符串类型 |
21 | string_ | 表示字节串类型 |
2.1数据类型对象
数据类型对象(Data Type Object)又称 dtype 对象,主要用来描述数组元素的数据类型、大小以及字节顺序。同时,它也可以用来创建结构化数据。比如常见的 int64、float32 都是 dtype 对象的实例,其语法格式如下:
np.dtype(object)
创建一个 dtype 对象可以使用下列方法:
import numpy as np
a= np.dtype(np.int64)
print(a)
输出结果:
int64
2.2数据类型标识码
NumPy 中每种数据类型都有一个唯一标识的字符码,如下所示:
字符 | 对应类型 |
---|---|
b | 代表布尔型 |
i | 带符号整型 |
u | 无符号整型 |
f | 浮点型 |
c | 复数浮点型 |
m | 时间间隔(timedelta) |
M | datatime(日期时间) |
O | Python对象 |
S,a | 字节串(S)与字符串(a) |
U | Unicode |
V | 原始数据(void) |
下面使用数据类型标识码,创建一组结构化数据:
#创建数据类型score
import numpy as np
dt = np.dtype([('score','i1')])
print(dt)
输出如下:
[('score', 'i1')]
将上述的数据类型对象 dt,应用到 ndarray 中:
#定义字段名score,以及数组数据类型i1
dt = np.dtype([('score','i1')])
a = np.array([(55,),(75,),(85,)], dtype = dt)
print(a)
print(a.dtype)
print(a['score'])
输出结果:
获取a数组:
[(55,) (75,) (85,)]
数据类型对象dtype
dtype([('score', 'i1')])
获取'score'字段分数
[55 75 85]
2.3定义结构化数据
通常情况下,结构化数据使用字段的形式来描述某个对象的特征。以下示例描述一位老师的姓名、年龄、工资的特征,该结构化数据其包含以下字段:
- str 字段:name
- int 字段:age
- float 字段:salary
定义过程如下:
import numpy as np
teacher = np.dtype([('name','S20'), ('age', 'i1'), ('salary', 'f4')])
#输出结构化数据teacher
print(teacher)
#将其应用于ndarray对象
b = np.array([('ycs', 32, 6357.50),('jxe', 28, 6856.80)], dtype = teacher)
print(b)
输出结果:
[('name', 'S20'), ('age', 'i1'), ('salary', '<f4')]
#输出的name为bytes字节串类型
[(b'ycs', 32, 6357.5) (b'jxe', 28, 6856.8)]
3. NumPy数组属性
3.1ndarray.itemsize
返回数组中每个元素的大小(以字节为单位),示例如下:
#数据类型为int8,代表1字节
import numpy as np
x = np.array([1,2,3,4,5], dtype = np.int8)
print (x.itemsize)
输出结果为:
1
#数据类型为int64,代表8字节
import numpy as np
x = np.array([1,2,3,4,5], dtype = np.int64)
print (x.itemsize)
输出结果:
8
3.2ndarray.flags
返回 ndarray 数组的内存信息,比如 ndarray 数组的存储方式,以及是否是其他数组的副本等。
示例如下:
import numpy as np
x = np.array([1,2,3,4,5])
print (x.flags)
输出结果如下:
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
4. Numpy创建数组
4.1numpy.empty()
numpy.empty() 创建未初始化的数组,可以指定创建数组的形状(shape)和数据类型(dtype),语法格式如下:
numpy.empty(shape, dtype = float, order = 'C')
它接受以下参数:
- shape:指定数组的形状;
- dtype:数组元素的数据类型,默认值是值 float;
- order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(行优先顺序)。
使用示例如下:
import numpy as np
arr = np.empty((3,2), dtype = int)
print(arr)
输出结果:
[[2003134838 175335712]
[ 538976288 538976288]
[1970562418 1684369010]]
可以看到,numpy.empty() 返回的数组带有随机值,但这些数值并没有实际意义。切记 empty 并非创建空数组。
4.2numpy.zeros()
该函数用来创建元素均为 0 的数组,同时还可以指定被数组的形状,语法格式如下:
numpy. zeros(shape,dtype=float,order="C")
参数名称 | 说明描述 |
---|---|
shape | 指定数组的形状大小。 |
dtype | 可选项,数组的数据类型 |
order | “C”代表以行顺序存储,“F”则表示以列顺序存储 |
示例如下:
import numpy as np
#默认数据类型为浮点数
a=np.zeros(6)
print(a)
b=np.zeros(6,dtype="complex64" )
print(b)
输出结果:
#a数组
[0. 0. 0. 0. 0. 0.]
#b数组
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
也可以使用自定义的数据类型创建数组,如下所示:
import numpy as np
c = np.zeros((3,3), dtype = [('x', 'i4'), ('y', 'i4')])
print(c)
#输出x,y,并指定的数据类型
[[(0, 0) (0, 0) (0, 0)]
[(0, 0) (0, 0) (0, 0)]
[(0, 0) (0, 0) (0, 0)]]
4.3numpy.ones()
返回指定形状大小与数据类型的新数组,并且新数组中每项元素均用 1 填充,语法格式如下:
numpy.ones(shape, dtype = None, order = 'C')
示例如下:
import numpy as np
arr1 = np.ones((3,2), dtype = int)
print(arr1)
输出结果如下:
[[1 1] [1 1] [1 1]]
下面介绍如何使用 Python 列表、流对象、可迭代对象来创建一个 NumPy 数组。
4.4numpy.asarray()
asarray() 与 array() 类似,但是它比 array() 更为简单。asarray() 能够将一个 Python 序列转化为 ndarray 对象,array()同样能接收python序列,语法格式如下:
numpy.asarray(sequence,dtype = None ,order = None )
它接受下列参数:
- sequence:接受一个 Python 序列,可以是列表或者元组;
- dtype:可选参数,数组的数据类型;
- order:数组内存布局样式,可以设置为 C 或者 F,默认是 C。
示例 1,将列表转化为 numpy 数组:
import numpy as np
l=[1,2,3,4,5,6,7]
a = np.asarray(l);
print(type(a))
print(a)
输出结果如下所示:
#a数组类型
<class 'numpy.ndarray'>
#a数组
[1 2 3 4 5 6 7]
示例 2,使用元组创建 numpy 数组:
import numpy as np
l=(1,2,3,4,5,6,7)
a = np.asarray(l);
print(type(a))
print(a)
输出结果如下:
<class 'numpy.ndarray'>
[1 2 3 4 5 6 7]
示例 3,使用嵌套列表创建多维数组:
import numpy as np
l=[[1,2,3,4,5,6,7],[8,9]]
a = np.asarray(l);
# a = np.asarray(l,dtype=object);
print(type(a))
print(a)
输出结果:
<class 'numpy.ndarray'>
[list([1, 2, 3, 4, 5, 6, 7]) list([8, 9])]
VisibleDeprecationWarning:从不规则的嵌套序列(这是具有不同长度或形状的列表或元组或 ndarray 的列表或元组)创建 ndarray。如果您打算这样做,则必须在创建 ndarray 时指定 “dtype=object”。
a = np.asarray(l)
4.5numpy.fromiter()
该方法可以把迭代对象转换为 ndarray 数组,其返回值是一个一维数组。
numpy.fromiter(iterable, dtype, count = -1)
参数说明如下:
参数名称 | 描述说明 |
---|---|
iterable | 可迭代对象。 |
dtype | 返回数组的数据类型。 |
count | 读取的数据数量,默认为 -1,读取所有数据。 |
示例5:使用内置 range() 函数创建列表对象,然后使用迭代器创建 ndarray 对象,代码如下:
import numpy as np
# 使用 range 函数创建列表对象
list=range(6)
#生成可迭代对象i
i=iter(list)
#使用i迭代器,通过fromiter方法创建ndarray
array=np.fromiter(i, dtype=float)
print(array)
输出结果:
[0. 1. 2. 3. 4. 5.]
5. NumPy创建区间数组
所谓区间数组,是指数组元素的取值位于某个范围内,并且数组元素之间可能会呈现某种规律,比如等比数列、递增、递减等。
5.1 numpy.arange()
在 NumPy 中,您可以使用 arange() 来创建给定数值范围的数组,语法格式如下:
numpy.arange(start, stop, step, dtype)
参数说明见下表:
参数名称 | 参数说明 |
---|---|
start | 起始值,默认是 0。 |
stop | 终止值,注意生成的数组元素值不包含终止值。 |
step | 步长,默认为 1。 |
dtype | 可选参数,指定 ndarray 数组的数据类型。 |
根据start
与stop
指定的范围以及step
步长值,生成一个 ndarray 数组,示例如下。
import numpy as np
x = np.arange(8)
print (x)
输出结果如下所示:
[0 1 2 3 4 5 6 7]
设置 start 、stop 值以及步长,最终输出 0-10 中的奇数:
import numpy as np
x = np.arange(1,10,2)
print (x)
输出结果如下所示:
[1 3 5 7 9]
5.2 numpy.linspace()
表示在指定的数值区间内,返回均匀间隔的一维等差数组,默认均分 50 份,语法格式如下:
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数说明如下:
- start:代表数值区间的起始值;
- stop:代表数值区间的终止值;
- num:表示数值区间内要生成多少个均匀的样本。默认值为 50;
- endpoint:默认为 True,表示数列包含 stop 终止值,反之不包含;
- retstep:默认为 True,表示生成的数组中会显示公差项,反之不显示;
- dtype:代表数组元素值的数据类型。
示例如下:
import numpy as np
#生成10个样本
a = np.linspace(1,10,10)
print(a)
输出结果:
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
下面示例是 endpoint 为 Fasle 时,此时不包含终止值:
import numpy as np
arr = np.linspace(10, 20, 5, endpoint = False)
print("数组数值范围 :",arr)
输出结果如下:
数组数值范围 : [10. 12. 14. 16. 18.]
retstep 参数使用示例如下:
import numpy as np
x = np.linspace(1,2,5, retstep = True)
print(x)
输出结果如下,其中 0.25 为等差数列的公差:
(array([1. , 1.25, 1.5 , 1.75, 2. ]), 0.25)
5.3 numpy.logspace
该函数同样返回一个 ndarray 数组,它用于创建等比数组,语法格式如下:
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
其中 base 代表对数函数的底数,默认为 10,参数详细说明见下表:
参数名称 | 说明描述 |
---|---|
start | 序列的起始值:base**start。 |
stop | 序列的终止值:base**stop。 |
num | 数值范围区间内样本数量,默认为 50。 |
endpoint | 默认为 True 包含终止值,反之不包含。 |
base | 对数函数的 log 底数,默认为10。 |
dtype | 可选参数,指定 ndarray 数组的数据类型。 |
使用示例如下:
import numpy as np
a = np.logspace(1.0,2.0, num = 10)
print (a)
输出结果:
[ 10. 12.91549665 16.68100537 21.5443469 27.82559402
35.93813664 46.41588834 59.94842503 77.42636827 100. ]
下面是 base = 2 的对数函数,示例如下:
import numpy as np
a = np.logspace(1,10,num = 10, base = 2)
print(a)
输出结果:
[ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]
6. random创建数组
6.1 np.random.randn()函数(n表示标志正态分布)
语法:
np.random.randn(d0,d1,d2……dn)
- randn函数根据给定维度生成[0,1)之间的数据,包含0,不包含1
- dn表示每个维度
- 返回值为指定维度的array
1)当函数括号内没有参数时,则返回一个浮点数;
2)当函数括号内有一个参数时,则返回秩为1的数组,不能表示向量和矩阵;
3)当函数括号内有两个及以上参数时,则返回对应维度的数组,能表示向量或矩阵;
4)np.random.standard_normal()函数与np.random.randn()类似,但是np.random.standard_normal()的输入参数为元组(tuple).
5)np.random.randn()的输入通常为整数,但是如果为浮点数,则会自动直接截断转换为整数。(其实就是整数)
作用:
通过本函数可以返回一个或一组服从标准正态分布的随机样本值。
特点:
标准正态分布是以0为均数、以1为标准差的正态分布,记为N(0,1)。对应的正态分布曲线如下所示,即
标准正态分布曲线下面积分布规律是:
在-1.96~+1.96范围内曲线下的面积等于0.9500(即取值在这个范围的概率为95%),在-2.58~+2.58范围内曲线下面积为0.9900(即取值在这个范围的概率为99%).
因此,由 np.random.randn()函数所产生的随机样本基本上取值主要在-1.96~+1.96之间,当然也不排除存在较大值的情形,只是概率较小而已。
应用场景:
在神经网络构建中,权重参数W通常采用该函数进行初始化,当然需要注意的是,通常会在生成的矩阵后面乘以小数,比如0.01,目的是为了提高梯度下降算法的收敛速度。
W = np.random.randn(2,2)*0.01
6.2 np.random.rand()函数(没有n,0~1均匀分布)
语法:
np.random.rand(d0,d1,d2……dn)
注:使用方法与np.random.randn()函数相同
作用:
通过本函数可以返回一个或一组服从“0~1”均匀分布的随机样本值。随机样本取值范围是[0,1),不包括1。
应用场景:
在深度学习的Dropout正则化方法中,可以用于生成dropout随机向量(dl),例如(keep_prob表示保留神经元的比例):dl = np.random.rand(al.shape[0],al.shape[1]) < keep_prob
6.3 np.random.randint()函数(返回区间内随机整数)
语法:
numpy.random.randint(low, high=None, size=None, dtype=’l’)
输入:
low—–为最小值
high—-为最大值
size—–为数组维度大小
dtype—为数据类型,默认的数据类型是np.int。
返回值:
返回随机整数或整型数组,范围区间为[low,high),包含low,不包含high;
high没有填写时,默认生成随机数的范围是[0,low)
6.4 生成[0,1)之间的浮点数
numpy.random.random_sample(size=None)
numpy.random.random(size=None)
numpy.random.ranf(size=None)
numpy.random.sample(size=None)
print('-----------random_sample--------------')
print(np.random.random_sample(size=(2,2)))
print('-----------random--------------')
print(np.random.random(size=(2,2)))
print('-----------ranf--------------')
print(np.random.ranf(size=(2,2)))
print('-----------sample--------------')
print(np.random.sample(size=(2,2)))
-----------random_sample--------------
[[ 0.34966859 0.85655008]
[ 0.16045328 0.87908218]]
-----------random--------------
[[ 0.25303772 0.45417512]
[ 0.76053763 0.12454433]]
-----------ranf--------------
[[ 0.0379055 0.51288667]
[ 0.71819639 0.97292903]]
-----------sample--------------
[[ 0.59942807 0.80211491]
[ 0.36233939 0.12607092]]
6.5 numpy.random.choice()
numpy.random.choice(a, size=None, replace=True, p=None)
- 从给定的一维数组中生成随机数
- 参数: a为一维数组类似数据或整数;size为数组维度;p为数组中的数据出现的概率
- a为整数时,对应的一维数组为np.arange(a)
np.random.choice(5,3)
array([4, 1, 4])
np.random.choice(5, 3, replace=False)
# 当replace为False时,生成的随机数不能有重复的数值
array([0, 3, 1])
np.random.choice(5,size=(3,2))
array([[1, 0],
[4, 2],
[3, 3]])
demo_list = ['lenovo', 'sansumg','moto','xiaomi', 'iphone']
np.random.choice(demo_list,size=(3,3))
array([['moto', 'iphone', 'xiaomi'],
['lenovo', 'xiaomi', 'xiaomi'],
['xiaomi', 'lenovo', 'iphone']],
dtype='<U7')
- 参数p的长度与参数a的长度需要一致;
- 参数p为概率,p里的数据之和应为1
demo_list = ['lenovo', 'sansumg','moto','xiaomi', 'iphone']
np.random.choice(demo_list,size=(3,3), p=[0.1,0.6,0.1,0.1,0.1])
array([['sansumg', 'sansumg', 'sansumg'],
['sansumg', 'sansumg', 'sansumg'],
['sansumg', 'xiaomi', 'iphone']],
dtype='<U7')
6.6 numpy.random.seed()
- np.random.seed()的作用:使得随机数据可预测。
- 当我们设置相同的seed,每次生成的随机数相同。如果不设置seed,则每次会生成不同的随机数
np.random.seed(0)
np.random.rand(5)
array([ 0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.seed(1676)
np.random.rand(5)
array([ 0.39983389, 0.29426895, 0.89541728, 0.71807369, 0.3531823 ])
np.random.seed(1676)
np.random.rand(5)
array([ 0.39983389, 0.29426895, 0.89541728, 0.71807369, 0.3531823 ])
7. NumPy遍历数组
NumPy 提供了一个 nditer 迭代器对象,它可以配合 for 循环完成对数组元素的遍历。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
#使用nditer迭代器,并使用for进行遍历
for x in np.nditer(a):
print(x)
输出结果:
0 5 10 15 20 25 30 35 40 45 50 55
7.1 遍历顺序
在内存中,Numpy 数组提供了两种存储数据的方式,分别是 C-order(行优先顺序)与 Fortrant-order(列优先顺序)。那么 nditer 迭代器又是如何处理具有特定存储顺序的数组呢?其实它选择了一种与数组内存布局一致的顺序,之所以这样做,是为了提升数据的访问效率。
在默认情况下,当我们遍历数组中元素的时候,不需要考虑数组的存储顺序,这一点可以通过遍历上述数组的转置数组来验证。
示例 2:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
#a的转置数组
b = a.T
print (b)
for x in np.nditer(b):
print(x,end=",")
输出结果:
#转置数组b
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
#a转置后的遍历输出
0,5,10,15,20,25,30,35,40,45,50,55,
从示例 1、2 的输出结果可以看出,a 和 a.T 的遍历顺序是一样的,也就是说,它们在内存中的存储顺序是一样的。
下面以 C 样式访问转置数组的副本。示例 3 如下:
import numpy as np
a = np.arange(0,60,5).reshape(3,4)
#copy方法生成数组副本
for x in np.nditer(a.T.copy(order='C')):
print (x, end=", " )
输出结果:
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,
通过示例 3 可知 a.T.copy(order = ‘C’) 的遍历结果与示例 1、2 的数组遍历结果不一样。究其原因,就是因为它们在内存中的存储方式不一样。
7.2 指定遍历顺序
您可以通过 nditer 对象的order
参数来指定数组的遍历的顺序。示例 4 如下:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print(a)
for x in np.nditer(a, order = 'C'):
print (x,end=",")
for x in np.nditer(a, order = 'F'):
print (x,end=",")
输出结果如下:
#c=order行顺序
0,5,10,15,20,25,30,35,40,45,50,55,
#F-order列顺序
0,20,40,5,25,45,10,30,50,15,35,55,
7.3 修改数组元素值
nditer 对象提供了一个可选参数op_flags
,它表示能否在遍历数组时对元素进行修改。它提供了三种模式,如下所示:
7.3.1 read-only
只读模式,在这种模式下,遍历时不能修改数组中的元素。
7.3.2 read-write
读写模式,遍历时可以修改元素值。
7.3.3 write-only
只写模式,在遍历时可以修改元素值。
示例如下:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ("原数组是:",a)
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改后的数组是:',a)
最后输出结果如下:
原数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
[[ 0 10 20 30]
[ 40 50 60 70]
[ 80 90 100 110]]
7.4 外部循环使用
nditer 对象的构造函数有一个“flags”参数,它可以接受以下参数值(了解即可):
参数值 | 描述说明 |
---|---|
c_index | 可以跟踪 C 顺序的索引。 |
f_index | 可以跟踪 Fortran 顺序的索引。 |
multi_index | 每次迭代都会跟踪一种索引类型。 |
external_loop | 返回的遍历结果是具有多个值的一维数组。 |
示例 6 如下:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print("原数组",a)
#修改后数组
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print(x)
结果输出:
原数组:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
#修改后的一维数组
[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]
7.5迭代多个数组
如果两个数组都能够被广播,那么 nditer 对象就可以同时对它们迭代。
假设数组 a 的维度是 34,另一个数组 b 的维度是 14 (即维度较小的数组 b 可以被广播到数组 a 中),示例如下:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print (a)
b = np.array([1, 2, 3, 4], dtype = int)
print (b)
#广播迭代
for x,y in np.nditer([a,b]):
print ("%d:%d" % (x,y),end=",")
输出结果是:
0:1,5:2,10:3,15:4,20:1,25:2,30:3,35:4,40:1,45:2,50:3,55:4,
8. NumPy相关数组操作
NumPy 中包含了一些处理数组的常用方法,大致可分为以下几类:
- 数组变维操作
- 数组转置操作
- 修改数组维度操作
- 连接与分割数组操作
8. 数组变维操作
函数名称 | 函数介绍 |
---|---|
reshape | 在不改变数组元素的条件下,修改数组的形状。 |
flat | 返回是一个迭代器,可以用 for 循环遍历其中的每一个元素。 |
flatten | 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。 |
ravel | 返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)。 |
1) numpy.ndarray.flat(返回数组迭代器)
numpy.ndarray.flat 返回一个数组迭代器,实例如下:
import numpy as np
a = np.arange(9).reshape(3,3)
for row in a:
print (row)
#使用flat属性:
for ele in a.flat:
print (ele,end=",")
输出结果如下:
#原数组
[0 1 2]
[3 4 5]
[6 7 8]
#输出元素
0,1,2,3,4,5,6,7,8,
2) numpy.ndarray.flatten()(返回副本)
numpy.ndarray.flatten 返回一份数组副本,对副本修改不会影响原始数组,其语法格式如下:
ndarray.flatten(order='C')
实例如下:
import numpy as np
a = np.arange(8).reshape(2,4)
print (a)
#默认按行C风格展开的数组
print (a.flatten())
#以F风格顺序展开的数组
print (a.flatten(order = 'F'))
输出结果:
#数组a
[[0 1 2 3]
[4 5 6 7]]
#默认c顺序站看数组
[0 1 2 3 4 5 6 7]
# F顺序站看数组
[0 4 1 5 2 6 3 7]
3) numpy.ravel()(返回视图)
numpy.ravel() 将多维数组中的元素以一维数组的形式展开,该方法返回数组的视图(view),如果修改,则会影响原始数组。
numpy.ravel(a, order='C')
实例结果如下:
import numpy as np
a = np.arange(8).reshape(2,4)
print ('原数组:')
print (a)
print ('调用 ravel 函数后:')
print (a.ravel())
print ('F 风格顺序调用 ravel 函数之后:')
print (a.ravel(order = 'F'))
输出结果如下:
原数组:
[[0 1 2 3]
[4 5 6 7]]
调用 ravel 函数后:
[0 1 2 3 4 5 6 7]
F 风格顺序调用 ravel 函数之后:
[0 4 1 5 2 6 3 7]
数组转置操作
函数名称 | 说明 |
---|---|
transpose | 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。 |
ndarray.T | 与 transpose 方法相同。 |
rollaxis | 沿着指定的轴向后滚动至规定的位置。 |
swapaxes | 对数组的轴进行对换,并不会改变原数组(有点类似于视图) |
1) numpy.transpose()
numpy.transpose() 用于对换多维数组的维度,比如二维数组使用此方法可以实现矩阵转置,语法格式如下:
numpy.transpose(arr, axes)
参数说明如下:
- arr:要操作的数组
- 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) numpy.rollaxis()
该方法表示沿着指定的轴,向后滚动至一个特定位置,格式如下:
numpy.rollaxis(arr, axis, start)
参数说明:
- arr:要传入的数组;
- axis:沿着哪条轴向后滚动,其它轴的相对位置不会改变;
- start:默认以 0 轴开始,可以根据数组维度调整它的值。
import numpy as np
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)
print ('原数组:')
print (a)
print ('\n')
# 将轴 2 滚动到轴 0(宽度到深度)
print ('调用 rollaxis 函数:')
print (np.rollaxis(a,2))
# 将轴 0 滚动到轴 1:(宽度到高度)
print ('\n')
print ('调用 rollaxis 函数:')
print (np.rollaxis(a,2,1))
输出结果如下:
原数组:
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
调用 rollaxis 函数:
[[[0 2]
[4 6]]
[[1 3]
[5 7]]]
调用 rollaxis 函数:
[[[0 2]
[1 3]]
[[4 6]
[5 7]]]
分析:
创建的2x2x2是一个三维数组:[[[0, 1], [2, 3]], [[4, 5], [6, 7]]]
如果要取数值 2,则a[0][1][0] ,数组下标与值对应如下表:
0(000) | 1(001) |
---|---|
2(010) | 3(011) |
4(100) | 5(101) |
6(110) | 7(111) |
程序运行np.rollaxis(a, 2)时,将轴2滚动到了轴0前面,即:5(101) ->6(110), 其他轴相对2轴位置不变(start默认0),数组下标排序由0,1,2变成了1,2,0
这时数组按下标顺序重组,例如第一个数组中[0,1]下标为[000,001],其中0的下标变动不影响值,1位置的下标由001变成010,第一位的下标滚动到最后一位下标的后面,值由1(001)变成2(010):
0(000) ->0(000) | 1(001) ->2(010) |
---|---|
2(010) ->4(100) | 3(011) ->6(110) |
4(100) ->1(001) | 5(101) ->3(011) |
6(110) ->5(101) | 7(111) ->7(111) |
3) numpy.swapaxes()
该方法用于交换数组的两个轴,其语法格式如下:
numpy.swapaxes(arr, axis1, axis2)
示例如:
import numpy as np
# 创建了三维的 ndarray
a = np.arange(27).reshape(3,3,3)
print (a)
#对换0轴与2轴
print(np.swapaxes(a,2,0))
输出结果:
#原a数组
[[[ 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]]]
#对换轴后的数组
[[[ 0 9 18]
[ 3 12 21]
[ 6 15 24]]
[[ 1 10 19]
[ 4 13 22]
[ 7 16 25]]
[[ 2 11 20]
[ 5 14 23]
[ 8 17 26]]]
修改数组维度操作
修改数组维度的操作,主要有以下方法:
函数名称 | 描述说明 |
---|---|
broadcast | 生成一个模拟广播的对象。 |
broadcast_to | 将数组广播为新的形状。 |
expand_dims | 扩展数组的形状。 |
squeeze | 从数组的形状中删除一维项。 |
1) numpy.broadcast()
返回值是数组被广播后的对象,该函数以两个数组作为输入参数,实例如下:
import numpy as np
a = np.array([[1], [2], [3]])
b = np.array([4, 5, 6])
# 对b广播a
d = np.broadcast(a,b)
#d它拥有 iterator 属性
r,c = d.iters
print (next(r), next(c))
print (next(r), next(c))
# 使用broadcast将a与b相加
e = np.broadcast(a,b)
f=np.empty(e.shape)
f.flat=[x+y for (x,y) in e]
print(f)
print(a+b)
输出结果:
#对b广播a
1 6
2 4
#f数组
[[5. 6. 7.]
[6. 7. 8.]
[7. 8. 9.]]
#a+b
[[5 6 7]
[6 7 8]
[7 8 9]]
2) numpy.broadcast_to()
该函数将数组广播到新形状中,它在原始数组的基础上返回一个只读视图。 如果新形状不符合 NumPy 的广播规则,则会抛出 ValueError 异常。函数的语法格式如下:
numpy.broadcast_to(array, shape, subok)
使用实例如下所示:
import numpy as np
a = np.arange(4).reshape(1,4)
print("原数组",a)
print ('调用 broadcast_to 函数之后:')
print (np.broadcast_to(a,(4,4)))
最后的输出结果如下:
#原数组
[[0 1 2 3]]
#调用 broadcast_to 函数之后:
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
3) numpy.expand_dims()
在指定位置插入新的轴,从而扩展数组的维度,语法格式如下:
numpy.expand_dims(arr, axis)
参数说明:
- arr:输入数组
- axis:新轴插入的位置
实例如下:
import numpy as np
x = np.array(([1,2],[3,4]))
print ('数组 x:')
print (x)
# 在 0 轴处插入新的轴
y = np.expand_dims(x, axis = 0)
print ('数组 y:')
print (y)
print ('\n')
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
输出结果为:
数组 x:
[[1 2]
[3 4]]
数组 y:
[[[1 2]
[3 4]]]
数组 x 和 y 的形状:
(2, 2) (1, 2, 2)
4) numpy.squeeze()
删除数组中维度为 1 的项,例如,一个数组的 shape 是 (5,1),经此函数后,shape 变为 (5,) 。其函数语法格式如下:
numpy.squeeze(arr, axis)
参数说明:
- arr:输入数的组;
- axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项。
下面是带有 axis 参数的实例:
>>> x = np.array([[[0], [1], [2]]])
>>> x.shape
(1, 3, 1)
>>> np.squeeze(x).shape
(3,)
>>> np.squeeze(x, axis=(2,)).shape
(1, 3)
再看另一组示例,如下所示:
import numpy as np
a = np.arange(9).reshape(1,3,3)
print (a)
b = np.squeeze(a)
print (b)
print ('数组 a 和 b 的形状:')
print (x.shape, y.shape)
输出结果为:
数组 a:
[[[0 1 2]
[3 4 5]
[6 7 8]]]
数组 b:
[[0 1 2]
[3 4 5]
[6 7 8]]
数组 a 和 b 的形状:
(1, 3, 3) (3, 3)
连接与分割数组操作
连接与分割数组是数组的两种操作方式,我们为了便于大家记忆,现将它们的方法整合在一起,如下所示:
类型 | 函数名称 | 描述说明 |
---|---|---|
连接数组方法 | concatenate | 沿指定轴连接两个或者多个相同形状的数组 |
stack | 沿着新的轴连接一系列数组 | |
hstack | 按水平顺序堆叠序列中数组(列方向) | |
vstack | 按垂直方向堆叠序列中数组(行方向) | |
分割数组方法 | split | 将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) | |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
1) 连接数组操作
numpy.concatenate() 沿指定轴连接相同形状的两个或多个数组,格式如下:
numpy.concatenate((a1, a2, ...), axis)
参数说明:
- a1, a2, …:表示一系列相同类型的数组;
- axis:沿着该参数指定的轴连接数组,默认为 0。
实例说明:创建两个 a 、b 数组,并沿指定轴将它们连接起来。注意两个数组的形状要保持一致。
import numpy as np
#创建数组a
a = np.array([[10,20],[30,40]])
print (a)
#创建数组b
b = np.array([[50,60],[70,80]])
print (b)
#沿轴 0 连接两个数组
print (np.concatenate((a,b)))
#沿轴 1 连接两个数组
print (np.concatenate((a,b),axis = 1))
输出结果:
#a
[[10 20]
[30 40]]
#b
[[50 60]
[70 80]]
#axis=0沿着垂直方向
[[10 20]
[30 40]
[50 60]
[70 80]]
#axis=1沿着水平方向
[[10 20 50 60]
[30 40 70 80]]
数组连接操作至少需要两个维度相同的数组,才允许对它们进行垂直或者水平方向上的操作。
在垂直方向堆叠数组,示例如下:
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
#垂直堆叠
c = np.vstack((a,b))
print (c)
输出结果如下:
[[1 2]
[3 4]
[5 6]
[7 8]]
2) 分割数组操作
numpy.split() 沿指定的轴将数组分割为多个子数组,语法格式如下:
numpy.split(ary, indices_or_sections, axis)
参数说明:
- ary:被分割的数组
- indices_or_sections:若是一个整数,代表用该整数平均切分,若是一个数组,则代表沿轴切分的位置(左开右闭);
- axis:默认为0,表示横向切分;为1时表示纵向切分。
示例如下所示:
import numpy as np
a = np.arange(6)
#原数组
print (a)
#将数组分为二个形状大小相等的子数组
b = np.split(a,2)
print (b)
#将数组在一维数组中标明要位置分割
b = np.split(a,[3,4])
print (b)
输出结果如下:
#a数组
[0 1 2 3 4 5]
#切分分形状大小相同的数组
[array([0, 1, 2]), array([3, 4, 5])]
#按数组标明位置切分,切分时左开右闭
[array([0, 1, 2]), array([3]), array([4, 5])]
最后看一下 hsplit() 的使用方法,示例如下:
np.random.random((x,y))
生成一个形状为(x,y)的数组,数组的每一个元素在(0,1)之间
np.floor()向下取整
import numpy as np
#arr1数组
arr1 = np.floor(10 * np.random.random((2, 6)))
print(arr1)
#拆分后数组
print(np.hsplit(arr1, 3))
输出结果:
#原arr1数组
[[2. 1. 5. 3. 1. 7.]
[1. 2. 9. 0. 9. 9.]]
#经过水平切分后得到的数组
[array([[2., 1.],
[1., 2.]]), array([[5., 3.],
[9., 0.]]), array([[1., 7.],
[9., 9.]])]]
NumPy数组元素增删改查
函数名称 | 描述说明 |
---|---|
resize | 返回指定形状的新数组。 |
append | 将元素值添加到数组的末尾。 |
insert | 沿规定的轴将元素值插入到指定的元素前。 |
delete | 删掉某个轴上的子数组,并返回删除后的新数组。 |
argwhere | 返回数组内符合条件的元素的索引值。 |
unique | 用于删除数组中重复的元素,并按元素值由大到小返回一个新数组。 |
1. numpy.resize()
numpy.resize() 返回指定形状的新数组。
numpy.resize(arr, shape)
使用示例:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(a)
#a数组的形状
print(a.shape)
b = np.resize(a,(3,2))
#b数组
print (b)
#b数组的形状
print(b.shape)
#修改b数组使其形状大于原始数组
b = np.resize(a,(3,3))
print(b)
输出结果为:
a数组:
[[1 2 3]
[4 5 6]]
a形状:
(2, 3)
b数组:
[[1 2]
[3 4]
[5 6]]
b数组的形状:
(3, 2)
修改后b数组:
[[1 2 3]
[4 5 6]
[1 2 3]]
这里需要区别 resize() 和 reshape() 的使用方法,它们看起来相似,实则不同。resize 仅对原数组进行修改,没有返回值,而 reshape 不仅对原数组进行修改,同时返回修改后的结果。
看一组示例,如下所示:
In [1]: import numpy as np
In [2]: x=np.arange(12)
#调用resize方法
In [3]: x_resize=x.resize(2,3,2)
In [4]: x
Out[4]:
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]]])
In [5]: x_resize
#返回None使用print打印
In [6]: print(x_resize)
None
#调用reshape方法
In [7]: x_shape=x.reshape(2,3,2)
#返回修改后的数组
In [8]: x_shape
Out[8]:
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]]])
In [9]: x
Out[9]:
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]]])
2. numpy.append()
在数组的末尾添加值,它返回一个一维数组。
numpy.append(arr, values, axis=None)
参数说明:
- arr:输入的数组;
- values:向 arr 数组中添加的值,需要和 arr 数组的形状保持一致;
- axis:默认为 None,返回的是一维数组;当 axis =0 时,追加的值会被添加到行,而列数保持不变,若 axis=1 则与其恰好相反。
使用示例:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
#向数组a添加元素
print (np.append(a, [7,8,9]))
#沿轴 0 添加元素
print (np.append(a, [[7,8,9]],axis = 0))
#沿轴 1 添加元素
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
输出结果为:
向数组a添加元素:
[1 2 3 4 5 6 7 8 9]
沿轴 0 添加元素:
[[1 2 3]
[4 5 6]
[7 8 9]]
沿轴 1 添加元素:
[[1 2 3 5 5 5]
[4 5 6 7 8 9]]
3. numpy.insert()
表示沿指定的轴,在给定索引值的前一个位置插入相应的值,如果没有提供轴,则输入数组被展开为一维数组。
numpy.insert(arr, obj, values, axis)
参数说明:
- arr:要输入的数组
- obj:表示索引值,在该索引值之前插入 values 值;
- values:要插入的值;
- axis:指定的轴,如果未提供,则输入数组会被展开为一维数组。
示例如下:
import numpy as np
a = np.array([[1,2],[3,4],[5,6]])
#不提供axis的情况,会将数组展开
print (np.insert(a,3,[11,12]))
#沿轴 0 垂直方向
print (np.insert(a,1,[11],axis = 0))
#沿轴 1 水平方向
print (np.insert(a,1,11,axis = 1))
输出结果如下:
提供 axis 参数:
[ 1 2 3 11 12 4 5 6]
沿轴 0:
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
沿轴 1:
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
4. numpy.delete()
该方法表示从输入数组中删除指定的子数组,并返回一个新数组。它与 insert() 函数相似,若不提供 axis 参数,则输入数组被展开为一维数组。
numpy.delete(arr, obj, axis)
参数说明:
- arr:要输入的数组;
- obj:整数或者整数数组,表示要被删除数组元素或者子数组;
- axis:沿着哪条轴删除子数组。
使用示例:
import numpy as np
a = np.arange(12).reshape(3,4)
#a数组
print(a)
#不提供axis参数情况
print(np.delete(a,5))
#删除第二列
print(np.delete(a,1,axis = 1))
#删除经切片后的数组
a = np.array([1,2,3,4,5,6,7,8,9,10])
print (np.delete(a, np.s_[::2]))
输出结果为:
a数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
无 axis 参数:
[ 0 1 2 3 4 6 7 8 9 10 11]
删除第二列:
[[ 0 2 3]
[ 4 6 7]
[ 8 10 11]]
删除经过切片的数组:
[ 2 4 6 8 10]
5. numpy.argwhere()
该函数返回数组中非 0 元素的索引,若是多维数组则返回行、列索引组成的索引坐标。
示例如下所示:
import numpy as np
x = np.arange(6).reshape(2,3)
print(x)
#返回所有大于1的元素索引
y=np.argwhere(x>1)
print(y)
输出结果:
#x数组
[[0 1 2]
[3 4 5]]
#返回行列索引坐标
[[0 2]
[1 0]
[1 1]
[1 2]]
6. numpy.unique()
用于删除数组中重复的元素,其语法格式如下:
numpy.unique(arr, return_index, return_inverse, return_counts)
参数说明:
- arr:输入数组,若是多维数组则以一维数组形式展开;
- return_index:如果为 True,则返回新数组元素在原数组中的位置(索引);
- return_inverse:如果为 True,则返回原数组元素在新数组中的位置(索引);
- return_counts:如果为 True,则返回去重后的数组元素在原数组中出现的次数。
示例如下:
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
print (a)
#对a数组的去重
uq = np.unique(a)
print (uq)
#数组去重后的索引数组
u,indices = np.unique(a, return_index = True)
#打印去重后数组的索引
print(indices)
#去重数组的下标:
ui,indices = np.unique(a,return_inverse = True)
print (ui)
#打印下标
print (indices)
#返回去重元素的重复数量
uc,indices = np.unique(a,return_counts = True)
print (uc)
元素出现次数:
print (indices)
输出结果为:
a数组:
[5 2 6 2 7 5 6 8 2 9]
去重后的a数组
[2 5 6 7 8 9]
去重数组的索引数组:
[1 0 2 4 7 9]
去重数组的下标:
[2 5 6 7 8 9]
原数组在新数组中的下标:
[1 0 2 0 3 1 2 4 0 5]
返回去重元素的重复数量:
[2 5 6 7 8 9]
统计重复元素出现次数:
[3 2 2 1 1 1]
NumPy位运算
序号 | 函数 | 位运算符 | 描述说明 |
---|---|---|---|
1 | bitwise_and | & | 计算数组元素之间的按位与运算。 |
2 | bitwise_or | | | 计算数组元素之间的按位或运算。 |
3 | invert | ~ | 计算数组元素之间的按位取反运算。 |
4 | left_shift | << | 将二进制数的位数向左移。 |
5 | right_shift | >> | 将二进制数的位数向右移。 |
bitwise_and()
该函数只能对数组中整数(即整型)的二进制数进行“按位与”运算。
bin() 返回一个整数 int 或者长整数 long int 的二进制表示。
示例如下:
import numpy as np
a = 10
b = 12
print("a的二进制数:",bin(a))
print("b的二进制数:",bin(b))
print("将a与b执行按位与操作:",np.bitwise_and(a,b))
输出结果如下:
a的二进制: 0b1010
b的二进制: 0b1100
a与b执行按位与操作: 8
如果两个的二进制数相对应的位都为 1,那么执行位与运算后,该位的结果就为 1,否则就为 0。上述示例:a 与 b 位与运算的结果为 1000,因此它的十进制结果为 8。
位与运算的真值表,如下所示:
A | B | AND(A,B) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
bitwise_or()
bitwise_or() 对数组中整数的二进制数执行“按位或”运算。示例如下:
import numpy as np
a,b = 13,17
print ('13 和 17 的二进制数:')
print (bin(a), bin(b))
print ('13 和 17 的位或:')
print (np.bitwise_or(13, 17))
输出结果:
13 和 17 的二进制数:
0b1101 0b10001
13 和 17 的位或:
29
对于按位或运算,只要相对应的二进制位上有一个为 1,那么它的运算结果就位 1,否则为 0,其真值表如下:
A | B | OR(A,B) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Invert()
该方法对数组中整数做按位取反运算,也就是 0 变成 1,1 变为 0。若是有符号的负整数,取其二进制数的补码,并执行 +1 操作。
对于有符号二进制数,其最高位为 0, 表示正数;最高位为 1, 表示负数。
下面通过一组示例,对取反运算进行说明:
import numpy as np
#数据类型为无符号整型uint8
arr = np.array([20],dtype = np.uint8)
print("二进制表示:",np.binary_repr(20,8))
print(np.invert(arr))
#进行取反操作
print("二进制表示: ", np.binary_repr(235,8))
输出结果如下:
二进制表示:00010100
[235]
二进制表示:11101011
注意:上述示例中,np.binary_repr 函数用来设置二进制数的位数。若对补码概念不熟悉,可参考百度百科《补码》。
left_shift()
该方法把数组元素的二进制数向左移动到指定位置,而其返回值所对应的二进制数,则会从右侧追加相等数量的 0(移动了多少位便追加多少个0)。
示例如下:
import numpy as np
#移动三位后的输出值
print (np.left_shift(20,3)
#打印移动后20的二进制数
print (np.binary_repr(20, width = 8))
#函数返回值的二进制数
print (np.binary_repr(160, width = 8))
输出结果为:
移动三位后的返回值:
160
移动三位后20的二进制数:
00010100
函数返回值的二进制数:
10100000
right_shift()
right_shift() 将数组中元素的二进制数向右移动到指定位置,其返回值对应的二进制数会从左侧追加相等数量的 0。该函数使用与 left_shift() 恰好相反。
示例如下:
import numpy as np
#将40右移两位后返回值:
print (np.right_shift(40,2))
#移动后40的二进制数:
print (np.binary_repr(40, width = 8))
#移动后返回值的二进制数:
print (np.binary_repr(10, width = 8))
输出结果为:
将40右移两位后返回值:
10
移动后40的二进制数:
00101000
移动后返回值的二进制数:
00001010
NumPy字符串处理函数
函数名称 | 描述 |
---|---|
add() | 对两个数组相应位置的字符串做连接操作。 |
multiply() | 返回多个字符串副本,比如将字符串“ hello”乘以3,则返回字符串“ hello hello hello”。 |
center() | 用于居中字符串,并将指定的字符,填充在原字符串的左右两侧。 |
capitalize() | 将字符串第一个字母转换为大写。 |
title() | 标题样式,将每个字符串的第一个字母转换为大写形式。 |
lower() | 将数组中所有的字符串的大写转换为小写。 |
upper() | 将数组中所有的字符串的小写转换为大写。 |
split() | 通过指定分隔符对字符串进行分割,并返回一个数组序列,默认分隔符为空格。 |
splitlines() | 以换行符作为分隔符来分割字符串,并返回数组序列。 |
strip() | 删除字符串开头和结尾处的空字符。 |
join() | 返回一个新的字符串,该字符串是以指定分隔符来连接数组中的所有元素。 |
replace() | 用新的字符串替换原数组中指定的字符串。 |
decode() | 用指定的编码格式对数组中元素依次执行解码操作。 |
encode() | 用指定的编码格式对数组中元素依次执行编码操作。 |
上述函数基于 Python 内置的字符串函数实现, 下面对一些常用函数进行讲解。
numpy.char.add()
numpy.char.add() 将两个数组对应位置的字符串元素进行连接。示例如下:
import numpy as np
print(np.char.add(['welcome','url'], [' to C net','is c.biancheng.net'] ))
输出结果:
['welcome to C net' 'url is c.biancheng.net']
numpy.char.multiply()
该函数将指定的字符串进行多次拷贝,并将拷贝结果返回,示例如下:
import numpy as np
print (np.char.multiply('c.biancheng.net',3))
输出结果:
c.biancheng.net c.biancheng.net c.biancheng.net
numpy.char.center()
numpy.char.center() 用于居中字符串,其语法格式如下:
np.char.center(string, width, fillchar)
string: 代表字符串,width: 表示长度,fillchar: 要填充的字符
示例:
import numpy as np
print(np.char.center("c.bianchneg.net", 20, '*'))
输出如下所示:
**c.bianchneg.net***
numpy.char.capitalize()
numpy.char.capitalize() 将字符串的第一个字母转换为大写,示例如下:
import numpy as np
print (np.char.capitalize('python'))
输出结果:
Python
numpy.char.title()
numpy.char.title() 将字符串数组中每个元素的第一个字母转换为大写,示例如下:
import numpy as np
print(np.char.title("welcome to china"))
输出结果
Welcome To China
numpy.char.lower()
numpy.char.lower() 将字符串数组中每个元素转换为小写,示例如下:
import numpy as np
print(np.char.lower("WELCOME TO MYHOME"))
输出结果:
welcome to myhome
numpy.char.upper()
numpy.char.upper() 将数组中的每个元素转换为大写,示例如下:
import numpy as np
print(np.char.upper("Welcome To Python"))
输出结果如下:
WELCOME TO JAVATPOINT
numpy.char.split()
该函数通过指定分隔符对字符串进行分割,并返回数组序列。默认情况下,分隔符为空格。
import numpy as np
print(np.char.split("Welcome To Python"),sep = " ")
输出结果
['Welcome', 'To', 'Python']
numpy.char.splitlines()
numpy.char.splitlines() 以换行符作为分隔符来分割字符串,并返回一个数组序列。
import numpy as np
print("Splitting the String line by line..")
print(np.char.splitlines("Welcome\nTo\nPython"))
输出结果:
['Welcome', 'To', 'Python']
numpy.char.strip()
numpy.char.strip() 用于移除开头或结尾处的空格。
import numpy as np
print("原字符串:",str)
str = " welcome to Python "
print(np.char.strip(str))
输出结果:
原字符串: welcome to Python
welcome to Python
numpy.char.join()
numpy.char.join() 通过指定的分隔符来连接数组中的元素或字符串。
import numpy as np
print (np.char.join(':','Love'))
#也可指定多个分隔符
print (np.char.join([':','-'],['Love','Python']))
输出结果:
L:o:v:e
['L:o:v:e' 'P-y-t-h-o-n']
numpy.char.replace()
numpy.char.replace() 使用新字符替换字符串中的指定字符。示例如下:
import numpy as np
str = "Welcome to China"
print("原字符串:",str)
#更改后字符串
print(np.char.replace(str, "Welcome to","Hello"))
输出结果:
原字符串: Welcome to China
Hello China
numpy.char.encode()与decode()
默认以utf-8
的形式进行编码与解码,示例如下:
import numpy as np
#cp500国际编码
encode_str = np.char.encode("Welcome to China", 'cp500')
decode_str =np.char.decode(encode_str, 'cp500')
print(encode_str)
print(decode_str)
输出结果:
b'\xa6\x85\x93\x83\x96\x94\x85@\xa3\x96@\xc3\x88\x89\x95\x81'
Welcome to China
NumPy数学函数
三角函数
NumPy 中提供了用于弧度计算的的 sin()(正弦)、cos()(余弦)和 tan()(正切)三角函数。
示例如下:
import numpy as np
arr = np.array([0, 30, 60, 90, 120, 150, 180])
#计算arr数组中给定角度的三角函数值
#通过乘以np.pi/180将其转换为弧度
print(np.sin(arr * np.pi/180))
print(np.cos(arr * np.pi/180))
print(np.tan(arr * np.pi/180))
输出结果如下:
sin()正弦值:
[0.00000000e+00 5.00000000e-01 8.66025404e-01 1.00000000e+00
8.66025404e-01 5.00000000e-01 1.22464680e-16]
cos()余弦值:
[ 1.00000000e+00 8.66025404e-01 5.00000000e-01 6.12323400e-17
-5.00000000e-01 -8.66025404e-01 -1.00000000e+00]
tan()正切值:
[ 0.00000000e+00 5.77350269e-01 1.73205081e+00 1.63312394e+16
-1.73205081e+00 -5.77350269e-01 -1.22464680e-16]
除了上述三角函数以外,NumPy 还提供了 arcsin,arcos 和 arctan 反三角函数。
若要想验证反三角函数的结果,可以通过 numpy.degrees() 将弧度转换为角度来实现,示例如下:
import numpy as np
arr = np.array([0, 30, 60, 90])
#正弦值数组
sinval = np.sin(arr*np.pi/180)
print(sinval)
#计算角度反正弦,返回值以弧度为单位
cosec = np.arcsin(sinval)
print(cosec)
#通过degrees函数转化为角度进行验证
print(np.degrees(cosec))
#余弦值数组
cosval = np.cos(arr*np.pi/180)
print(cosval)
#计算反余弦值,以弧度为单位
sec = np.arccos(cosval)
print(sec)
#通过degrees函数转化为角度进行验证
print(np.degrees(sec))
#下面是tan()正切函数
tanval = np.tan(arr*np.pi/180)
print(tanval)
cot = np.arctan(tanval)
print(cot)
print(np.degrees(cot))
输出结果:
正选值数组:
[0. 0.5 0.8660254 1. ]
#计算角度反正弦值,以弧度为单位
[0. 0.52359878 1.04719755 1.57079633]
通过degrees验证
[ 0. 30. 60. 90.]
余弦数组:
[1.00000000e+00 8.66025404e-01 5.00000000e-01 6.12323400e-17]
通过degrees验证
[0. 0.52359878 1.04719755 1.57079633]
反余弦值:
[ 0. 30. 60. 90.]
正切数组:
[0.00000000e+00 5.77350269e-01 1.73205081e+00 1.63312394e+16]
反正切值:
[0. 0.52359878 1.04719755 1.57079633]
通过degrees验证
[ 0. 30. 60. 90.]
舍入函数
NumPy 提供了三个舍入函数,介绍如下:
1) numpy.around()
该函数返回一个十进制值数,并将数值四舍五入到指定的小数位上。该函数的语法如下:
numpy.around(a,decimals)
参数说明:
- a:代表要输入的数组;
- decimals:要舍入到的小数位数。它的默认值为0,如果为负数,则小数点将移到整数左侧。
示例如下:
import numpy as np
arr = np.array([12.202, 90.23120, 123.020, 23.202])
print(arr)
print("数组值四舍五入到小数点后两位",np.around(arr, 2))
print("数组值四舍五入到小数点后-1位",np.around(arr, -1))
输出结果:
原数组arr:[12.202 90.2312 123.02 23.202]
数组值四舍五入到小数点后两位[12.2 90.23 123.02 23.2]
数组值四舍五入到小数点后-1位[10. 90. 120. 20.]
2) numpy.floor()
该函数表示对数组中的每个元素向下取整数,即返回不大于数组中每个元素值的最大整数。示例如下:
import numpy as np
a = np.array([-1.8, 1.1, -0.4, 0.9, 18])
#对数组a向下取整
print (np.floor(a))
输出结果:
[-2. 1. -1. 0. 18.]
3) numpy.ceil()
该函数与 floor 函数相反,表示向上取整。示例如下:
import numpy as np
a = np.array([-1.8, 1.1, -0.4, 0.9, 18])
#对数组a向上取整
print (np.ceil(a))
输出结果:
[-1. 2. -0. 1. 18.]
NumPy算术运算
NumPy 数组的“加减乘除”算术运算,分别对应 add()、subtract()、multiple() 以及 divide() 函数。
注意:做算术运算时,输入数组必须具有相同的形状,或者符合数组的广播规则,才可以执行运算。
下面看一组示例:
import numpy as np
a = np.arange(9, dtype = np.float_).reshape(3,3)
#数组a
print(a)
#数组b
b = np.array([10,10,10])
print(b)
#数组加法运算
print(np.add(a,b))
#数组减法运算
print(np.subtract(a,b))
#数组乘法运算
print(np.multiply(a,b))
#数组除法运算
print(np.divide(a,b))
输出结果:
a数组:
[[ 0. 1. 2.]
[ 3. 4. 5.]
[ 6. 7. 8.]]
b数组:
[10 10 10]
加:
[[ 10. 11. 12.]
[ 13. 14. 15.]
[ 16. 17. 18.]]
减:
[[-10. -9. -8.]
[ -7. -6. -5.]
[ -4. -3. -2.]]
乘:
[[ 0. 10. 20.]
[ 30. 40. 50.]
[ 60. 70. 80.]]
除:
[[ 0. 0.1 0.2]
[ 0.3 0.4 0.5]
[ 0.6 0.7 0.8]]
下面介绍了 NumPy 中其他重要的算术运算函数。
numpy.reciprocal()
该函数对数组中的每个元素取倒数,并以数组的形式将它们返回。
当数组元素的数据类型为**整型(int)**时,对于绝对值小于 1 的元素,返回值为 0,而当数组中包含 0 元素时,返回值将出现 overflow(inf) 溢出提示,示例如下:
import numpy as np
#注意此处有0
a = np.array([0.25, 1.33, 1, 0, 100])
#数组a默认为浮点类型数据
print(a)
#对数组a使用求倒数操作
print (np.reciprocal(a))
#b数组的数据类型为整形int
b = np.array([100], dtype = int)
print(b)
#对数组b使用求倒数操作
print( np.reciprocal(b) )
输出结果:
a数组:
[ 0.25 1.33 1. 0. 100. ]
对a数组求倒数有inf提示:
__main__:1: RuntimeWarning: divide by zero encountered in reciprocal
[ 4. 0.7518797 1. inf 0.01 ]
b数组:
[100]
对b数组求倒数:
[0]
numpy.power()
该函数将 a 数组中的元素作为底数,把 b 数组中与 a 相对应的元素作幂 ,最后以数组形式返回两者的计算结果。示例如下:
import numpy as np
a = np.array([10,100,1000])
#a数组
print ('我们的数组是;')
#调用 power 函数
print (np.power(a,2))
b数组
b = np.array([1,2,3])
print (b)
调用 power 函数
print (np.power(a,b))
输出结果:
a数组是:
[ 10 100 1000]
调用 power 函数:
[ 100 10000 1000000]
b数组:
[1 2 3]
调用 power 函数:
[ 10 10000 1000000000]
numpy.mod()
返回两个数组相对应位置上元素相除后的余数,它与 numpy.remainder() 的作用相同 。
import numpy as np
a = np.array([11,22,33])
b = np.array([3,5,7])
#a与b相应位置的元素做除法
print( np.mod(a,b))
#remainder方法一样
print(np.remainder(a,b))
输出结果:
mod:
[1 0 2]
remainder:
[1 0 2]
numpy有关行列的计算
- numpy.sum() 求和
- numpy.mean() 平均值
- numpy.min() 最小值/numpy.max() 最大值
- numpy.ptp() 最大值与最小值的差(最大值-最小值)
- numpy.std() 标准差/numpy.var() 方差
- 多维数组的参数axis
import numpy as np
a = np.arange(12).reshape(3, 4)
print(a.shape)
print(a)
# (3, 4)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
numpy.sum() 求和
把刚刚生成的数组a放入函数np.sum()中,返回得到数组中所有元素的和。
print(np.sum(a))
# 66
参数axis=0时,返回数组各列的和,参数axis=1时,返回数组各行的和。
print(np.sum(a, axis=0))
print(np.sum(a, axis=1))
# [12 15 18 21]
# [ 6 22 38]
其实不使用numpy的函数也是可以的,因为ndarray数组中也有相同的求和方法sum()。并且也可以通过参数axis指定行或列。
print(a.sum())
# 66
print(a.sum(axis=0))
print(a.sum(axis=1))
# [12 15 18 21]
# [ 6 22 38]
numpy.mean() 平均值
numpy.mean()的使用方法与numpy.sum()相同,也可以通过参数axis指定行或列。
print(np.mean(a))
# 5.5
print(np.mean(a, axis=0))
print(np.mean(a, axis=1))
# [ 4. 5. 6. 7.]
# [ 1.5 5.5 9.5]
和sum()一样,ndarray数组中也有相同的求平均值的方法mean()。并且也可以通过参数axis指定行或列。
print(a.mean())
# 5.5
print(a.mean(axis=0))
print(a.mean(axis=1))
# [ 4. 5. 6. 7.]
# [ 1.5 5.5 9.5]
numpy.min() 最小值/numpy.max() 最大值
在分别使用numpy.min()和numpy.max()求数组中元素的最小值与最大值的时候,也可以通过参数axis指定行或列。并且,为了使用方便,还可以直接使用函数numpy.amin()和numpy.amax()进行计算,所得到的结果是一样的。
print(np.min(a))
print(np.min(a, axis=0))
print (np.amin(a,0))
# 0
# [0 1 2 3]
# [0 1 2 3]
print(a.max())
print(a.max(axis=1))
print(np.amax(a,1))
# 11
# [ 3 7 11]
# [ 3 7 11]
numpy.ptp() 最大值与最小值的差(最大值-最小值)
函数numpy.ptp()可以返回得到数组中最大值与最小值之间的差(最大值-最小值),也可以通过参数axis指定行或列。
print(np.ptp(a))
#11
print(np.ptp(a, axis=1))
#[3 3 3]
print(np.ptp(a, axis=0))
#[8 8 8 8]
numpy.std() 标准差/numpy.var() 方差
求标准差和方差的函数分别为numpy.std()和numpy.var()。使用方法和之前相同,也可以通过参数axis指定行或列。
print(np.std(a))
#3.452052529534663
print(np.var(a))
#11.916666666666666
多维数组的参数axis
首先,准备一个2x3x4的数组b。
b = np.arange(24).reshape(2, 3, 4)
print(b.shape)
print(b)
# (2, 3, 4)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
当axis=0时,结果维3x4的数组。
print(b.sum(axis=0))
# [[12 14 16 18]
# [20 22 24 26]
# [28 30 32 34]]
当axis=1时,结果维2x4的数组。
print(b.sum(axis=1))
# [[12 15 18 21]
# [48 51 54 57]]
当axis=2时,结果维2x3的数组。
print(b.sum(axis=2))
# [[ 6 22 38]
# [54 70 86]]
asix还可以进行双数值的指定。结果如下。
print(b.sum(axis=(0, 1)))
# [60 66 72 78]
print(b.sum(axis=(0, 2)))
# [ 60 92 124]
print(b.sum(axis=(1, 2)))
# [ 66 210]
复数数组处理函数
NumPy 提供了诸多处理复数类型数组的函数,主要有以下几个:
- numpy.real() 返回复数数组的实部;
- numpy.imag() 返回复数数组的虚部;
- numpy.conj() 通过更改虚部的符号,从而返回共轭复数;
- numpy.angle() 返回复数参数的角度,该函数的提供了一个 deg 参数,如果 deg=True,则返回的值会以角度制来表示,否则以以弧度制来表示。
示例如下所示:
import numpy as np
a = np.array([-5.6j, 0.2j, 11. , 1+1j])
print(a)
#real()
print np.real(a)
#imag()
print np.imag(a)
#conj()
print np.conj(a)
#angle()
print np.angle(a)
#angle() 带参数deg
print np.angle(a, deg = True)
输出结果:
a数组:
[ 0.-5.6j 0.+0.2j 11.+0.j 1.+1.j ]
real():
[ 0. 0. 11. 1.]
imag():
[-5.6 0.2 0. 1. ]
conj():
[ 0.+5.6j 0.-0.2j 11.-0.j 1.-1.j ]
angle() :
[-1.57079633 1.57079633 0. 0.78539816]
angle(a,deg=True)
[-90. 90. 0. 45.]
python: np.pad() 函数的用法
在卷积神经网络中,为了避免因为卷积运算导致输出图像缩小和图像边缘信息丢失,常常采用图像边缘填充技术,即在图像四周边缘填充0,使得卷积运算后图像大小不会缩小,同时也不会丢失边缘和角落的信息。在Python的numpy库中,常常采用numpy.pad()进行填充操作,具体分析如下:
1.语法结构
pad(array, pad_width, mode, **kwargs)
返回值:数组
2.参数解释
array——表示需要填充的数组;
pad_width——表示每个轴(axis)边缘需要填充的数值数目。
参数输入方式为:((before_1, after_1), … (before_N, after_N)),其中(before_1, after_1)表示第1轴两边缘分别填充before_1个和after_1个数值。取值为:{sequence, array_like, int}mode——表示填充的方式(取值:str字符串或用户提供的函数),总共有11种填充模式;
3.填充方式
‘constant’——表示连续填充相同的值,每个轴可以分别指定填充值,constant_values=(x, y)时前面用x填充,后面用y填充,缺省值填充0
‘edge’——表示用边缘值填充
‘linear_ramp’——表示用边缘递减的方式填充
‘maximum’——表示最大值填充
‘mean’——表示均值填充
‘median’——表示中位数填充
‘minimum’——表示最小值填充
‘reflect’——表示对称填充
‘symmetric’——表示对称填充
‘wrap’——表示用原数组后面的值填充前面,前面的值填充后面
3.1 常数填充模式——’constant’
在卷积神经网络中,通常采用constant填充方式!!
A = np.arange(95,99).reshape(2,2) #原始输入数组
#在数组A的边缘填充constant_values指定的数值
#(3,2)表示在A的第[0]轴填充(二维数组中,0轴表示行),即在0轴前面填充3个宽度的0,比如数组A中的95,96两个元素前面各填充了3个0;在后面填充2个0,比如数组A中的97,98两个元素后面各填充了2个0
#(2,3)表示在A的第[1]轴填充(二维数组中,1轴表示列),即在1轴前面填充2个宽度的0,后面填充3个宽度的0
np.pad(A,((3,2),(2,3)),'constant',constant_values = (0,0)) #constant_values表示填充值,且(before,after)的填充值等于(0,0)
array([[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 95, 96, 0, 0, 0],
[ 0, 0, 97, 98, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0]])
#填充时,从前面轴,往后面轴依次填充
np.pad(A,((3,2),(2,3)),'constant',constant_values = (-2,2)) #填充值,前面填充改为-2,后面填充改为2
array([[-2, -2, -2, -2, 2, 2, 2],
[-2, -2, -2, -2, 2, 2, 2],
[-2, -2, -2, -2, 2, 2, 2],
[-2, -2, 95, 96, 2, 2, 2],
[-2, -2, 97, 98, 2, 2, 2],
[-2, -2, 2, 2, 2, 2, 2],
[-2, -2, 2, 2, 2, 2, 2]])
np.pad(A,((3,2),(2,3)),'constant',constant_values = ((0,0),(1,2))) #0轴和1轴分别填充不同的值,先填充0轴,后填充1轴,存在1轴填充覆盖0轴填充的情形
array([[ 1, 1, 0, 0, 2, 2, 2],
[ 1, 1, 0, 0, 2, 2, 2],
[ 1, 1, 0, 0, 2, 2, 2],
[ 1, 1, 95, 96, 2, 2, 2],
[ 1, 1, 97, 98, 2, 2, 2],
[ 1, 1, 0, 0, 2, 2, 2],
[ 1, 1, 0, 0, 2, 2, 2]])
np.pad(A,((3,2),(2,3)),'constant') #,constant_values 缺省,则默认填充均为0
array([[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 95, 96, 0, 0, 0],
[ 0, 0, 97, 98, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0]])
3.2边缘值填充模式——’edge’
B = np.arange(1,5).reshape(2,2) #原始输入数组
array([[1, 2],
[3, 4]])
np.pad(B,((1,2),(2,1)),'edge') #注意先填充0轴,后面填充1轴,依次填充
array([[1, 1, 1, 2, 2],
[1, 1, 1, 2, 2],
[3, 3, 3, 4, 4],
[3, 3, 3, 4, 4],
[3, 3, 3, 4, 4]])
3.3边缘最大值填充模式——’maximum’
B = np.arange(1,5).reshape(2,2) #原始输入数组
np.pad(B,((1,2),(2,1)),'maximum') #maximum填充模式还有其他控制参数,比如stat_length,详细见numpy库
array([[4, 4, 3, 4, 4],
[2, 2, 1, 2, 2],
[4, 4, 3, 4, 4],
[4, 4, 3, 4, 4],
[4, 4, 3, 4, 4]])
C = np.arange(0,9).reshape(3,3) #原始输入数组
np.pad(C,((3,2),(2,1)),'maximum')
array([[8, 8, 6, 7, 8, 8],
[8, 8, 6, 7, 8, 8],
[8, 8, 6, 7, 8, 8],
[2, 2, 0, 1, 2, 2],
[5, 5, 3, 4, 5, 5],
[8, 8, 6, 7, 8, 8],
[8, 8, 6, 7, 8, 8],
[8, 8, 6, 7, 8, 8]])
numpy库ndarray多维数组的维度变换方法(reshape、resize、swapaxes、flatten)
import numpy as np
a=np.arange(20)
print(a)
#[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
print(a.reshape(4,5))
#[[ 0 1 2 3 4]
#[ 5 6 7 8 9]
#[10 11 12 13 14]
#[15 16 17 18 19]]
print(a)
#[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
a.shape=(5,4)
print(a)
'''
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
'''
reshape并不会直接改变原数组,而是会产生一个元素相同,维度不同的新数组,这个新数组会可以赋给新变量,也可以赋给指向原数组的变量。(有点类似于视图)
resize和shape会直接改变原数组。
Numpy的函数np.where()—满足条件的处理
- numpy.where()的概要
- 多个条件式的使用
- 满足条件元素的替换
- 满足条件元素的处理
- 满足条件元素的索引
Numpy.where()的概要
Numpy.where(condition,[x,y])
当条件(condition)满足时为真(True),返回x。当条件(condition)不满足时为假(False),返回y。返回的结果也是一个ndarray数组。
import numpy as np
a = np.arange(9).reshape((3, 3))
print(a)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
print(np.where(a < 4, -1, 100))
# [[ -1 -1 -1]
# [ -1 100 100]
# [100 100 100]]
print(np.where(a < 4, True, False))
# [[ True True True]
# [ True False False]
# [False False False]]
不使用numpy.where(),直接使用条件式,可以得到一个满足条件时为真(True),不满足时为假(False)的ndarray数组。
print(a < 4)
# [[ True True True]
# [ True False False]
# [False False False]]
多个条件式的使用
多个条件式时,用()将其分开,条件式与条件式之间可以用 &,| 逻辑运算符进行连接。但不可以使用and,or等关键字链接。
print(np.where((a > 2) & (a < 6), -1, 100))
# [[100 100 100]
# [ -1 -1 -1]
# [100 100 100]]
print(np.where((a > 2) & (a < 6) | (a == 7), -1, 100))
# [[100 100 100]
# [ -1 -1 -1]
# [100 -1 100]]
print((a > 2) & (a < 6))
# [[False False False]
# [ True True True]
# [False False False]]
print((a > 2) & (a < 6) | (a == 7))
# [[False False False]
# [ True True True]
# [False True False]]
多个条件式时,不使用numpy.where(),也能返回得到一个True,False的ndarray数组。
满足条件元素的替换
满足条件或不满足条件的元素的替换可以参考上述的例子。也可以对只满足条件或,只不满足条件的元素进行替换。将数组中元素代入numpy.where()的参数x,y即可。
print(np.where(a < 4, -1, a))
# [[-1 -1 -1]
# [-1 4 5]
# [ 6 7 8]]
print(np.where(a < 4, a, 100))
# [[ 0 1 2]
# [ 3 100 100]
# [100 100 100]]
numpy.where()返回一个新的ndarray数组,原数组不变。
a_org = np.arange(9).reshape((3, 3))
print(a_org)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
a_new = np.where(a_org < 4, -1, a_org)
print(a_new)
# [[-1 -1 -1]
# [-1 4 5]
# [ 6 7 8]]
print(a_org)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
更替数组自身值的时候,可以这样写。
a_org[a_org < 4] = -1
print(a_org)
# [[-1 -1 -1]
# [-1 4 5]
# [ 6 7 8]]
满足条件元素的处理
numpy.where()不光可以返回原数组的值,也可以进行计算后,返回一个新的数组。
print(np.where(a < 4, a * 10, a))
# [[ 0 10 20]
# [30 4 5]
# [ 6 7 8]]
满足条件元素的索引
省略numpy.where()的参数x,y时,返回满足条件元素的角标。
print(np.where(a < 4))
# (array([0, 0, 0, 1]), array([0, 1, 2, 0]))
print(type(np.where(a < 4)))
# <class 'tuple'>
但是,上述的结果并不好理解。可以使用list(),zip()以及*对其进行以下整理,结果如下。
print(list(zip(*np.where(a < 4))))
# [(0, 0), (0, 1), (0, 2), (1, 0)]
这里的(0, 0), (0, 1), (0, 2), (1, 0)为原数组中满足条件元素的角标。
多维度的数组也同样适用。
a_3d = np.arange(24).reshape(2, 3, 4)
print(a_3d)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
print(np.where(a_3d < 5))
# (array([0, 0, 0, 0, 0]), array([0, 0, 0, 0, 1]), array([0, 1, 2, 3, 0]))
print(list(zip(*np.where(a_3d < 5))))
# [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 0)]
一维数组也同样适用。但如果也使用list(),zip()以及*对其进行整理的话,返回的结果也是一个2维的角标集合。
a_1d = np.arange(6)
print(a_1d)
# [0 1 2 3 4 5]
print(np.where(a_1d < 3))
# (array([0, 1, 2]),)
print(list(zip(*np.where(a_1d < 3))))
# [(0,), (1,), (2,)]
可以使用tolist(),将其转换成list格式。
print(np.where(a_1d < 3)[0])
# [0 1 2]
print(np.where(a_1d < 3)[0].tolist())
# [0, 1, 2]
Numpy任意行&列的删除方法(numpy.delete)
- Numpy.delete()基本的使用方法
- 删除指定的索引(行或者列):参数obj
- 删除指定的轴(维度):参数axis
- 一次删除多行和多列
- 列表的指定
- 切片的指定
- 行和列的指定
- 多维数组的例
Numpy.delete()基本的使用方法
- Numpy.delete(arr,obj,axis=None)有以下3个参数:
- arr:输入数组
- obj:指定要通过的整数,切片或者列表(数组)删除的行号/列号
- axis:要删除的轴
以下是2维数组的例:
import numpy as np
a = np.arange(12).reshape(3, 4)
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
稍后进行详细的说明,例如:当删除第2行时,obj=1且axis=0。此时原始数组不会被改变,而是创建该数组的新副本。
a_del = np.delete(a, 1, 0)
print(a_del)
# [[ 0 1 2 3]
# [ 8 9 10 11]]
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
删除指定的索引(行或者列):参数obj
在第2个参数obj中,从0开始指定要删除的索引角标(行号/列号),指定不存在的索引角标将返回错误。
print(np.delete(a, 0, 0))
# [[ 4 5 6 7]
# [ 8 9 10 11]]
print(np.delete(a, 2, 0))
# [[0 1 2 3]
# [4 5 6 7]]
# print(np.delete(a, 3, 0))
# IndexError: index 3 is out of bounds for axis 0 with size 3
删除指定的轴(维度):参数axis
在第3个参数axis中,从0开始指定要删除的轴(维度)。对于二维数组来说,行是第一维度(从0开始)。指定不存在的维度将返回错误。
print(np.delete(a, 1, 0))
# [[ 0 1 2 3]
# [ 8 9 10 11]]
print(np.delete(a, 1, 1))
# [[ 0 2 3]
# [ 4 6 7]
# [ 8 10 11]]
# print(np.delete(a, 1, 2))
# AxisError: axis 2 is out of bounds for array of dimension 2
如果axis=None,则将obj指定的索引处的元素展平到一维后将其删除。由于轴的默认值为"无",因此如果省略的话,将执行默认的操作
print(np.delete(a, 1, None))
# [ 0 2 3 4 5 6 7 8 9 10 11]
print(np.delete(a, 1))
# [ 0 2 3 4 5 6 7 8 9 10 11]
一次删除多行和多列
如果在第二个参数obj中指定列表或切片,则可以一次删除多个行或列。
列表的指定
print(np.delete(a, [0, 3], 1))
# [[ 1 2]
# [ 5 6]
# [ 9 10]]
print(np.delete(a, [0, 1, 3], 1))
# [[ 2]
# [ 6]
# [10]]
切片的指定
[start:stop:step]格式来指定切片的范围,从而指定多个行或列。
Slice()的使用:
使用Slice()创建一个Slice对象,并在第2个参数obj中指定它。
如果只有1个参数,等效于[:stop],
如果只有2个参数,等效于[start:stop],
如果省略,则显式设置为None。
print(np.delete(a, slice(2), 1))
# [[ 2 3]
# [ 6 7]
# [10 11]]
print(np.delete(a, slice(1, 3), 1))
# [[ 0 3]
# [ 4 7]
# [ 8 11]]
print(np.delete(a, slice(None, None, 2), 1))
# [[ 1 3]
# [ 5 7]
# [ 9 11]]
np.s_的使用:
要以切片[start:stop:step]的形式描述时,也可以使用numpy.s_[]的书写方式(书写方式与Slice()相同)。
print(np.delete(a, np.s_[:2], 1))
# [[ 2 3]
# [ 6 7]
# [10 11]]
print(np.delete(a, np.s_[1:3], 1))
# [[ 0 3]
# [ 4 7]
# [ 8 11]]
print(np.delete(a, np.s_[::2], 1))
# [[ 1 3]
# [ 5 7]
# [ 9 11]]
行和列的指定
numpy.delete()无法一次删除多个维度(例如行和列)。要删除多个维度时,请重复使用numpy.delete()。
print(np.delete(np.delete(a, 1, 0), 1, 1))
# [[ 0 2 3]
# [ 8 10 11]]
多维数组的例
到目前位置,为了方便起,都是按照2维数组的行和列进行的描述。但是对于三维甚至更高维度的数组,该概念是相同的。
以下面的数组为例。
a_3d = np.arange(24).reshape(2, 3, 4)
print(a_3d)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
print(a_3d.shape)
# (2, 3, 4)
在参数axis上指定维度,参数obj指定索引。
print(np.delete(a_3d, 1, 0))
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]]
print(np.delete(a_3d, 1, 1))
# [[[ 0 1 2 3]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [20 21 22 23]]]
print(np.delete(a_3d, 1, 2))
# [[[ 0 2 3]
# [ 4 6 7]
# [ 8 10 11]]
#
# [[12 14 15]
# [16 18 19]
# [20 22 23]]]
使用列表和切片的方法也是相同的
print(np.delete(a_3d, [0, 3], 2))
# [[[ 1 2]
# [ 5 6]
# [ 9 10]]
#
# [[13 14]
# [17 18]
# [21 22]]]
print(np.delete(a_3d, np.s_[::2], 2))
# [[[ 1 3]
# [ 5 7]
# [ 9 11]]
#
# [[13 15]
# [17 19]
# [21 23]]]
Numpy各种随机数组的生成方法
- 生成均匀分布的随机数。
- numpy.random.rand(): 0.0到1.0
- numpy.random.random_sample(): 0.0到1.0
- numpy.random.randint():任意值范围的整数
- 生成正态分布的随机数。
- numpy.random.randn(): 平均为0,标准差为1
- numpy.random.normal(): 任意值的平均和标准差
- 生成二项式的随机数。
- numpy.random.binomial()
- 生成Beta分布的随机数。
- numpy.random.beta()
- 生成Gamma分布的随机数。
- numpy.random.gamma()
- 生成卡方分布的随机数。
- numpy.random.chisquare()
生成均匀分布的随机数
numpy.random.rand(): 均匀分布 0.0到1.0
numpy.random.rand()返回一组0.0到1.0之间的随机数。
import numpy as np
rand = np.random.rand() # 1个随机数
print(rand)
# 0.5399711080561779
arr = np.random.rand(3) # 长度为3的随机数数组
print(arr)
# [ 0.22393312 0.56723404 0.41167989]
arr = np.random.rand(4, 4) # 4 x 4的随机数数组
print(arr)
# [[ 0.98109413 0.43272792 0.78808567 0.14697466]
# [ 0.14529422 0.66417579 0.62020433 0.39887021]
# [ 0.78762131 0.3616854 0.76995665 0.25530529]
# [ 0.59426681 0.64130992 0.41451061 0.2356074 ]]
arr = np.random.rand(3, 2, 2) # 3 x 2 x 2的随机数数组
print(arr)
# [[[ 0.26072665 0.63424568]
# [ 0.43025675 0.88787556]]
#
# [[ 0.58189813 0.57733422]
# [ 0.4312518 0.12558879]]
#
# [[ 0.58588003 0.58290714]
# [ 0.58133023 0.05894161]]]
numpy.random.random_sample(): 均匀分布 0.0到1.0
numpy.random.random_sample()和np.random.rand()相同,返回一组0.0到1.0之间的随机数。不同的是指定参数的类型。
numpy.random.random_sample()的参数类型为tuple(元组)。
rand = np.random.random_sample() # 1个随机数
print(rand)
# 0.7812294650415362
arr = np.random.random_sample(3) # 长度为3的随机数数组
print(arr)
# [ 0.31315625 0.75406842 0.51955327]
arr = np.random.random_sample((4, 4)) # 4 x 4的随机数数组
print(arr)
# [[ 0.17710988 0.63316992 0.00101942 0.94233375]
# [ 0.9439738 0.58700846 0.97807038 0.56899597]
# [ 0.62050185 0.23601975 0.57513176 0.56947325]
# [ 0.64393715 0.92796497 0.83784537 0.1544701 ]]
arr = np.random.random_sample((3, 2, 2)) # 3 x 2 x 2的随机数数组
print(arr)
# [[[ 0.26624554 0.33096779]
# [ 0.1814989 0.12867246]]
#
# [[ 0.1435755 0.45274324]
# [ 0.12867198 0.98908694]]
#
# [[ 0.86989893 0.67003622]
# [ 0.17530006 0.03146698]]]
print(np.random.random_sample is np.random.random)
# True
其他:
- np.random.random()
- np.random.ranf()
- np.random.sample()
上述函数的函数名虽然不同,但功能完全相同。
numpy.random.randint(): 均匀分布 任意值范围的整数
np.random.randint()返回一组任意值范围的整数随机数。
参数的指定顺序为最小值,最大值,尺寸,类型。
arr = np.random.randint(4, 10, (3, 3)) # 4到10的3 x 3的随机整数数组
print(arr)
# [[9 5 6]
# [4 8 9]
# [9 8 5]]
生成正态分布的随机数。
numpy.random.randn(): 平均为0,标准差为1
np.random.randn()返回一组平均为0,标准差为1,服从正态分布的随机数。
arr = np.random.randn(3, 3)
print(arr)
# [[-0.25630308 0.86118703 0.7163906 ]
# [-0.63096426 -2.09983061 1.28259567]
# [ 1.45971205 0.2939326 0.64207751]]
numpy.random.normal(): 任意值的平均和标准差
numpy.random.normal()返回一组平均为loc,标准差为scale,服从正态分布的随机数。
numpy.random.normal(loc=0.0, scale=1.0, size=None)
参数size的类型为tuple(元组)
arr = np.random.normal(-2, 0.5, (3, 3))
print(arr)
# [[-2.40461812 -2.76365861 -1.70312821]
# [-2.29453302 -1.53210319 -1.49669024]
# [-1.90580765 -1.45375908 -2.44137036]]
生成二项式的随机数。
numpy.random.binomial()
numpy.random.binomial()返回一组服从参数n,p的二项式随机数。
参数size的类型为tuple(元组)
arr = np.random.binomial(10, 0.5, 10)
print(arr)
# [7 4 7 5 7 8 5 5 3 4]
生成Beta分布的随机数。
numpy.random.beta()
numpy.random.beta()返回一组服从参数a,b的Beta分布的随机数。
参数size的类型为tuple(元组)
arr = np.random.beta(2, 2, 10)
print(arr)
# [ 0.36516508 0.86746749 0.54430968 0.31152791 0.57359928 0.48281988
# 0.70518635 0.57312808 0.09019818 0.87831173]
生成Gamma分布的随机数。
numpy.random.gamma()
numpy.random.gamma()返回一组服从参数shape,比例scale的Gamma分布的随机数。
参数size的类型为tuple(元组)
arr = np.random.gamma(5, 1, 10)
print(arr)
# [ 3.86630062 1.69144819 3.07071675 3.14181626 3.61405871 8.37772201
# 5.47063142 4.80523142 3.68531649 4.43143731]
生成卡方分布的随机数。
numpy.random.chisquare()
numpy.random.chisquare()返回一组服从自由度df的卡方分布的随机数。
参数size的类型为tuple(元组)
arr = np.random.chisquare(3, 10)
print(arr)
# [ 0.49617849 2.39966829 2.84359974 3.5340327 0.71761612 2.04619564
# 0.35930769 4.00448281 1.2907048 2.99259386]
Numpy初始化生成相同元素值的ndarray数组
生成相同元素值数组的方法如下:
通过形状shape(行数,列数)的指定,和带类型参数dtype的方法。
-
numpy.zeros(): 初始值为0
-
numpy.ones(): 初始值为1
-
numpy.full(): 任意值的初始化
如何生成与现有数组相同(指的是形状shape,类型dtype相同)的数组。
-
numpy.zeros_like(): 初始值为0
-
numpy.ones_like(): 初始值为1
-
numpy.full_like(): 任意值的初始化
numpy.zeros(): 初始值为0
import numpy as np
print(np.zeros(3))
# [ 0. 0. 0.]
print(np.zeros((2, 3)))
# [[ 0. 0. 0.]
# [ 0. 0. 0.]]
print(np.zeros(3).dtype)
# float64
print(np.zeros(3, dtype=np.int))
# [0 0 0]
print(np.zeros(3, dtype=np.int).dtype)
# int64
numpy.ones(): 初始值为1
使用numpy.ones()函数可以生成一个ndarray数组,其中所有元素值均为1。使用方法与numpy.zeros()相同。将要生成的数组的形状左右参数传递。
print(np.ones(3))
# [ 1. 1. 1.]
print(np.ones((2, 3)))
# [[ 1. 1. 1.]
# [ 1. 1. 1.]]
print(np.ones(3).dtype)
# float64
print(np.ones(3, dtype=np.int))
# [1 1 1]
print(np.ones(3, dtype=np.int).dtype)
# int64
numpy.full(): 任意值的初始化
使用numpy.full()函数可以生成一个ndarray数组,其中所有元素值可以为任意值。
将要生成数组的形状作为第一参数传递,并将任意值作为第二个参数(fill_value)进行传递。
print(np.full(3, 100))
# [100 100 100]
print(np.full(3, np.pi))
# [ 3.14159265 3.14159265 3.14159265]
print(np.full((2, 3), 100))
# [[100 100 100]
# [100 100 100]]
print(np.full((2, 3), np.pi))
# [[ 3.14159265 3.14159265 3.14159265]
# [ 3.14159265 3.14159265 3.14159265]]
值的类型可以根据第二个参数(fill_value)的值进行指定。
比如100为int64,100.0为float64。
print(np.full(3, 100).dtype)
# int64
print(np.full(3, 100.0).dtype)
# float64
print(np.full(3, np.pi).dtype)
# float64
当然也可以使用参数dtype进行类型指定,并且还可以进行类型的强制转换。
print(np.full(3, 100, dtype=float))
# [ 100. 100. 100.]
print(np.full(3, np.pi, dtype=int))
# [3 3 3]
numpy.zeros_like(): 初始值为0
先生成2个原始ndarray数组,一个类型为int,另外一个类型为float。
import numpy as np
a_int = np.arange(6).reshape((2,3))
print(a_int)
# [[0 1 2]
# [3 4 5]]
a_float = np.arange(6).reshape((2,3)) / 10
print(a_float)
# [[ 0. 0.1 0.2]
# [ 0.3 0.4 0.5]]
要生成全为0的数组时,可以使用numpy.zeros_like(),第一参数为原始数组。
新生成数组的类型和原始数组相同。
print(np.zeros_like(a_int))
# [[0 0 0]
# [0 0 0]]
print(np.zeros_like(a_float))
# [[ 0. 0. 0.]
# [ 0. 0. 0.]]
也可以使用参数dtype进行类型的重新指定。
print(np.zeros_like(a_int, dtype=np.float))
# [[ 0. 0. 0.]
# [ 0. 0. 0.]]
numpy.ones_like(): 初始值为1
要生成全为1的数组时,可以使用numpy.ones_like()函数。使用方法与numpy.zeros_like()相同。第一个参数为原始数组。
新生成数组的类型和原始数组相同。
print(np.ones_like(a_int))
# [[1 1 1]
# [1 1 1]]
print(np.ones_like(a_float))
# [[ 1. 1. 1.]
# [ 1. 1. 1.]]
也可以使用参数dtype进行类型的重新指定。
print(np.ones_like(a_int, dtype=np.float))
# [[ 1. 1. 1.]
# [ 1. 1. 1.]]
numpy.full_like(): 任意值的初始化
生成一个ndarray数组,其中元素的值可以为任意值。
将要生成数组的形状作为第一参数传递,并将任意值作为第二个参数(fill_value)进行传递。
新生成数组的类型和原始数组相同。
print(np.full_like(a_int, 100))
# [[100 100 100]
# [100 100 100]]
print(np.full_like(a_float, 100))
# [[ 100. 100. 100.]
# [ 100. 100. 100.]]
值的类型可以进行强制转换。
print(np.full_like(a_int, 0.123))
# [[0 0 0]
# [0 0 0]]
print(np.full_like(a_float, 0.123))
# [[ 0.123 0.123 0.123]
# [ 0.123 0.123 0.123]]
也可以使用参数dtype进行类型的重新指定。
print(np.full_like(a_int, 0.123, dtype=np.float))
# [[ 0.123 0.123 0.123]
# [ 0.123 0.123 0.123]]
Numpy含有缺失值ndarray数组的求和,平均值的计算方法
通常情况下,ndarrya数组中会含有一个或多个缺失值(nan),这种情况下使用函数sum()来求和的话,会直接返回nan。这个时候可以使用函数nansum(),可以对缺失值(nan)以外的其他值进行求和。
举例:使用函数np.genfromtxt()读取一个含有缺失值的csv文件。缺失值的部分将直接显示为nan。
import numpy as np
arr = np.genfromtxt('./data/sample_nan.csv', delimiter=',')
print(arr)
# [[ 11. 12. nan 14.]
# [ 21. nan nan 24.]
# [ 31. 32. 33. 34.]]
使用nansum()进行求和
使用函数sun()的话,将直接返回nan。
print(arr.sum())
# nan
print(np.sum(arr))
# nan
使用函数nansum()的话,可以对缺失值(nan)以外的其他值进行求和。
print(np.nansum(arr))
# 212.0
也可以通过参数axis,来指定行或列的计算。
print(np.nansum(arr, axis=0))
# [ 63. 44. 33. 72.]
print(np.nansum(arr, axis=1))
# [ 37. 45. 130.]
平均值,最大值,最小值等的计算
平均值,最大值,最小值,标准差,方差等的计算,可以使用函数np.nanmean(), np.nanmax(), np.nanmin(), np.nanstd(), np.nanvar()。
print(np.nanmean(arr))
# 23.5555555556
print(np.nanmax(arr))
# 34.0
print(np.nanmin(arr))
# 11.0
print(np.nanstd(arr))
# 8.90831211237
print(np.nanvar(arr))
# 79.3580246914
Numpy数组(ndarray)中缺失值(nan)的替换
将NumPy数组ndarray的缺失值NaN(例如np.nan)的元素替换为其他值时,可是使用np.nan_to_num()和np.isnan()布尔值索引的方法。可以将其替换为任意值,或替换为不包含缺失值NaN的元素的平均值。
在此,将对以下进行说明内容。
- 缺失值NaN的生成和判定
- np.genfromtxt()参数filling_values的指定
- np.nan_to_num()缺失值NaN的替换
- 用布尔值索引的方法替换缺失值NaN
缺失值NaN的生成和判定
当使用np.genfromtxt()读取CSV文件时,默认情况下,缺失部分变为缺失值NaN(非数字)。使用print()打印时,显示nan。
import numpy as np
a = np.genfromtxt('./data/12/sample_nan.csv', delimiter=',')
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
使用np.nan或float(‘nan’)显式生成缺少的NaN。此外,可以导入标准库中的math模块并将其用作math.nan。结果都一样。
a_nan = np.array([0, 1, np.nan, float('nan')])
print(a_nan)
# [ 0. 1. nan nan]
用"=="不能进行是否为缺失值(nan)的判定,所以请使用np.isnan()或math.isnan()来判定是否为缺少值(nan)。
print(np.nan == np.nan)
# False
print(np.isnan(np.nan))
# True
np.isnan()也可以用来判定ndarray中每个元素是否判为缺失值NaN。
print(a_nan == np.nan)
# [False False False False]
print(np.isnan(a_nan))
# [False False True True]
np.genfromtxt()参数filling_values的指定
例如,填充值为0时。
a_fill = np.genfromtxt('./data/12/sample_nan.csv', delimiter=',', filling_values=0)
print(a_fill)
# [[11. 12. 0. 14.]
# [21. 0. 0. 24.]
# [31. 32. 33. 34.]]
np.nan_to_num()缺失值NaN的替换
使用np.nan_to_num()替换缺失值NaN。
如果将数组ndarray指定为np.nan_to_num()的第一个参数,则默认情况下会创建一个缺失值替换为0的新ndarray。原始ndarray不变
a = np.genfromtxt('./data/12/sample_nan.csv', delimiter=',')
print(np.nan_to_num(a))
# [[11. 12. 0. 14.]
# [21. 0. 0. 24.]
# [31. 32. 33. 34.]]
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
如果第二个参数设置为False,则原始ndarray将被更改。
print(np.nan_to_num(a, copy=False))
# [[11. 12. 0. 14.]
# [21. 0. 0. 24.]
# [31. 32. 33. 34.]]
print(a)
# [[11. 12. 0. 14.]
# [21. 0. 0. 24.]
# [31. 32. 33. 34.]]
在NumPy 1.17或更高版本中,您可以指定要用第三个参数nan替换的值。
a = np.genfromtxt('./data/12/sample_nan.csv', delimiter=',')
print(np.nan_to_num(a, nan=-1))
# [[11. 12. -1. 14.]
# [21. -1. -1. 24.]
# [31. 32. 33. 34.]]
函数np.nanmean()用于计算不缺少值的元素的平均值,可以将其替换为平均值。
print(np.nanmean(a))
# 23.555555555555557
print(np.nan_to_num(a, nan=np.nanmean(a)))
# [[11. 12. 23.55555556 14. ]
# [21. 23.55555556 23.55555556 24. ]
# [31. 32. 33. 34. ]]
用布尔值索引的方法替换缺失值NaN
使用函数np.isnan()判定缺失值是否为NaN,同时可以获得缺失值的位置为True的ndarray。
a = np.genfromtxt('./data/12/sample_nan.csv', delimiter=',')
print(np.isnan(a))
# [[False False True False]
# [False True True False]
# [False False False False]]
通过上述方法,可以通过将任意值分配给缺失值的位置来替换缺失值。 例如:要将其替换为0时。
a[np.isnan(a)] = 0
print(a)
# [[11. 12. 0. 14.]
# [21. 0. 0. 24.]
# [31. 32. 33. 34.]]
也可以使用np.nanmean()替换为平均值。
a = np.genfromtxt('./data/12/sample_nan.csv', delimiter=',')
a[np.isnan(a)] = np.nanmean(a)
print(a)
# [[11. 12. 23.55555556 14. ]
# [21. 23.55555556 23.55555556 24. ]
# [31. 32. 33. 34. ]]
Numpy数组(ndarray)中含有缺失值(nan)行和列的删除方法
要删除numpy数组ndarray中包含缺失值NaN的行或列,可以使用np.isnan()确定缺失值,使用any()或all()提取不含缺失值行和列。
在此,将对以下进行说明内容。
- 删除所有的缺失值(NaN)
- 删除包含缺失值(NaN)的行
- 删除包含缺失值(NaN)的列
例如,通过np.genfromtxt()读取以下缺少数据的csv。缺失部分成为缺失值NaN。
import numpy as np
a = np.genfromtxt('./data/13/sample_nan.csv', delimiter=',')
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
删除所有的缺失值(NaN)
使用函数np.isnan()来确定是否含有缺失值NaN,缺失值的位置的返回值为True。
print(np.isnan(a))
# [[False False True False]
# [False True True False]
# [False False False False]]
通过使用取反运算符〜在此ndarray中将缺失值NaN的位置设置为False,可以删除缺失值(提取不缺失值的元素),但由于剩余元素的数量不同,因此可以删除原始数组ndarray的形状不会保留,而是被展平。
print(~np.isnan(a))
# [[ True True False True]
# [ True False False True]
# [ True True True True]]
print(a[~np.isnan(a)])
# [11. 12. 14. 21. 24. 31. 32. 33. 34.]
删除包含缺失值(NaN)的行
要删除包含缺失值NaN的行,可以使用any()方法,如果NumPy数组行中有一个缺失值则整行返回True。
如果参数axis= 1,则确定每一行是否有缺失值。
print(np.isnan(a).any(axis=1))
# [ True True False]
使用取反运算符〜将没有缺失值的行设置为True。
print(~np.isnan(a).any(axis=1))
# [False False True]
删除包含缺失值的行。
print(a[~np.isnan(a).any(axis=1), :])
# [[31. 32. 33. 34.]]
print(a[~np.isnan(a).any(axis=1)])
# [[31. 32. 33. 34.]]
删除包含缺失值(NaN)的列
删除包含缺失值NaN的列时也是如此。 如果在any()中参数axis= 0,则确定每一列是否至少有一个True。使用取反运算符〜将没有任何缺失值的列设置为True。
print(~np.isnan(a).any(axis=0))
# [ True False False True]
删除包含缺失值的列。
print(a[:, ~np.isnan(a).any(axis=0)])
# [[11. 14.]
# [21. 24.]
# [31. 34.]]
如果只想删除缺少值的列,请使用all()而不是any()。
a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
a[2, 2] = np.nan
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. nan 34.]]
print(a[:, ~np.isnan(a).any(axis=0)])
# [[11. 14.]
# [21. 24.]
# [31. 34.]]
print(a[:, ~np.isnan(a).all(axis=0)])
# [[11. 12. 14.]
# [21. nan 24.]
# [31. 32. 34.]]
NumPy数组ndarray的显示格式(位数,指数符号,零填充等)的指定
通过print()显示NumPy数组ndarray时,可以通过numpy.set_printoptions()来更改显示格式(位数,指数符号,零填充等)。
设置后,脚本将使用该设置。
np.set_printoptions()的设置是通过print()显示时的设置,原始ndarary本身的值不会更改。
在此:
-
指定小数点后的位数(precision, floatmode)
-
使用/不使用指数表示法(suppress)
-
各种类型的格式指定(formatter)
-
指定小数点后的位数
-
指数
-
整数零填充
-
指定小数点后的位数(precision, floatmode)
precision
使用参数precision指定小数点后的位数。
可以使用np.get_printoptions()显示当前设置。每个参数的值以字典dict格式返回。
import numpy as np
print(np.get_printoptions())
# {'edgeitems': 3, 'threshold': 1000, 'floatmode': 'maxprec', 'precision': 8, 'suppress': False, 'linewidth': 75, 'nanstr': 'nan', 'infstr': 'inf', 'sign': '-', 'formatter': None, 'legacy': False}
precision是小数点后的位数的设置,而不是有效位数的设置,所以它不影响整数部分。 默认值为precision = 8。
a = np.array([12.3456, 0.123456789])
print(a)
# [12.3456 0.12345679]
np.set_printoptions(precision=3)
print(a)
# [12.346 0.123]
np.set_printoptions(precision=10)
print(a)
# [12.3456 0.123456789]
floatmode
小数点后的显示格式可以通过参数floatmode选择。 默认值为floatmode = maxprec。每个元素都显示有所需的位数。尾部不填充零。
np.set_printoptions(precision=4, floatmode='maxprec')
print(a)
# [12.3456 0.1235]
np.set_printoptions(precision=10, floatmode='maxprec')
print(a)
# [12.3456 0.123456789]
在floatmode = fixed中,所有元素的位数固定为精度值。尾部零填充。
np.set_printoptions(precision=4, floatmode='fixed')
print(a)
# [12.3456 0.1235]
np.set_printoptions(precision=10, floatmode='fixed')
print(a)
# [12.3456000000 0.1234567890]
在floatmode = maxprec_equal中,其他元素用零填充到具有最大位数的元素上。
np.set_printoptions(precision=4, floatmode='maxprec_equal')
print(a)
# [12.3456 0.1235]
np.set_printoptions(precision=10, floatmode='maxprec_equal')
print(a)
# [12.345600000 0.123456789]
floatmode = unique会显示每个元素所需的位数,而与精度值无关。
np.set_printoptions(precision=4, floatmode='unique')
print(a)
# [12.3456 0.123456789]
np.set_printoptions(precision=10, floatmode='unique')
print(a)
# [12.3456 0.123456789]
np.round()
如上所述,np.set_printoptions()的设置是通过print()显示时的设置,原始ndarary本身的值不变,并且不会生成新的ndarray。
如果要生成一个新的ndarray,它舍入为任意位数,使用np.round()。
在np.round()中,第一个参数指定目标ndarray,第二个参数指定小数点后的位数。如果对数字位数使用负值,则也可以四舍五入为整数位数。
b = np.round(a, 2)
print(b)
# [12.35 0.12]
b = np.round(a, -1)
print(b)
# [10. 0.]
b = np.round([1234.56, 123456.789], -2)
print(b)
# [ 1200. 123500.]
使用/不使用指数表示法(suppress)
默认情况下,当ndarray的最小值小于1e-4(= 0.0001)或最大值与最小值之比大于1e3(= 1000)时,将以指数符号显示。 当采用指数表示法时,所有元素都采用指数表示法。
a = np.array([0.123456, 0.123456])
print(a)
# [0.123456 0.123456]
a = np.array([0.123456, 0.0000123456])
print(a)
# [1.23456e-01 1.23456e-05]
a = np.array([123.456, 0.0123456])
print(a)
# [1.23456e+02 1.23456e-02]
Numpy使用sort和argsort函数进行(行・列)排序
如果将NumPy函数numpy.sort()应用于二维NumPy数组ndarray,则可以获得一个ndarray,其中每一行和每一列的值都按升序分别排序。
如果要按特定的行或列进行排序,请使用numpy.argsort()。
numpy.argsort()是一个返回索引ndarray而不是排序值的函数。
将描述以下内容。
- 如何使用numpy.sort():获取排序数组ndarray
- 如何使用ndarray.sort():排序数组ndarray本身
- 如何使用numpy.argsort():获取排序索引的数组ndarray
- 如何按特定的行或列排序
如何使用numpy.sort():获取排序数组ndarray
一维数组
将原始数组ndarray指定为第一个参数。
对于一维数组,它只是按升序排序。
返回一个新的已排序的ndarray,保留原始的ndarray不变。
import numpy as np
a = np.array([3, 4, 2, 0, 1])
print(a)
# [3 4 2 0 1]
a_sort = np.sort(a)
print(a_sort)
# [0 1 2 3 4]
print(a)
# [3 4 2 0 1]
ndarray方法sort()用于更新ndarray本身。见下文。
np.sort()函数没有反向参数,这与Python标准的sort()方法和sorted()函数不同。如果要降序使用切片[::-1]。
a_sort_reverse = np.sort(a)[::-1]
print(a_sort_reverse)
# [4 3 2 1 0]
多维数组
以二维数组为例。
a_2d = np.array([[20, 3, 100], [1, 200, 30], [300, 10, 2]])
print(a_2d)
# [[ 20 3 100]
# [ 1 200 30]
# [300 10 2]]
选择要按参数轴排序的轴。
对于二维数组,axis = 0在列上排序,而axis = 1在行上排序。每列/行中的值分别进行排序。
a_2d_sort_col = np.sort(a_2d, axis=0)
print(a_2d_sort_col)
# [[ 1 3 2]
# [ 20 10 30]
# [300 200 100]]
a_2d_sort_row = np.sort(a_2d, axis=1)
print(a_2d_sort_row)
# [[ 3 20 100]
# [ 1 30 200]
# [ 2 10 300]]
默认值为axis = -1,它沿最后一个轴排序。如果是二维数组,则按行排序。
a_2d_sort_row = np.sort(a_2d)
print(a_2d_sort_row)
# [[ 3 20 100]
# [ 1 30 200]
# [ 2 10 300]]
a_2d_sort_row = np.sort(a_2d, axis=-1)
print(a_2d_sort_row)
# [[ 3 20 100]
# [ 1 30 200]
# [ 2 10 300]]
如果要降序,请对每个轴使用切片[::-1]。末尾的;;可以省略([::-1]等效于[::-1,:])。
a_2d_sort_col_reverse = np.sort(a_2d, axis=0)[::-1]
print(a_2d_sort_col_reverse)
# [[300 200 100]
# [ 20 10 30]
# [ 1 3 2]]
a_2d_sort_row_reverse = np.sort(a_2d, axis=1)[:, ::-1]
print(a_2d_sort_row_reverse)
# [[100 20 3]
# [200 30 1]
# [300 10 2]]
如何使用ndarray.sort():排序数组ndarray本身
除了函数外,还提供sort()作为NumPy数组ndarray的方法。
ndarray本身已排序和更新。参数与numpy.sort()函数相同。
print(a_2d)
# [[ 20 3 100]
# [ 1 200 30]
# [300 10 2]]
a_2d.sort()
print(a_2d)
# [[ 3 20 100]
# [ 1 30 200]
# [ 2 10 300]]
a_2d.sort(axis=0)
print(a_2d[::-1])
# [[ 3 30 300]
# [ 2 20 200]
# [ 1 10 100]]
如何使用numpy.argsort():获取排序索引的数组ndarray
np.argsort()返回排序索引的ndarray(在原始ndarray中的位置,从0 = 0开始),而不是按值。参数轴等的概念与np.sort()相同。
a_2d = np.array([[20, 3, 100], [1, 200, 30], [300, 10, 2]])
print(a_2d)
# [[ 20 3 100]
# [ 1 200 30]
# [300 10 2]]
a_2d_sort_col_index = np.argsort(a_2d, axis=0)
print(a_2d_sort_col_index)
# [[1 0 2]
# [0 2 1]
# [2 1 0]]
a_2d_sort_row_index = np.argsort(a_2d)
print(a_2d_sort_row_index)
# [[1 0 2]
# [0 2 1]
# [2 1 0]]
如何按特定的行或列排序
使用np.argsort()按任何行或列对多维数组进行排序,而不是像np.sort()那样对每一行或列进行排序。
使用np.argsort()获取参考行或列索引并相应地重新排列行和列的流程。
按特定列排序
使用np.argsort()获取参考行或列索引。
print(a_2d)
# [[ 20 3 100]
# [ 1 200 30]
# [300 10 2]]
col_num = 1
print(a_2d[:, col_num])
# [ 3 200 10]
print(np.argsort(a_2d[:, col_num]))
# [0 2 1]
根据该索引对行进行排序。
a_2d_sort_col_num = a_2d[np.argsort(a_2d[:, col_num])]
print(a_2d_sort_col_num)
# [[ 20 3 100]
# [300 10 2]
# [ 1 200 30]]
如果要使用降序,请以相反的顺序使用[::-1]以通过np.argsort()获得索引。
print(np.argsort(a_2d[:, col_num])[::-1])
# [1 2 0]
a_2d_sort_col_num_reverse = a_2d[np.argsort(a_2d[:, col_num])[::-1]]
print(a_2d_sort_col_num_reverse)
# [[ 1 200 30]
# [300 10 2]
# [ 20 3 100]]
按特定行排序
行与列相同。
row_num = 1
print(a_2d[row_num])
# [ 1 200 30]
print(np.argsort(a_2d[row_num]))
# [0 2 1]
a_2d_sort_row_num = a_2d[:, np.argsort(a_2d[row_num])]
print(a_2d_sort_row_num)
# [[ 20 100 3]
# [ 1 30 200]
# [300 2 10]]
print(np.argsort(a_2d[row_num])[::-1])
# [1 2 0]
a_2d_sort_row_num_inverse = a_2d[:, np.argsort(a_2d[row_num])[::-1]]
print(a_2d_sort_row_num_inverse)
# [[ 3 100 20]
# [200 30 1]
# [ 10 2 300]]
NumPy数组ndarray以任何顺序排列行和列
NumPy数组ndarray的行和列可以使用称为花哨索引的机制以任何顺序重新排列(替换)。
分别描述行和列的情况。
-
以任何顺序对列进行排序
-
以任何顺序对行进行排序
import numpy as np
a = np.arange(10, 35).reshape(5, 5)
print(a)
# [[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]]
以任何顺序对列进行排序
可以通过以任何顺序引用索引列表来获得排序后的ndarray。
col_swap = a[:, [3, 2, 4, 0, 1]]
print(col_swap)
# [[13 12 14 10 11]
# [18 17 19 15 16]
# [23 22 24 20 21]
# [28 27 29 25 26]
# [33 32 34 30 31]]
如果要反转,切片::-1比列表更容易。
col_inverse = a[:, ::-1]
print(col_inverse)
# [[14 13 12 11 10]
# [19 18 17 16 15]
# [24 23 22 21 20]
# [29 28 27 26 25]
# [34 33 32 31 30]]
也可以仅提取(选择)特定的列。即使它们重叠也可以。
col_select = a[:, [2, 4, 0]]
print(col_select)
# [[12 14 10]
# [17 19 15]
# [22 24 20]
# [27 29 25]
# [32 34 30]]
col_select2 = a[:, [2, 2, 2]]
print(col_select2)
# [[12 12 12]
# [17 17 17]
# [22 22 22]
# [27 27 27]
# [32 32 32]]
以任何顺序对行进行排序
行与列相同。
向后的索引::可以省略([…,:]等效于[…])。
row_swap = a[[3, 2, 4, 0, 1], :]
print(row_swap)
# [[25 26 27 28 29]
# [20 21 22 23 24]
# [30 31 32 33 34]
# [10 11 12 13 14]
# [15 16 17 18 19]]
row_swap = a[[3, 2, 4, 0, 1]]
print(row_swap)
# [[25 26 27 28 29]
# [20 21 22 23 24]
# [30 31 32 33 34]
# [10 11 12 13 14]
# [15 16 17 18 19]]
row_inverse = a[::-1]
print(row_inverse)
# [[30 31 32 33 34]
# [25 26 27 28 29]
# [20 21 22 23 24]
# [15 16 17 18 19]
# [10 11 12 13 14]]
row_select = a[[2, 4, 0]]
print(row_select)
# [[20 21 22 23 24]
# [30 31 32 33 34]
# [10 11 12 13 14]]
row_select2 = a[[2, 2, 2]]
print(row_select2)
# [[20 21 22 23 24]
# [20 21 22 23 24]
# [20 21 22 23 24]]
NumPy数组ndarray中计算满足条件的元素的个数
连同示例代码一起说明了一种计算满足NumPy数组ndarray条件的元素数量的方法。
将描述以下内容。
-
全体ndarray中满足条件的元素数的计算
-
计算ndarray的每一行和每一列满足条件的元素数
-
使用numpy.any()(全体,行/列)检查是否有满足条件的元素
-
使用numpy.all()检查所有元素是否都满足条件(全体,行/列)
-
多种条件
全体ndarray中满足条件的元素数的计算
将ndarray与标量值进行比较将返回以布尔值(True,False)作为元素的ndarray。您可以将<,==,!=等进行比较。
import numpy as np
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(a < 4)
# [[ True True True True]
# [False False False False]
# [False False False False]]
print(a % 2 == 1)
# [[False True False True]
# [False True False True]
# [False True False True]]
使用np.count_nonzero()获得True的数量,即满足条件的元素的数量
print(np.count_nonzero(a < 4))
# 4
print(np.count_nonzero(a % 2 == 1))
# 6
计算ndarray的每一行和每一列满足条件的元素数
通过指定参数轴,为每个轴(每个维度)处理多维数组的Np.count_nonzero()。
在二维数组的情况下,将在参数axis= 0的列中进行处理,在axis= 1的行中进行处理。通过使用它,可以计算满足每一行和每一列条件的元素的数量。
print(np.count_nonzero(a < 4, axis=0))
# [1 1 1 1]
print(np.count_nonzero(a < 4, axis=1))
# [4 0 0]
print(np.count_nonzero(a % 2 == 1, axis=0))
# [0 3 0 3]
print(np.count_nonzero(a % 2 == 1, axis=1))
# [2 2 2]
自版本1.12.0起,可以使用np.count_nonzero()指定参数轴。由于np.sum()自1.7.0版以来已实现参数轴,因此可以将np.sum()用于较早的版本。
使用numpy.any()(全体,行/列)检查是否有满足条件的元素
np.any()是一个函数,如果在作为第一个参数传递的ndarray中至少有一个True元素,则返回True,否则返回False。
print(np.any(a < 4))
# True
print(np.any(a > 100))
# False
与np.count_nonzero()类似,如果指定了参数轴,则np.any()将处理每一行和每一列。
print(np.any(a < 4, axis=0))
# [ True True True True]
print(np.any(a < 4, axis=1))
# [ True False False]
使用numpy.all()检查所有元素是否都满足条件(全体,行/列)
np.all()是一个函数,如果在第一个参数中传递的ndarray的所有元素均为True,则返回True,否则返回False。
print(np.all(a < 4))
# False
print(np.all(a < 100))
# True
与np.count_nonzero()相似,当指定参数轴时,将对每一行和每一列处理np.all()。
print(np.all(a < 4, axis=0))
# [False False False False]
print(np.all(a < 4, axis=1))
# [ True False False]
多种条件
如果要组合多个条件,请将每个条件表达式括在()中,并将其与&或|连接。
print((a < 4) | (a % 2 == 1))
# [[ True True True True]
# [False True False True]
# [False True False True]]
print(np.count_nonzero((a < 4) | (a % 2 == 1)))
# 8
print(np.count_nonzero((a < 4) | (a % 2 == 1), axis=0))
# [1 3 1 3]
print(np.count_nonzero((a < 4) | (a % 2 == 1), axis=1))
# [4 2 2]
请注意,如果省略括号()或使用and和or,将发生错误。
NumPy数组ndarray中提取,删除满足条件的元素,行和列
-
提取符合条件的元素
-
提取符合条件的行和列
- 使用numpy.all()提取所有元素均满足条件的行和列
- 使用numpy.any()提取具有至少一个满足条件的元素的行/列
-
删除符合条件的元素,行和列
- 使用否定运算符〜
- 使用numpy.delete()和numpy.where()
-
对于多种条件
提取符合条件的元素
如果要提取满足条件的元素,请使用ndarray [条件表达式]。
即使原始ndarray是多维数组,它也将返回一个展平的一维数组。
import numpy as np
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(a < 5)
# [[ True True True True]
# [ True False False False]
# [False False False False]]
print(a[a < 5])
# [0 1 2 3 4]
print(a < 10)
# [[ True True True True]
# [ True True True True]
# [ True True False False]]
print(a[a < 10])
# [0 1 2 3 4 5 6 7 8 9]
返回一个新的数组ndarray,保留原来的ndarray不变。以下示例是相同的。
b = a[a < 10]
print(b)
# [0 1 2 3 4 5 6 7 8 9]
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
也可以计算满足条件的元素的总和(sum(),平均均值(),最大值max(),最小值min()和标准差std()。
print(a[a < 5].sum())
# 10
print(a[a < 5].mean())
# 2.0
print(a[a < 5].max())
# 4
print(a[a < 10].min())
# 0
print(a[a < 10].std())
# 2.8722813232690143
提取符合条件的行和列
在提取元素的示例中,返回了一个一维数组,但是如果使用np.all(),np.any(),则可以在保留原始ndarray尺寸的同时提取行和列。
将描述以下两种类型。
- numpy.all():提取所有元素均满足条件的行/列
- numpy.any():提取具有至少一个满足条件的元素的行/列
使用numpy.all()提取所有元素均满足条件的行和列
np.all()是一个函数,如果在第一个参数中传递的ndarray的所有元素均为True,则返回True,否则返回Flase。
如果传递参数轴,则每个轴(每个尺寸)的所有元素均为True时,将返回True。对于二维数组,axis = 0将是列的结果,而axis = 1将是行的结果。
print(a < 5)
# [[ True True True True]
# [ True False False False]
# [False False False False]]
print(np.all(a < 5))
# False
print(np.all(a < 5, axis=0))
# [False False False False]
print(np.all(a < 5, axis=1))
# [ True False False]
print(a < 10)
# [[ True True True True]
# [ True True True True]
# [ True True False False]]
print(np.all(a < 10, axis=0))
# [ True True False False]
print(np.all(a < 10, axis=1))
# [ True True False]
将每个结果提供给行或列索引参考[行,列]时,将提取所需的行/列。在[line,:]的情况下,可以省略尾随的::。
print(a[:, np.all(a < 10, axis=0)])
# [[0 1]
# [4 5]
# [8 9]]
print(a[np.all(a < 10, axis=1), :])
# [[0 1 2 3]
# [4 5 6 7]]
print(a[np.all(a < 10, axis=1)])
# [[0 1 2 3]
# [4 5 6 7]]
如果不满足条件,则返回一个空的ndarray。
print(a[:, np.all(a < 5, axis=0)])
# []
即使只有一行或一列,维数也不会改变。
print(a[np.all(a < 5, axis=1)])
# [[0 1 2 3]]
print(a[np.all(a < 5, axis=1)].ndim)
# 2
print(a[np.all(a < 5, axis=1)].shape)
# (1, 4)
使用numpy.any()提取具有至少一个满足条件的元素的行/列
np.any()是一个函数,如果在作为第一个参数传递的ndarray中至少有一个True元素,则返回True,否则返回Flase。
如果传递参数轴,则每个轴(每个尺寸)至少有一个True元素时,将返回True。对于二维数组,axis = 0将是列的结果,而axis = 1将是行的结果。
print(a < 5)
# [[ True True True True]
# [ True False False False]
# [False False False False]]
print(np.any(a < 5))
# True
print(np.any(a < 5, axis=0))
# [ True True True True]
print(np.any(a < 5, axis=1))
# [ True True False]
可以按照与np.all()相同的方式提取满足条件的行和列。
print(a[:, np.any(a < 5, axis=0)])
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(a[np.any(a < 5, axis=1)])
# [[0 1 2 3]
# [4 5 6 7]]
删除符合条件的元素,行和列
如果要删除元素/行/列而不是根据条件提取(获取),则有以下两种方法。
- 使用否定运算符〜
- 使用numpy.delete()和numpy.where()
使用否定运算符~
如果将负运算符〜添加到条件中,则将提取不满足条件的元素,行和列。这等效于删除满足条件的元素/行/列。
print(a[~(a < 5)])
# [ 5 6 7 8 9 10 11]
print(a[:, np.all(a < 10, axis=0)])
# [[0 1]
# [4 5]
# [8 9]]
print(a[:, ~np.all(a < 10, axis=0)])
# [[ 2 3]
# [ 6 7]
# [10 11]]
print(a[np.any(a < 5, axis=1)])
# [[0 1 2 3]
# [4 5 6 7]]
print(a[~np.any(a < 5, axis=1)])
# [[ 8 9 10 11]]
使用numpy.delete()和numpy.where()
行和列也可以使用np.delete()和np.where()删除。
np.delete()将目标ndarray,要删除的索引(行号,列号等)以及目标轴(维)轴设置为参数。
在二维数组的情况下,axis = 0删除行,而axis = 1删除列,这与上面的np.all()和np.any()不同。
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.delete(a, [0, 2], axis=0))
# [[4 5 6 7]]
print(np.delete(a, [0, 2], axis=1))
# [[ 1 3]
# [ 5 7]
# [ 9 11]]
np.where()返回满足条件的元素的索引。
对于多维数组,它是满足每个维(行,列)条件的索引(行号,列号)列表的元组。
print(a < 2)
# [[ True True False False]
# [False False False False]
# [False False False False]]
print(np.where(a < 2))
# (array([0, 0]), array([0, 1]))
print(np.where(a < 2)[0])
# [0 0]
print(np.where(a < 2)[1])
# [0 1]
通过组合这两个功能,可以删除满足条件的行和列。
print(np.delete(a, np.where(a < 2)[0], axis=0))
# [[ 4 5 6 7]
# [ 8 9 10 11]]
print(np.delete(a, np.where(a < 2)[1], axis=1))
# [[ 2 3]
# [ 6 7]
# [10 11]]
print(a == 6)
# [[False False False False]
# [False False True False]
# [False False False False]]
print(np.where(a == 6))
# (array([1]), array([2]))
print(np.delete(a, np.where(a == 6)))
# [ 0 3 4 5 6 7 8 9 10 11]
print(np.delete(a, np.where(a == 6)[0], axis=0))
# [[ 0 1 2 3]
# [ 8 9 10 11]]
print(np.delete(a, np.where(a == 6)[1], axis=1))
# [[ 0 1 3]
# [ 4 5 7]
# [ 8 9 11]]
如上例所示,删除甚至具有一个满足条件的元素的行/列(与使用np.any()时相同)。
如果执行诸如计算由np.where()获取的索引数之类的处理,则可以删除满足所有条件的行和列(与使用np.all()时相同),但是np使用.all()更容易。
对于多种条件
如果要组合多个条件,请将每个条件表达式括在()中,并将其与&或|连接。
print(a[(a < 10) & (a % 2 == 1)])
# [1 3 5 7 9]
print(a[np.any((a == 2) | (a == 10), axis=1)])
# [[ 0 1 2 3]
# [ 8 9 10 11]]
print(a[:, ~np.any((a == 2) | (a == 10), axis=0)])
# [[ 0 1 3]
# [ 4 5 7]
# [ 8 9 11]]
NumPy如何使用insert将元素/行/列插入/添加到数组ndarray
- numpy.insert()概述
- 一维数组
- 使用numpy.insert()插入和添加元素
- 替换元素
- 二维数组的行
- 使用numpy.insert()插入和添加行
- 在numpy.vstack()的开头和结尾添加行
- 行的置换
- 二维数组的列
- 使用numpy.insert()插入和添加列
- 在numpy.vstack()的开头和结尾添加列
- 列的置换
numpy.insert()概述
np.insert()函数的参数如下。
- arr:原始NumPy数组ndarray
- obj:插入值的位置,int,slice,list
- value:要插入的元素/行/列的值
- axis:插入值的轴(尺寸)
原始的NumPy数组ndarray保持不变,并返回一个新的ndarray。
一维数组
使用numpy.insert()插入和添加元素
将元素插入一维数组时,请设置参数axis = np.insert()的值无(默认值可以省略)。
还可以通过在列表或数组中指定参数值来插入多个元素。
import numpy as np
a = np.arange(4)
print(a)
# [0 1 2 3]
print(np.insert(a, 2, 100))
# [ 0 1 100 2 3]
print(np.insert(a, 1, [100, 101, 102]))
# [ 0 100 101 102 1 2 3]
print(np.insert(a, [0, 2, 4], [100, 101, 102]))
# [100 0 1 101 2 3 102]
替换元素
如果要替换一维数组的元素,可以编写:原始的ndarray值被替换了,因此为方便起见创建并处理了一个副本。
_a = a.copy()
_a[1] = 100
print(_a)
# [ 0 100 2 3]
_a = a.copy()
_a[1:3] = [100, 101]
print(_a)
# [ 0 100 101 3]
在替换前后更改ndarray形状的操作将导致错误。例如,如果要用多个元素替换一个元素。
# _a = a.copy()
# _a[1] = [100, 101, 102]
# print(_a)
# ValueError: setting an array element with a sequence.
用np.insert()插入并用np.delete()删除不必要的值后,可以获得所需的数组。
_a = np.insert(a, 1, [100, 101, 102])
_a = np.delete(_a, 4)
print(_a)
# [ 0 100 101 102 2 3]
二维数组的行
使用numpy.insert()插入和添加行
如果参数axis = None(默认值),则即使原始ndarray是多维数组,也将返回展平的一维数组。
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.insert(a, 2, 100))
# [ 0 1 100 2 3 4 5 6 7 8 9 10 11]
numpy中reshape函数的三种常见相关用法
- numpy.arange(n).reshape(a, b) 依次生成n个自然数,并且以a行b列的数组形式显示
np.arange(16).reshape(2,8) #生成16个自然数,以2行8列的形式显示
# Out:
# array([[ 0, 1, 2, 3, 4, 5, 6, 7],
# [ 8, 9, 10, 11, 12, 13, 14, 15]])
- mat (or array).reshape(c, -1) 必须是矩阵格式或者数组格式,才能使用 .reshape(c, -1) 函数, 表示将此矩阵或者数组重组,以 c行d列的形式表示
arr.shape # (a,b)
arr.reshape(m,-1) #改变维度为m行、d列 (-1表示列数自动计算,d= a*b /m )
arr.reshape(-1,m) #改变维度为d行、m列 (-1表示行数自动计算,d= a*b /m )
-1的作用就在此**: 自动计算d:d=数组或者矩阵里面所有的元素个数/c**, d必须是整数,不然报错)
(reshape(-1, m)即列数固定,行数需要计算)
arr=np.arange(16).reshape(2,8)
arr
'''
out:
array([[ 0, 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14, 15]])
'''
arr.reshape(4,-1) #将arr变成4行的格式,列数自动计算的(c=4, d=16/4=4)
'''
out:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
'''
arr.reshape(8,-1) #将arr变成8行的格式,列数自动计算的(c=8, d=16/8=2)
'''
out:
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11],
[12, 13],
[14, 15]])
'''
arr.reshape(10,-1) #将arr变成10行的格式,列数自动计算的(c=10, d=16/10=1.6 != Int)
'''
out:
ValueError: cannot reshape array of size 16 into shape (10,newaxis)
'''
- numpy.arange(a,b,c) 从 数字a起, 步长为c, 到b结束,生成array
- numpy.arange(a,b,c).reshape(m,n) :将array的维度变为m 行 n列。
np.arange(1,12,2)#间隔2生成数组,范围在1到12之间
# Out: array([ 1, 3, 5, 7, 9, 11])
np.arange(1,12,2).reshape(3,2)
'''
Out:
array([[ 1, 3],
[ 5, 7],
[ 9, 11]])
'''
numpy中reshape函数的三种常见相关用法
- numpy.arange(n).reshape(a, b) 依次生成n个自然数,并且以a行b列的数组形式显示
np.arange(16).reshape(2,8) #生成16个自然数,以2行8列的形式显示
# Out:
# array([[ 0, 1, 2, 3, 4, 5, 6, 7],
# [ 8, 9, 10, 11, 12, 13, 14, 15]])
- mat (or array).reshape(c, -1) 必须是矩阵格式或者数组格式,才能使用 .reshape(c, -1) 函数, 表示将此矩阵或者数组重组,以 c行d列的形式表示
arr.shape # (a,b)
arr.reshape(m,-1) #改变维度为m行、d列 (-1表示列数自动计算,d= a*b /m )
arr.reshape(-1,m) #改变维度为d行、m列 (-1表示行数自动计算,d= a*b /m )
-1的作用就在此**: 自动计算d:d=数组或者矩阵里面所有的元素个数/c**, d必须是整数,不然报错)
(reshape(-1, m)即列数固定,行数需要计算)
arr=np.arange(16).reshape(2,8)
arr
'''
out:
array([[ 0, 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14, 15]])
'''
arr.reshape(4,-1) #将arr变成4行的格式,列数自动计算的(c=4, d=16/4=4)
'''
out:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
'''
arr.reshape(8,-1) #将arr变成8行的格式,列数自动计算的(c=8, d=16/8=2)
'''
out:
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11],
[12, 13],
[14, 15]])
'''
arr.reshape(10,-1) #将arr变成10行的格式,列数自动计算的(c=10, d=16/10=1.6 != Int)
'''
out:
ValueError: cannot reshape array of size 16 into shape (10,newaxis)
'''
- numpy.arange(a,b,c) 从 数字a起, 步长为c, 到b结束,生成array
- numpy.arange(a,b,c).reshape(m,n) :将array的维度变为m 行 n列。
np.arange(1,12,2)#间隔2生成数组,范围在1到12之间
# Out: array([ 1, 3, 5, 7, 9, 11])
np.arange(1,12,2).reshape(3,2)
'''
Out:
array([[ 1, 3],
[ 5, 7],
[ 9, 11]])
'''