Python学习笔记(4):Numpy 数据结构

在这里插入图片描述

文章导读

 - 课程难度:★★☆☆☆
 - 预计学习时间:1小时
 - 简介:本节主要讲解了Numpy数据结构相关的基本操作及使用功能等,包括:(1)创建数组;(2)数组的数据格式;(3)数组的运算;(4)三种数组的访问与修改方法;(5)数组的重塑、拼接与拆分;
 - 重点涉及的函数和内容:np.array()、astype()、tolist()、reshape()和resize()、ravel()和flatten()、np.concatenate()、np.vstack和np.hstack、np.r_和np.c_、np.split()

前言

Numpy库是Python中用于科学计算的核心库,它提供了一个强大的多维数组及相关运算等功能。接下来将分别从数组的创建、格式、运算、访问和修改等方面对数组进行系统地学习和了解。本节将分别从数组的创建、数据格式、运算、访问与修改、重塑与拼接等五个方面来对numpy的数组进行详细地介绍。

一、创建数组

导入numpy库:

import numpy as np

创建数组
我们可以利用np.array()函数把列表、元组或range对象直接转换为numpy数组;或者使用np.zeros()np.ones()np.full()等函数初始化一个一定形状的数组,后续根据需要再对其元素进行修改,该方法对于一维数组的初始化直接传入一个数值即可,而多维数组则可以传入元组以确定初始化数组的形状。具体示例如下:

np.array([1,2,3,4]) #把列表转换为数组
np.array((1,2,3,4)) #把元组转换为数组
np.array(range(4))  #把range对象转换为数组
np.array([[1,2,3,4],[5,6,7,8]]) #二维数组
np.zeros(3)      #全0的一维数组
np.zeros((3,4))  #3×4的全0二维数组
np.ones((1,3))   #1×3的全1二维数组
np.full((2,3),4) #常量数组,2×3的全4数组
np.empty((1,3))  #1×3的空数组,只申请空间,不初始化
np.eye(4)        #4×4的单位方阵
np.eye(2,3)      #2×3的单位矩阵
np.identity(4)   #4×4的单位矩阵,该方法只能创建行数与列数相等的单位方阵
np.arange(0,1,0.2)  #等差数组,0——1(不包括1),步长为0.2
np.linspace(0,10,5) #等差数组,0——10,5个元素

#构建相同形状的数组
a = np.array([[1,2,4],[3,4,5]])
b= np.ones_like(a)   #使b的形状与a相同,元素全为1
print(b)

输出结果如下:

array([1, 2, 3, 4])
array([1, 2, 3, 4])
array([0, 1, 2, 3])
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])
array([0., 0., 0.])
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
array([[1., 1., 1.]])
array([[4, 4, 4],
       [4, 4, 4]])
array([[0., 0., 0.]])
array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]])
array([[1., 0., 0.],
       [0., 1., 0.]])
array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]])
array([0. , 0.2, 0.4, 0.6, 0.8])
array([ 0. ,  2.5,  5. ,  7.5, 10. ])
[[1 1 1]
 [1 1 1]]

二、数组的数据格式

1、 数据类型介绍

int:整数
float:浮点数
complex:复数
bool:布尔类型,存储TRUE和FALSE值
object : Python对象
string:字符串

2、 查看数组

a = np.array([[1,2,3,4,5],[6,7,8,9,10],[13,5,6,8,2]])
print(a.dtype)  #数组中元素的数据类型
print(a.shape)  #数组尺寸
print(a.ndim)  #数组的维度
print(len(a))  #数组的长度
print(a.size)  #数组中的元素个数

输出结果如下:

int32
(3, 5)
2
3
15

转换数组内元素的类型:astype(),该方法不改变原数组

print(a.dtype)
a.astype('float')
print(a.astype('float').dtype) # 转换后的元素类型
print(a.dtype) #转换后原数组的元素类型

输出结果如下:

int32
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.],
       [13.,  5.,  6.,  8.,  2.]])
float64
int32

将数组转换为列表:tolist(),该方法不改变原数组

print(a.tolist())
print(a)

输出结果如下:

[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [13, 5, 6, 8, 2]]

[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [13  5  6  8  2]]

3、 补充及注意事项

1.一个numpy数组只能有一个数据格式,建立该对象的原数据若是有多个数据,它会自动将数据类型转换为能满足所有数据的最为精确的数据类型。

a = np.array([1, 2, 3.3])
print(a.dtype)
b = np.array([1, 2, 3.3, 'alpha'])
print(b.dtype)

输出结果如下:

float64
<U32

例如在这里,对于一个数组如果能归结为int型,就不用float,如果能归结为float型,就不用字符串。这个u32是unicode 32的意思。

  1. 在一个待建立的numpy数组里面,同一层级里面的数据必须全部是元素,或者全部是序列(列表、元组)
c = np.array([1, 2, 3, [4, 5]]) 		# 这是会报错的
d = np.array([(1, 2, 3), [4, 'beta']]) 	# 即便两种不同的序列也能建立,返回object。
print(d, d.dtype)

输出结果如下:

【错误】ValueError: setting an array element with a sequence.
[(1, 2, 3) list([4, 'beta'])] object
  1. 若是想要建立一个多维numpy数组,每一维度的元素必须等长,否则会建立一个由python object数据类型构成的numpy数组
e = np.array([[1, 2, 3], [4, 5, 6]]) # 二维数组的正确建立方式
print(e, e.dtype)
f = np.array([[1, 2, 3], [4, 5, ]]) # 如果元素不等长,建立的数据类型就是object
print(f, f.dtype)

输出结果如下:

[[1 2 3]
[4 5 6]] int32
[list([1, 2, 3]) list([4, 5])] object

三、数组的运算

先定义几个如下数组:

a = np.array([1, 2, 3, 4, 5, 6])
b = np.array([1, 2, 3, 4])
c = np.array([1, 2, 3])
d = np.array(['alpha', 'beta', 'gamma'])
  1. 一个数组做各种算术操作,是一个数组的所有元素进行一次计算(这里需要仔细注意的是,列表的+和numpy数组的+有明显的不同,列表中表示两个列表的拼接,而numpy数组则是两个等长的数组进行一对一的求和运算。其区别还在乘法中体现。)但是,字符串的数组并不支持类似于 +* 之类的操作
print(a + 1)		# 数组中每个值加1
print(a * 3)		# 数组中每个值乘3
print(a > 3) 		# 将3与数组中每个值做比较,返回布尔数组
print(1 / a) 		# 用1除以每个元素,即计算每个元素的倒数
print(2 - a)		# 将2与数组中每个值做差
print(2 ** a)		# 对数组中每个元素tmp,求2的tmp次方

输出结果如下:

[2 3 4 5 6 7]
[ 3  6  9 12 15 18]
[False False False  True  True  True]
[1.         0.5        0.33333333 0.25       0.2        0.16666667]
[ 1  0 -1 -2 -3 -4]
[ 2  4  8 16 32 64]

如果想要将numpy的字符串数组的每个元素与特定字符串做拼接,会报如下的错误:

d += '_Add' 		# 报错1:循环numpy数组运算时不允许字符串的拼接
  1. 数组运算也可以结合赋值运算符,做成+=%=等形式
 a = np.array([1, 2, 3, 4, 5, 6])
 a *= 2
 print(a)
 a = np.array([1, 2, 3, 4, 5, 6])
 a %= 2
 print(a)

输出结果如下:

[ 2  4  6  8 10 12]
[1 0 1 0 1 0]
  1. 一个numpy数组和其他numpy数组做算术运算时,是元素间一一对应计算
a = np.array([1, 2, 3, 4, 5, 6])
b = np.array([-1, 1, 3, 5, 7, 9])
c = np.array([1, 2, 3])
d = np.array(['alpha', 'beta', 'gamma'])
e = np.array(['one', 'two', 'three'])

这种计算发生在元素的一一对应之间,同时也可以进行比较运算。因为一维数组之间的运算多,我们重点提它。两个一维numpy数组的计算必须要求其具有相等的形状,且对应元素要能发生相互的计算

print(a + b) 		# 算数运算会返回一串一一对应计算的数值数组
print(a * b)
print(a >= b) 		# 比较运算会返回一串一一对应比较布尔值数组。
print(a == b)

输出结果如下:

[ 0  3  6  9 12 15]
[-1  2  9 20 35 54]
[ True  True  True False False False]
[False False  True False False False]

如下两种情况就会报错,报错的信息如下:

print(a + c) 		# 报错1,两个数组不等长,即便是a和c存在倍数关系
print(d + e) 		# 报错2,如前所述,numpy的字符串数组之间不能用+进行拼接
报错1【ValueError: operands could not be broadcast together with shapes (6,) (3,)】
报错2【TypeError: ufunc 'add' did not contain a loop with signature matching types dtype('<U5') dtype('<U5') dtype('<U5')
  1. 对于高维度数组,有一种广播机制,能让不同形状的数组乘到一起。这里举一个高维乘一维的例子:
a_2d = np.array([[1, 2, 3], [4, 5, 6]]) 	# 一个(2, 3)的数组
a_3d = np.array([[[3, 4, 5],[3, 4, 5]],
               [[5, 6, 7], [5, 6, 7]]]) 	# 一个(2, 2, 3)的数组
c = np.array([1, 2, 3]) 					# 一个(3, )的数组

print(a_2d * c)
print(a_3d * c)

输出结果如下:

[[ 1  4  9]
 [ 4 10 18]]
[[[ 3  8 15]
  [ 3  8 15]]

 [[ 5 12 21]
  [ 5 12 21]]]

从上面的运算结果可以总结,高维数组乘一维数组的运算方式是,高维数组中最后一维对应乘以一维数组的各元素,要求一维数组的长度等于高维数组的最后一维的长度,更复杂的它的广播机制在此略过,此知识点用的较少。

四、数组的访问与修改

对于数组的访问可以通过基于下标与切片、整数列表以及逻辑索引等三种方法。

1、基于下标与切片

数据的访问与切片和列表中的访问的十分相似。
一维数组的访问:与列表的访问方式相同

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(a[2]) 		# 访问元素
print(a[3:5]) 		# 访问一个切片,给出了起点和终点
print(a[2:]) 		# 访问一个切片,只给出了起点,起点被设置为数组的开始。
print(a[:]) 		# 访问一个没有起点和终点的切片,等同于访问原数组。

输出结果如下:

3
[4 5]
[ 3  4  5  6  7  8  9 10]
[ 1  2  3  4  5  6  7  8  9 10]

高维数组的访问:直观上来看,只用一个中括号[]访问所有维度的值,各个维度之间用逗号,分隔,而不是像列表先访问高维、再访问低维度一样,逐级地分步访问,尽管这种方式也是可行的。具体示例如下:

b = np.array(([1,2,3,4],
              [5,6,7,8],
              [9,10,11,12]))
print(b[0, 1]) 	# 访问某个特定元素,需要传递行值和列值,用逗号分隔。访问第1行第2列
print(b[0]) 	# 如果没有后续维度,返回结果就是我们的这个维度的切片。访问第一行
print(b[0:1, :]) # 想要访问某些行,就将列只写一个冒号,表示访问所有列。访问第1行
print(b[:, 1:4]) # 想要访问某些列,就将行只写一个冒号,表示访问所有行。访问第2列到第4列    

输出结果如下:

2
[1 2 3 4]
[[1 2 3 4]]
[[ 2  3  4]
 [ 6  7  8]
 [10 11 12]]

接下来,将介绍基于下标与切片的方式修改数组,对于单个元素或是一个切片,我们都可以直接进行修改。对于元素,我们通过下标将之访问后,赋予新值即可。对于一个切片,将之访问出来之后,可以只传一个值替换掉切片中的所有值也可以传一组等形状的值对应替换掉原值,具体示例如下:
一维数组的修改

a = np.array([1,2,3,4,5,6,7,8,9,10])
a[0] =0   #用一个值替换一个值
a[1:3] = [0] #用一个值替换切片
a[3:9] = [1,2,3,4,5,6] #用切片替换切片
print(a)

输出结果如下:

[ 0  0  0  1  2  3  4  5  6 10]

多维数组的修改:用值替换单个元素或切片,示例如下:

b = np.array(([1,2,3,4],
              [5,6,7,8],
              [9,10,11,12]))
b[:2,:3]=0 # 前2行、前3的元素用0替换
b[2,1] =-10 #第3行第二列的元素用-10替换
b

输出结果如下:

array([[  0,   0,   0,   4],
       [  0,   0,   0,   8],
       [  9, -10,  11,  12]])

同样地,也可以用切片替换切片,需要注意的是,传入数组的形状要与访问的一致,具体示例如下:

b = np.array(([1,2,3,4],
              [5,6,7,8],
              [9,10,11,12]))
b[:2,:3] = [[0,0,0],[1,1,1]] 
b              

输出结果如下:

array([[ 0,  0,  0,  4],
       [ 1,  1,  1,  8],
       [ 9, 10, 11, 12]])

2、基于整数列表

numpy数组支持通过传递一个列表来进行多个元素的访问。
一维数组

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(a[[0,2,3,7]]) 

输出结果如下:

[1 3 4 8]

多维数组
可以通过传入切片和列表来访问某些行、某些列的元素,具体示例如下:

b = np.array([[1,  2,  3,  4,  5,  6  ],
           [7,  8,  9,  10, 11, 12 ],
           [13, 14, 15, 16, 17, 18 ],
           [19, 20, 21, 22, 23, 24]])
           
print(b[[0, 2, 3]]) #访问行下标为0、2、3所在行的所有元素,即第1、3、4行。
                    #等价于 b[[0,2,3],:],不指定列下标表示所有列
print(b[:,[1,3,4]]) #访问第2、4、5列,不指定行下表表示所有行 
print(b[1:3,[0,2]]) #访问行下标为[1,3)、列下标为0、2的元素,即:第2、3行第1、3列的元素
print(b[[0,3],[1,2]]) #访问固定元素,b[0,1]、b[3,2]

输出结果如下:

[[ 1  2  3  4  5  6]
 [13 14 15 16 17 18]
 [19 20 21 22 23 24]]
 
[[ 2  4  5]
 [ 8 10 11]
 [14 16 17]
 [20 22 23]]
 
[[ 7  9]
 [13 15]]

[ 2 21]

3、基于逻辑索引

该方法的原理为:数组和标量或等长数组进行关系运算可以返回布尔型数组,以此可以作为下标访问其中的元素,返回True对应位置上元素组成的数组。具体示例如下:

(1)单一条件筛选

a = np.array([1, 2, 3, 4, 5, 6])
b = np.array([-1, 1, 3, 5, 7, 9])
print(a >= b)  #数组之间的比较会返回一串布尔型数值
print(a[ a >= b ]) #在数组a中筛选出所有对应元素里a比b大的值

输出结果如下:

[ True  True  True False False False]
[1 2 3]

(2)多条件筛选

利用布尔数组的时候,逻辑条件的拼接需要用逻辑运算符&|、和 ~,而不能用andornot,同时,每一个逻辑条件需要用括号括起来。具体案例如下:
下面是一串消费记录,关于每个人进行的历次消费的情境,name和purchase一一对应,为了想要找到所有Joe超过3元的消费记录,代码如下:

name = np.array(['Bob', 'Joe', 'Joe', 'Joe','Will', 'Will', 'Alex'])
purchase = np.array([3.3, 6.9, 2.1, 4.2, 5.5, 3.9, 3.0])
print(purchase[(name=='Joe')&(purchase>3)]) 

输出结果如下:

[6.9 4.2]

~ 实际上是位运算的取反符号,可以接整型数据和布尔型数据,选取不是Joe的所有消费金额代码如下:

print(purchase[~(name=='Joe')])

输出结果如下:

[3.3 5.5 3.9 3. ]

接着,既然可以基于布尔值访问元素,我们同样也能基于布尔值修改元素。

b = np.array([[1, 2, 3, 4, 5, 6],
              [7, 8, 9, 10, 11, 12],
              [13, 14, 15, 16, 17, 18]]) 
b[b > 10] = 10
print(b)

输出结果如下:

[[ 1  2  3  4  5  6]
 [ 7  8  9 10 10 10]
 [10 10 10 10 10 10]]

这是一个非常直观的基于条件对数组筛选的形式,因此在数据分析中常常使用。

五、数组的重塑、拼接与拆分

1、重塑

(1).reshape()函数:

该方法接收的是一个元组,对数组进行重塑之后,原值不会发生改变,返回值是重塑后的数据,首先来看一下该方法的实现过程,示例如下:

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

输出结果如下:

[ 0  1  2  3  4  5  6  7  8  9 10 11]
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

其次,可以给待重塑数组的某一维度传-1,此时系统将自动给定大小:

a_x3 = a.reshape(-1,3)
print(a_x3)

输出结果如下:

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]

另外,可以利用其他数组的shape属性,重塑数组,具体示例如下:

b = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]])
a_b = a.reshape(b.shape)
print(a_b)

输出结果如下:

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]

最后,需要注意的是,对.reshape()操作后的返回值进行修改,此时也修改原数组中对应的值,例如:

a = np.arange(12)
a_34 = a.reshape(3, 4)
a_34[1, 2] = -1
print(a)

输出结果如下:

[ 0  1  2  3  4  5 -1  7  8  9 10 11]

(2).resize()函数:

re.shape()相似,.resize()函数也接收一个元组。区别是resize()会直接改变原数组,而没有返回值:

a = np.arange(12)
a_26 = a.resize(2, 6)
print(a_26)
print(a)

输出结果如下:

None		# a_26作为resize()函数的返回值为None,表示函数无返回值
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]

(3).ravel()、.flatten()函数

使数组扁平化,一是可以使用reshaperesize函数,二是使用ravelflatten函数。
reshaperesize函数对数组实现扁平化的方法如下:

b = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]])
b_1d = b.reshape(12)
print(b_1d)

输出结果如下:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

使用ravel()、flatten()函数,两者都不会在原值上进行修改,但是两者是有区别的。区别就在于对.ravel()的返回值如果进行修改,修改会反映到原值上,就像.reshape()一样。而对.flatten()的返回值进行修改则不会。

b = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]])
b_1d = b.ravel()
print(b_1d)
print(b)
b_1d[3] = -1
print(b)

输出结果如下:

[ 1  2  3  4  5  6  7  8  9 10 11 12]
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]

2、拼接

列表的拼接用的是 +.extend()。但数组的拼接是把数组直接横向或纵向接在另一个数组上。数组的拼接主要使用np.concatenate()函数,还有np.vstacknp.hstack(),以及np.r_[]np.c[]等三组函数。

(1)np.concatenate()函数

该方法待拼接的数据要写成列表的形式,同时还需要补充拼接的轴向axis,axis = 0代表横向,axis = 1代表纵向:

a = np.arange(24).reshape(4, 6)
b = np.ones(18).reshape(3, 6)
c = np.zeros(16).reshape(4, 4)

a_b = np.concatenate([a, b], axis = 0) #将a、b进行横线拼接
a_c = np.concatenate([a, c], axis = 1) #将a、c进行纵向拼接
print(a_b, '\n')
print(a_c, '\n')

输出结果如下:

[[ 0.  1.  2.  3.  4.  5.]
 [ 6.  7.  8.  9. 10. 11.]
 [12. 13. 14. 15. 16. 17.]
 [18. 19. 20. 21. 22. 23.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]] 

[[ 0.  1.  2.  3.  4.  5.  0.  0.  0.  0.]
 [ 6.  7.  8.  9. 10. 11.  0.  0.  0.  0.]
 [12. 13. 14. 15. 16. 17.  0.  0.  0.  0.]
 [18. 19. 20. 21. 22. 23.  0.  0.  0.  0.]] 

拼接是有顺序的,若是将[a, b]的拼接改成了[b, a],,b的数据就会在前面(上面)。类似的,c的数据就会在左边。另外,数据拼接之后,对新数据进行修改不会影响到原数据

a_c[0]=100
print(a_c,'\n\n',a,'\n\n',c)

输出结果如下:

[[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
 [  6.   7.   8.   9.  10.  11.   0.   0.   0.   0.]
 [ 12.  13.  14.  15.  16.  17.   0.   0.   0.   0.]
 [ 18.  19.  20.  21.  22.  23.   0.   0.   0.   0.]] 

 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]] 

 [[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]

(2)np.vstack()、np.hstack()函数

这组函数可以看成是np.concatenate()的简版,两个函数分别对数组进行横向(轴0)、纵向(轴1)拼接:

a = np.arange(24).reshape(4, 6)
b = np.ones(18).reshape(3, 6)
print(np.vstack([a, b]), '\n')
print(np.hstack([a, c]), '\n')

输出结果如下:

[[ 0.  1.  2.  3.  4.  5.]
 [ 6.  7.  8.  9. 10. 11.]
 [12. 13. 14. 15. 16. 17.]
 [18. 19. 20. 21. 22. 23.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]] 

[[ 0.  1.  2.  3.  4.  5.  0.  0.  0.  0.]
 [ 6.  7.  8.  9. 10. 11.  0.  0.  0.  0.]
 [12. 13. 14. 15. 16. 17.  0.  0.  0.  0.]
 [18. 19. 20. 21. 22. 23.  0.  0.  0.  0.]] 

(3)np.r_[]、np.c_[]

np.r_[]np.c_[],这组方法效果分别等同于np.vstack()np.hstack(),只是,这两个方法是直接通过中括号[]接收numpy数组并进行拼接,并不作为函数接收一个待拼接的数组列表
我们展示其应用效果如下:

a = np.arange(24).reshape(4, 6)
b = np.ones(18).reshape(3, 6)
print(np.r_[a, b], '\n')
print(np.c_[a, c], '\n')

输出结果如下:

[[  0.   1.   2.   3.   4.   5.]
 [  6.   7.   8.   9.  10.  11.]
 [ 12.  13.  14.  15.  16.  17.]
 [ 18.  19.  20.  21.  22.  23.]
 [  1.   1.   1.   1.   1.   1.]
 [  1.   1.   1.   1.   1.   1.]
 [  1.   1.   1.   1.   1.   1.]] 

[[  0.   1.   2.   3.   4.   5.   0.   0.   0.   0.]
 [  6.   7.   8.   9.  10.  11.   0.   0.   0.   0.]
 [ 12.  13.  14.  15.  16.  17.   0.   0.   0.   0.]
 [ 18.  19.  20.  21.  22.  23.   0.   0.   0.   0.]]

据此,对二维数组中np.vstack()np.r_[]功能相同,np.hstack()np.c_[]功能相同,横纵向拼接的功能都能用np.concatenate()实现。但对一维数组的拼接中,三组功能有一些不同,我们用一个例子集中展现:

a_1d = np.array([1, 2, 3])
b_1d = np.array([4, 5, 6])
print(np.concatenate([a_1d, b_1d], axis = 0), '\n')
print(np.hstack([a_1d, b_1d]))
print(np.vstack([a_1d, b_1d]) , '\n')
print(np.r_[a_1d, b_1d])
print(np.c_[a_1d, b_1d])

三组数据拼接方法的输出结果如下:

[1 2 3 4 5 6] 
[1 2 3 4 5 6] 
[[1 2 3]
 [4 5 6]]
[1 2 3 4 5 6]
[[1 4]
 [2 5]
 [3 6]]

从此我们可以看见对于一维数组,np.concatenate()(一维数组的axis仅有0)、np.hstack()np.r_[]都是进行数组的横向扩展,而np.vstack()将两个数组看成两行、做了横向堆叠,np.c_[]将两个数组看成两列、做了纵向堆叠,二者互为转置。这数种拼接方法的一些区别需要理顺。

3、拆分

np.concatenate()函数相对应的是np.split(),将数组沿某个轴进行拆分,拆分是以均等的方式拆分,份数必须被轴的长度整除,具体参考如下代码示例:

(1)np.split()函数

a = np.arange(24).reshape(4, 6)
print(np.split(a, 4, axis = 0), '\n') 	# 将a沿横向(轴0)拆成4份
print(np.split(a, 3, axis = 1), '\n') 	# 将a沿横向(轴1)拆成3份

输出结果如下:

[array([[0, 1, 2, 3, 4, 5]]), array([[ 6,  7,  8,  9, 10, 11]]), array([[12, 13, 14, 15, 16, 17]]), array([[18, 19, 20, 21, 22, 23]])] 

[array([[ 0,  1],
       [ 6,  7],
       [12, 13],
       [18, 19]]), array([[ 2,  3],
       [ 8,  9],
       [14, 15],
       [20, 21]]), array([[ 4,  5],
       [10, 11],
       [16, 17],
       [22, 23]])] 

(2)np.vsplit()、np.hsplit()函数

相似的也有np.vsplit()np.hsplit()函数,作为np.split()的简版,两个函数分别对数组进行横向(轴0)、纵向(轴1)的拆分:

print(np.vsplit(a, 2),'\n') # 将a沿横向拆成2份
print(np.hsplit(a, 2)) # 将a沿纵向拆成3份

输出结果如下:

[array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]]), array([[12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])] 

[array([[ 0,  1,  2],
       [ 6,  7,  8],
       [12, 13, 14],
       [18, 19, 20]]), array([[ 3,  4,  5],
       [ 9, 10, 11],
       [15, 16, 17],
       [21, 22, 23]])]

以上就是numpy数组的主要内容。


对于缺乏Python基础的同仁,可以通过免费专栏🔥《Python学习笔记(基础)》从零开始学习Python

结语

请始终相信“Done is better than perfect” ,不要过分追求完美,即刻行动就是最好的开始, 一个模块一个模块地积累和练习,必将有所收获。
还有其他的问题欢迎在评论区留言📝!


[版权申明] 非商业目的注明出处可自由转载,转载请标明出处!!!
博客:butterfly_701c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值