numpy教程

1. NumPy ndarray对象

NumPy 定义了一个 n 维数组对象,简称 ndarray 对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块,您可以使用索引或切片的方式获取数组中的每个元素。

ndarray 对象采用了数组的索引机制,将数组中的每个元素映射到内存块上,并且按照一定的布局对内存块进行排列,常用的布局方式有两种,即按行或者按列。

1.1创建ndarray对象

通过 NumPy 的内置函数 array() 可以创建 ndarray 对象,其语法格式如下:

numpy.array(object, dtype = None, copy = True, order = None,ndmin = 0)

下面表格对其参数做了说明:

序号参数描述说明
1object表示一个序列。
2dtype可选参数,通过它可以更改数组的数据类型。
3copy可选参数,表示数组能否被复制,默认是 True。
4order以哪种内存布局创建数组,有 3 个可选值,分别是 C(行序列)/F(列序列)/A(默认)。
5ndmin用于指定数组的维度。
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数据类型

序号数据类型语言描述
1bool_布尔型数据类型(True 或者 False)
2int_默认整数类型,类似于 C 语言中的 long,取值为 int32 或 int64
3intc和 C 语言的 int 类型一样,一般是 int32 或 int 64
4intp用于索引的整数类型(类似于 C 的 ssize_t,通常为 int32 或 int64)
5int8代表与1字节相同的8位整数。值的范围是-128到127。
6int16代表 2 字节(16位)的整数。范围是-32768至32767。
7int32代表 4 字节(32位)整数。范围是-2147483648至2147483647。
8int64表示 8 字节(64位)整数。范围是-9223372036854775808至9223372036854775807。
9uint8代表1字节(8位)无符号整数。
10uint162 字节(16位)无符号整数。
11uint324 字节(32位)的无符号整数。
12uint648 字节(64位)的无符号整数。
13float_float64 类型的简写。
14float16半精度浮点数,包括:1 个符号位,5 个指数位,10个尾数位。
15float32单精度浮点数,包括:1 个符号位,8 个指数位,23个尾数位。
16float64双精度浮点数,包括:1 个符号位,11 个指数位,52个尾数位。
17complex_复数类型,与 complex128 类型相同。
18complex64表示实部和虚部共享 32 位的复数。
19complex128表示实部和虚部共享 64 位的复数。
20str_表示字符串类型
21string_表示字节串类型

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)
Mdatatime(日期时间)
OPython对象
S,a字节串(S)与字符串(a)
UUnicode
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 数组的数据类型。

根据startstop指定的范围以及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)的数组,数组的每一个元素在(01)之间
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位运算

序号函数位运算符描述说明
1bitwise_and&计算数组元素之间的按位与运算。
2bitwise_or|计算数组元素之间的按位或运算。
3invert~计算数组元素之间的按位取反运算。
4left_shift<<将二进制数的位数向左移。
5right_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。

位与运算的真值表,如下所示:

ABAND(A,B)
000
010
100
111

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,其真值表如下:

ABOR(A,B)
000
011
101
111

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]])
'''
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哒啵Q_git

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值