函数定义:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型 |
copy | 对象是否需要复制 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
常用的参数有object,dtype以及ndmin,举例如下:
import numpy as np
a = np.array([1, 2, 3, 4, 5])
b = np.array([1, 2, 3, 4, 5], dtype = complex, ndmin = 2)
print("a最低(默认)一维,默认类型为整数: ",a)
print("b最低二维,数据类型为复数: ",b)
# 结果为:
# a最低(默认)一维,默认类型为整数: [1 2 3 4 5]
# b最低二维,数据类型为复数: [[1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j]]
函数定义:
numpy.dtype(object, align, copy)
常用的参数为object,即你需要转化为什么数据类型。numpy的数据类型同c/c++/java一样,属于强数据类型,包括np.int8,np.int16,np.float16,np.float32等,int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替。
dtype也可以定义结构化数据类型,如下:
import numpy as np
student = np.dtype([('name', 'S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50), ('xyz', 18, 75)], dtype=student)
print(a)
print("名字:" ,a["name"])
print(type(a[0]["age"]))
# 结果为:
# [(b'abc', 21, 50.)(b'xyz', 18, 75.)]
# 名字: [b'abc' b'xyz']
#
常用属性有:
属性 | 描述 |
---|---|
ndarray.ndim | 秩,即矩阵的维度 |
ndarray.shape | 矩阵的形状 |
ndarray.size | 矩阵元素总数 |
ndarray.dtype | 矩阵元素类型 |
ndarray.itemsize | 矩阵单个元素所占内存 |
范例:
a = np.array([[1, 2, 3], [4, 5, 6]])
print("矩阵的维度: " ,a.ndim)
print("矩阵的形状: ", a.shape)
print("矩阵元素总数: ",a.size )
print("矩阵单个元素所占内存: ", a.itemsize)
# 结果:
# 矩阵的维度: 2
# 矩阵的形状: (2, 3)
# 矩阵元素总数: 6
# 矩阵单个元素所占内存: 4
4.1 随机值、定值创建
使用numpy.empty、numpy.zeros、numpy.ones分别创建元素值为:随机值、0值、1值的数组,方法参数有(shape, dtype , order),参数描述如下:
参数 | 描述 |
---|---|
shape | 数组形状 |
dtype | 元素类型 |
order | 排序方式,‘C’ 代表行优先, 'F’代表列优先 |
4.2 从已有数组中创建数组
4.2.1 numpy.asarray
使用numpy.asarray(object, dtype = None, order = None)方法从已有的元组、列表等变量中创建数组,参数说明如下:
参数 | 描述 |
---|---|
object | 已存在的元组、列表等 |
dtype | 元素类型 |
order | 排序方式,‘C’ 代表行优先, 'F’代表列优先 |
范例:
x = [1, 2, 3]
a = np.asarray(x, dtype=float)
print("将列表转化为数组: " ,a)
# 结果:
# 将列表转化为数组: [1. 2. 3.]
4.2.2 numpy.frombuffer
使用numpy.frombuffer 实现动态数组,以流的形式读入参数,转化成 ndarray 对象,函数定义为:
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
参数说明:
参数 | 描述 |
---|---|
buffer | 任意流对象 |
count | 从流中读取的数据量,值为“-1”时代表读取所有数据 |
offset | 读取数据的起始位置 |
范例:
s1 = b'Hello World'
# s1 = 'Hello World' python 2.x 的写法
a1 = np.frombuffer(s1, dtype='S1',count=4 , offset=3)
print(a1)
#结果:
# [b'l' b'o' b' ' b'W']
注:Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。
4.2.2 numpy.fromiter
该方法可以从一个迭代器中创建数组,函数定义为:
numpy.fromiter(iterable, dtype, count=-1)
参数 | 描述 |
---|---|
iterable | 迭代器对象 |
count | 从流中读取的数据量,值为“-1”时代表读取所有数据 |
范例:
x = [1,2,3,4,5,6]
# 生成迭代器
a = iter(x)
y = np.fromiter(a, dtype=float,count=4)
print(y)
#结果:
# [1. 2. 3. 4.]
4.3 从数值范围中创建数组
4.3.1 numpy.arange
最常用的就是numpy.arange(start, stop, step, dtype)方法,根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
参数 | 描述 |
---|---|
start | 起始数值,默认为0 |
stop | 终止数值,不包含 |
step | 每次增加的步长,默认1 |
范例:
x = np.arange(start=10,stop = 33, step =3, dtype = float)
print(x)
# 结果:
# [10. 13. 16. 19. 22. 25. 28. 31.]
注:生成的范围是左闭右开,不包含终止数值
4.3.2 numpy.linspace
此方法用于创建一个等差数列,函数定义:
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
常用参数说明:
参数 | 描述 |
---|---|
start | 起始数值 |
stop | 终止数值,不包含 |
num | 生成的数列元素个数,默认50 |
endpoint | 是否包含终止数值,true时包含 |
retstep | 为true时生成的数组中会显示间距 |
范例:
a = np.linspace(start=0 ,stop=10,num=5 ,endpoint=True,retstep=True)
print(a)
# 结果:
# (array([ 0. , 2.5, 5. , 7.5, 10. ]), 2.5)
4.3.3 numpy.logspace
此方法用于生成一个等比数列,方法定义为:
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数说明:
参数 | 描述 |
---|---|
start | 起始数值为base**start |
stop | 终止数值为base**stop,不包含 |
num | 生成的数列元素个数,默认50 |
endpoint | 是否包含终止数值,true时包含 |
base | log的底数 |
范例:
a = np.logspace(start=1 ,stop=5,num=6 ,endpoint=True,base=2)
print(a)
# 结果:
# [ 2. 3.48220225 6.06286627 10.55606329 18.37917368 32. ]
切片对象可以通过内置的 slice 函数,函数定义为:
slice(start, stop, step),参数分别为起始位置,终止位置,步长。除此之外,也可以通过“:”来简写切片,规则为:[start:stop:step].
范例:
a = np.arange(10)
s = slice(2,-4,1 ) # 从索引 2 开始到 倒数第4个位置停止,间隔为1
print(a[s])
print(a[2:7:1])
# 结果:
# [2 3 4 5]
# [2 3 4 5 6]
注:
1.当位置为负数时,代表从尾部往前数,-2即倒数第二个位置。
2.在用“:”简写时,省略第一个数代表从第一个元素开始切片,省略第二个数代表切片至最后一个元素,省略最后一个数代表步长为1。切片范围为左闭右开,即不包含最右边的位置。
当切片用于多维数组时,效果大同小异,范例如下:
a = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
print("原数组:", a)
print("第2列元素a[..., 1]: ", a[..., 1])
print("第2行元素a[1, ...]: ", a[1, ...])
print("第2行元素a[1]: ", a[1])
print("第2列及剩下的所有元素a[..., 1:]: ", a[..., 1:])
print("第2行及剩下的所有元素a[1:]: ", a[1:])
print("第1列和第3列元素: ", a[..., 0:3:2])
print("第1行和第3行元素: ", a[0:3:2])
print("第1行和第3行元素: ", a[0:3:2,0:3])
# 结果:
# 原数组: [[0 1 2]
# [3 4 5]
# [6 7 8]]
# 第2列元素a[..., 1]: [1 4 7]
# 第2行元素a[1, ...]: [3 4 5]
# 第2行元素a[1]: [3 4 5]
# 第2列及剩下的所有元素a[..., 1:]: [[1 2]
# [4 5]
# [7 8]]
# 第2行及剩下的所有元素a[1:]: [[3 4 5]
# [6 7 8]]
# 第1列和第3列元素: [[0 2]
# [3 5]
# [6 8]]
# 第1行和第3行元素: [[0 1 2]
# [6 7 8]]
# 第1行和第3行元素: [[0 1 2]
# [6 7 8]]
其中,“…”代表选择元组的长度与数组的维度相同。可以看出,用于多位数列时,位置数字代表相对于的行数或者列数。
4.1 整数数组索引
直接看范例:
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print("原数组: ",x)
print("取位置为(1,1)(0,2)(3,0)的元素:\n")
y = x[[1, 0, 3], [1, 2, 0]]
print(y)
rows = np.array([[0, 0], [3, 3]])
cols = np.array([[0, 2], [0, 2]])
y = x[rows, cols]
print('这个数组的四个角元素是(结果为二维):')
print(y)
rows = np.array([0, 0, 3, 3])
cols = np.array([0, 2, 0, 2])
y = x[rows, cols]
print('这个数组的四个角元素是(结果为一维):')
print(y)
# 使用...和:也能完成上述操作,如下
print("...+:完成: " ,x[0:4:3,0:3:2])
# 结果为:
# 原数组: [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
# 取位置为(1,1)(0,2)(3,0)的元素: [4 2 9]
# 这个数组的四个角元素是(结果为二维):
# [[ 0 2]
# [ 9 11]]
# 这个数组的四个角元素是(结果为一维): [ 0 2 9 11]
# ...+:完成: [[ 0 2]
# [ 9 11]]
x[[1, 0, 3], [1, 2, 0]]写法中,列表前面的元素是行标,后面的元素是列标。
在取四个角坐标时,两种写法类似,行列坐标对应,不过取出的结果的维度不一样,一个为一维,一个为二维。
在用“…”+“:”组合取值时,则是用切片的知识,取第0行、第3行(步长是3)与第0列、第2列(步长是2)的交汇点的值。
4.2 布尔索引
即在取值时加入判断条件,如a[a>5]取a中值大于5的数,a[np.iscomplex(a)]取a中的复数,a[~np.isnan(a)]取a中非NA的数,范例:
a = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])
print(a[~np.isnan(a)])
a = a[~np.isnan(a)]
print(a[a>3])
# 结果:
# [1. 2. 3. 4. 5.]
# [4. 5.]
#结果
4.3 花式索引
直接看范例:
x=np.arange(20).reshape(5,4)
print("原数组: \n",x)
print("取第三、一、五、倒数第二行:\n",x[[2,0,4,-2]])
print("按照0、3、1、2的列序取第0、3、1行的数\n",x[np.ix_([0, 3, 1], [0, 3, 1, 2])])
# 结果:
# 原数组:
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]
# [16 17 18 19]]
# 取第三、一、五、倒数第二行:
# [[ 8 9 10 11]
# [ 0 1 2 3]
# [16 17 18 19]
# [12 13 14 15]]
# 按照0、3、1、2的列序取第0、3、1行的数
# [[ 0 3 1 2]
# [12 15 13 14]
# [ 4 7 5 6]]
可以看出,和前面的切片类似,数字代表行数,负数代表从后往前的位置。
np.ix_([1,5,7,2],[0,3,1,2])函数有两个参数,前面代表行坐标,后面代表列坐标,与前面不同的是,这里一个行坐标会和每一个列坐标都交汇一次,即行坐标“1”会和“[0,3,1,2]”产生四个位置,即(1,0)、(1,3)、(1,1)、(1,2)。
注意注意!!!:
花式索引和布尔索引取得的效果和切片看似类似,但不完全一样,切片相当于“浅拷贝”,相当于取出的值还是在原来的内存,只是简单复制了数值,并未为这个值开辟一个新的内存空间,如果此时修改取出来的这个值,那么原变量的值也会相应改变。而花式索引和布尔索引是“深拷贝”,取出来的值会重新得到一个内存空间,这样修改取出来的值不会影响原来的变量。如果不清楚看下面的例子:
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print("原数组: \n" ,x)
y = x[1:3, 1:3]
print("切片后: \n ",y)
# 更改切片后的变量y(此时并未直接改变原变量x)
y[1][1] = 100
print("切片后的变量y:\n",y)
print("原变量x:\n ",x)
# 结果:
# 原数组:
# [[0 1 2]
# [3 4 5]
# [6 7 8]
# [9 10 11]]
# 切片后:
# [[4 5]
# [7 8]]
# 切片后的变量y:
# [[4 5]
# [7 100]]
# 原变量x:
# [[0 1 2]
# [3 4 5]
# [6 7 100]
# [9 10 11]]
可以看出,在修改切片后的数组y的数值后,原数组x的值也跟着改变了,而对于布尔和花式索引来说,则不会,如下:
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print("原数组: \n" ,x)
y = x[x > 5]
print("切片后: \n ",y)
# 更改切片后的变量y(此时并未直接改变原变量x)
y[2] = 100
print("切片后的变量y:\n",y)
print("原变量x:\n ",x)
# 结果:
# 原数组:
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
# 切片后:
# [ 6 7 8 9 10 11]
# 切片后的变量y:
# [ 6 7 100 9 10 11]
# 原变量x:
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
看到更改y数组后,原x数组并未改变。
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式,当两个数组形状相同时,则两数组相乘时,直接是对应元素相乘,如两数组形状不同,则触发广播机制。例如:
a = np.array([[0, 0, 0],
[10, 10, 10],
[20, 20, 20],
[30, 30, 30]])
b = np.array([1, 2, 3])
print(a + b)
# 结果:
# [[1 2 3]
# [11 12 13]
# [21 22 23]
# [31 32 33]]
广播的规则:
1.让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
2.输出数组的形状是输入数组形状的各个维度上的最大值。
3.如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
4.当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
1.数组拥有相同形状。
2.当前维度的值相等。
3.当前维度的值有一个是 1。
数组中有很多元素,我们可以通过生成一个迭代器,通过逐步迭代来遍历数组元素,范例:
a = np.arange(6).reshape(2, 3)
print('原始数组是:\n' ,a)
print('迭代输出元素:')
for x in np.nditer(a):
print(x, end=", ")
# 结果:
# 原始数组是:
# [[0 1 2]
# [3 4 5]]
# 迭代输出元素:
# 0, 1, 2, 3, 4, 5,
在遍历矩阵的转置时,通常使用a.T来获得矩阵a的装置矩阵,但此时转置矩阵的内存地址还是原来的内存,所以遍历时的结果会和原矩阵一样,且修改转置矩阵时原矩阵也会改变,如下:
a = np.arange(6).reshape(2, 3)
print("原矩阵: \n",a)
y = a.T
print("转置矩阵: \n" ,y)
y[1][1] = 100
print("改变转置矩阵: \n" ,y)
print("原矩阵: \n" ,a )
print("按行优先遍历原矩阵")
for x in np.nditer(a):
print(x, end=", ")
print("\n")
print("按行优先遍历转置矩阵:")
for x in np.nditer(y):
print(x, end=", ")
# 结果:
# 原矩阵:
# [[0 1 2]
# [3 4 5]]
# 转置矩阵:
# [[0 3]
# [1 4]
# [2 5]]
# 改变转置矩阵:
# [[0 3]
# [1 100]
# [2 5]]
# 原矩阵:
# [[0 1 2]
# [3 100 5]]
# 按行优先遍历原矩阵
# 0, 1, 2, 3, 100, 5,
# 按行优先遍历转置矩阵:
# 0, 1, 2, 3, 100, 5,
可以看出,改变转置矩阵y后,原矩阵也改变,且转置矩阵和原矩阵遍历结果一样。
而是用a.T.copy(order=‘C’)得到的转置矩阵会获得新的地址空间,order参数表示何种复制方式,“C”代表行优先,“F”代表列优先
a = np.arange(6).reshape(2, 3)
print("原矩阵: \n",a)
y = a.T.copy(order='C')
print("转置矩阵: \n" ,y)
y[1][1] = 100
print("改变转置矩阵: \n" ,y)
print("原矩阵: \n" ,a )
print("按行优先遍历原矩阵")
for x in np.nditer(a):
print(x, end=", ")
print("\n")
print("按行优先遍历转置矩阵:")
for x in np.nditer(y):
print(x, end=", ")
# 结果:
# 原矩阵:
# [[0 1 2]
# [3 4 5]]
# 转置矩阵:
# [[0 3]
# [1 4]
# [2 5]]
# 改变转置矩阵:
# [[ 0 3]
# [ 1 100]
# [ 2 5]]
# 原矩阵:
# [[0 1 2]
# [3 4 5]]
# 按行优先遍历原矩阵
# 0, 1, 2, 3, 4, 5,
# 按行优先遍历转置矩阵:
# 0, 3, 1, 100, 2, 5,
nditer类的构造器拥有flags参数,它的传入参数有以下:
参数 | 描述 |
---|---|
c_index | 记录行优先遍历时的索引 |
f_index | 记录列优先遍历时的索引 |
multi_index | 每次迭代可以跟踪一种索引类型 |
external_loop | 给出的值是具有多个值的一维数组,而不是零维数组 |
范例:
a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
print('原始数组是:\n' , a)
print('修改后的数组是:')
for x in np.nditer(a, flags=['external_loop'], order='F'):
print(x, end=", ")
# 结果:
# 原始数组是:
# [[0 5 10 15]
# [20 25 30 35]
# [40 45 50 55]]
# 修改后的数组是:
# [0 20 40], [5 25 45], [10 30 50], [15 35 55],
a=np.arange(6).reshape(2,3)
print("记录列遍历索引:")
p = np.nditer(a, flags=['f_index'])
while not p.finished:
print("<%s>" % (p.index) ,end=", ")
p.iternext()
print("\n记录行遍历索引:")
p = np.nditer(a, flags=['f_index'])
while not p.finished:
print("<%s>" % (p.index) ,end=", ")
p.iternext()
# 结果:
# 记录列遍历索引:
# < 0 >, < 2 >, < 4 >, < 1 >, < 3 >, < 5 >,
# 记录行遍历索引:
# < 0 >, < 2 >, < 4 >, < 1 >, < 3 >, < 5 >,
9.1 常用属性
9.1.1 numpy.reshape
numpy.reshape函数用户改变矩阵的形状,函数定义为:
numpy.reshape(arr, newshape, order=‘C’)
其中arr传入原来的数组,newshape为新矩阵的形状,order为遍历顺序。范例:
a = np.arange(8)
print('原始数组:\n' ,a)
b = a.reshape(4, 2)
print('修改后的数组:\n' ,b)
# 结果:
# 原始数组:
# [0 1 2 3 4 5 6 7]
# 修改后的数组:
# [[0 1]
# [2 3]
# [4 5]
# [6 7]]
9.1.2 numpy.flat
该函数用于得到一个数组的迭代器,可用于遍历数组,范例:
a = np.arange(8).reshape(2,4)
print('原始数组:')
for row in a:
print(row)
print('迭代后的数组:')
for element in a.flat:
print(element ,end=",")
# 结果:
# 原始数组:
# [0 1 2 3]
# [4 5 6 7]
# 迭代后的数组:
# 0,1,2,3,4,5,6,7,
9.1.3 numpy.flatten
次函数返回一个深拷贝的数组,独立内存空间,对拷贝数组所做的修改不会影响原始数组,范例:
a = np.arange(8).reshape(2,4)
print('原始数组:\n' , a)
b = a.flatten()
print('展开的数组:\n', b)
# 改变拷贝数组
b[3] = 100
print('展开的数组:\n' ,b)
print('原始数组:\n', a)
# 结果:
# 原始数组:
# [[0 1 2 3]
# [4 5 6 7]]
# 展开的数组:
# [0 1 2 3 4 5 6 7]
# 展开的数组:
# [ 0 1 2 100 4 5 6 7]
# 原始数组:
# [[0 1 2 3]
# [4 5 6 7]]
9.1.3 numpy.ravel
返回的是数组视图,类似于浅拷贝,只是复制了数据,但内存地址未改变,改变拷贝数组会影响原数组,范例:
a = np.arange(8).reshape(2,4)
print('原始数组:\n' , a)
b = a.ravel()
print('展开的数组:\n', b)
# 改变拷贝数组
b[3] = 100
print('展开的数组:\n' ,b)
print('原始数组:\n', a)
# 结果:
# 原始数组:
# [[0 1 2 3]
# [4 5 6 7]]
# 展开的数组:
# [0 1 2 3 4 5 6 7]
# 展开的数组:
# [ 0 1 2 100 4 5 6 7]
# 原始数组:
# [[ 0 1 2 100]
# [ 4 5 6 7]]
9.2 翻转数组
numpy.transpose用于获得数组的转置,效果和a.T相似(也为浅拷贝),范例:
a = np.arange(6).reshape(2,3)
print('原始数组:\n' , a)
y = np.transpose(a)
print('翻转数组:\n' , y)
# 改变翻转数组
y[1] = 100
print('翻转数组:\n' , y)
print('原始数组:\n' , a)
# 结果:
# 原始数组:
# [[0 1 2]
# [3 4 5]]
# 翻转数组:
# [[0 3]
# [1 4]
# [2 5]]
# 翻转数组:
# [[ 0 3]
# [100 100]
# [ 2 5]]
# 原始数组:
# [[ 0 100 2]
# [ 3 100 5]]
9.3 修改数组维度
9.3.1 numpy.broadcast
numpy.broadcast 用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])
# 对 y 广播 x
b = np.broadcast(x,y)
# 它拥有 iterator 属性,基于自身组件的迭代器元组
print ('对 y 广播 x:')
r,c = b.iters
# Python3.x 为 next(context) ,Python2.x 为context.next()
print (next(r), next(c))
print (next(r), next(c))
print ('\n')
# shape 属性返回广播对象的形状
print ('广播对象的形状:')
print (b.shape)
print ('\n')
# 手动使用 broadcast 将 x 与 y 相加
b = np.broadcast(x,y)
c = np.empty(b.shape)
print ('手动使用 broadcast 将 x 与 y 相加:')
print (c.shape)
print ('\n')
c.flat = [u + v for (u,v) in b]
print ('调用 flat 函数:')
print (c)
print ('\n')
# 获得了和 NumPy 内建的广播支持相同的结果
print ('x 与 y 的和:')
print (x + y)
上面代码的结果为:
对 y 广播 x:
1 4
1 5
广播对象的形状:
(3, 3)
手动使用 broadcast 将 x 与 y 相加:
(3, 3)
调用 flat 函数:
[[5. 6. 7.]
[6. 7. 8.]
[7. 8. 9.]]
x 与 y 的和:
[[5 6 7]
[6 7 8]
[7 8 9]]
9.3.2 numpy.broadcast_to
numpy.broadcast_to 函数将数组广播到新形状。它在原始数组上返回只读视图
a = np.arange(4).reshape(1,4)
print ('原数组:')
print (a)
print ('\n')
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]]
9.3.3 numpy.expand_dims
numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状,函数格式如下:
numpy.expand_dims(arr, axis)
arr是输入数组,axis是新轴插入的位置
x = np.array(([1,2],[3,4]))
print ('数组 x:')
print (x)
print ('\n')
y = np.expand_dims(x, axis = 0)
#数组 x:
#[[1 2]
# [3 4]]
print ('数组 y:')
print (y)
print ('\n')
#数组 y:
# [[[1 2]
# [3 4]]]
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
print ('\n')
#数组 x 和 y 的形状:
# (2, 2) (1, 2, 2)
# 在位置 1 插入轴
y = np.expand_dims(x, axis = 1)
print ('在位置 1 插入轴之后的数组 y:')
print (y)
print ('\n')
#在位置 1 插入轴之后的数组 y:
#[[[1 2]]
# [[3 4]]]
print ('x.ndim 和 y.ndim:')
print (x.ndim,y.ndim)
print ('\n')
# x.ndim 和 y.ndim:
# 2 3
print ('x.shape 和 y.shape:')
print (x.shape, y.shape)
#x.shape 和 y.shape:
#(2, 2) (2, 1, 2)
9.3.4 numpy.squeeze
numpy.squeeze 函数从给定数组的形状中删除一维的条目,函数格式如下:
numpy.squeeze(arr, axis)
axis:整数或整数元组,用于选择形状中一维条目的子集
x = np.arange(9).reshape(1,3,3)
print ('数组 x:')
print (x)
print ('\n')
y = np.squeeze(x)
print ('数组 y:')
print (y)
print ('\n')
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
数组 x:
[[[0 1 2]
[3 4 5]
[6 7 8]]]
数组 y:
[[0 1 2]
[3 4 5]
[6 7 8]]
数组 x 和 y 的形状:
(1, 3, 3) (3, 3)
9.4 连接数组
函数 | 描述 |
---|---|
concatenate | 连接沿现有轴的数组序列 |
stack | 沿着新的轴加入一系列数组。 |
hstack | 水平堆叠序列中的数组(列方向) |
vstack | 竖直堆叠序列中的数组(行方向) |
9.4.1 numpy.concatenate
numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组,格式如下:
numpy.concatenate((a1, a2, …), axis)
a1, a2, …:相同类型的数组 |
---|
axis:沿着它连接数组的轴,默认为 0 |
a = np.array([[1,2],[3,4]])
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('\n')
# 两个数组的维度相同
print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b)))
print ('\n')
print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
沿轴 0 连接两个数组:
[[1 2]
[3 4]
[5 6]
[7 8]]
沿轴 1 连接两个数组:
[[1 2 5 6]
[3 4 7 8]]
9.4.2 numpy.stack
numpy.stack 函数用于沿新轴连接数组序列,格式如下:
numpy.stack(arrays, axis)
arrays相同形状的数组序列 |
---|
axis:返回数组中的轴,输入数组沿着它来堆叠 |
a = np.array([[1,2],[3,4]])
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('\n')
print ('沿轴 0 堆叠两个数组:')
print (np.stack((a,b),0))
print ('\n')
print ('沿轴 1 堆叠两个数组:')
print (np.stack((a,b),1))
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
沿轴 0 堆叠两个数组:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
沿轴 1 堆叠两个数组:
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]
9.4.3 numpy.hstack
numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组。
a = np.array([[1,2],[3,4]])
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('\n')
print ('水平堆叠:')
c = np.hstack((a,b))
print (c)
print ('\n')
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
水平堆叠:
[[1 2 5 6]
[3 4 7 8]]
9.4.4 numpy.vstack
numpy.vstack 是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。
a = np.array([[1,2],[3,4]])
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('\n')
print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
竖直堆叠:
[[1 2]
[3 4]
[5 6]
[7 8]]
9.5 分割数组
函数 | 数组及操作 |
---|---|
split | 将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
9.5.1 numpy.split
numpy.split 函数沿特定的轴将数组分割为子数组,格式如下:
numpy.split(ary, indices_or_sections, axis)
ary:被分割的数组
indices_or_sections:果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)
axis:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分
a = np.arange(9)
print ('第一个数组:')
print (a)
print ('\n')
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('\n')
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
第一个数组:
[0 1 2 3 4 5 6 7 8]
将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
将数组在一维数组中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
9.5.2 numpy.hsplit
numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。
harr = np.floor(10 * np.random.random((2, 6)))
print ('原array:')
print(harr)
print ('拆分后:')
print(np.hsplit(harr, 3))
原array:
[[4. 7. 6. 3. 2. 6.]
[6. 3. 6. 7. 9. 7.]]
拆分后:
[array([[4., 7.],
[6., 3.]]), array([[6., 3.],
[6., 7.]]), array([[2., 6.],
[9., 7.]])]
9.5.3 numpy.vsplit
numpy.vsplit 沿着垂直轴分割,其分割方式与hsplit用法相同。
a = np.arange(16).reshape(4,4)
print ('第一个数组:')
print (a)
print ('\n')
print ('竖直分割:')
b = np.vsplit(a,2)
print (b)
第一个数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
竖直分割:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
9.6 数组元素的添加与删除
相关函数:
1.numpy.resize 函数返回指定大小的新数组。
2.numpy.append 函数在数组的末尾添加值。
3.numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。
4.numpy.delete 函数返回从输入数组中删除指定子数组的新数组。
5.numpy.unique 函数用于去除数组中的重复元素。