Numpy详解
相关教程
【Python】Numpy详解
【Python】Pandas详解
【Python】Matplotlib详解
一、Numpy介绍
数据分析三剑客之一的Numpy,是一个用于处理数组的 Python 包【基于数组对象的科学计算库】。 其全名为 “Numeric Python”,是一款开源的Python库。Numpy相当于Python中的列表(List),但只能存放相同的数据类型。
引入Numpy的目的是可以计算大型的多维数组和矩阵操作,其计算能力强,运行的速度快。列表(List)需要先寻找元素的地址,再访问到元素;而Numpy的数组被存储在内存中的一个连续的位置【物理地址连续性】,可以非常有效地访问和操作它们。
【功能侧重】:numpy
主要专注于数值计算和数组操作,提供了高效的底层计算功能,是许多科学计算和数据分析库的基础。
【应用场景】:numpy
在数据分析,科学计算、机器学习算法的底层实现、图像处理等领域应用广泛,例如在深度学习中,用于处理神经网络中的数据张量。
二、安装Numpy
在终端处输入以下命令
pip install numpy
三、Ndarray对象
Numpy的数组对象称为 Ndarray,它是一系列同类型数据的集合。
3.1:创建Ndarray对象
我们可以通过array()函数来创建一个Numpy ndarray对象
完整定义格式:numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数序号 | 参数及描述 |
---|---|
1 | object 任何暴露数组接口方法的对象都会返回一个数组或任何(嵌套)序列。✔ |
2 | dtype 数组的所需数据类型,可选。✔ |
3 | copy 可选,默认为true ,对象是否被复制。 |
4 | order C (按行)、F (按列)或A (任意,默认)。 |
5 | subok 默认情况下,返回的数组被强制为基类数组。 如果为true ,则返回子类。 |
6 | ndmin 指定返回数组的最小维数 或 自定义维度。✔ |
小型案例:
import numpy as np
arr=np.array([1,2,3,4])
print(arr)
------------------------
[1 2 3 4]
------------------------
3.2:Ndarray的维度
零维数组
import numpy as np arr=np.array(71) print(arr) ------------------- 71 -------------------
一维数组
import numpy as np arr=np.array([1,2,3,4]) print(arr) --------------------- [1 2 3 4] ---------------------
二维数组
二维数组通常也称之为矩阵或二阶张量【行的元素数量要一致】
import numpy as np arr=np.array([[1,2,3],[4,5,4]]) print(arr) --------------------- [[1 2 3] [4 5 4]] ---------------------
三维数组
import numpy as np arr=np.array([[[1,2,3],[3,4,2],[4,3,1],[5,3,6]]]) print(arr) --------------------- [[[1 2 3] [3 4 2] [4 3 1] [5 3 6]]] ---------------------
生成0和1数组
np.ones(shape(, dtype)),生成全0的数组
np.zeros(shape(, dtype)),生成全1的数组
np.ones_like(a(, dtype)),生成像a那样维度的全0数组
np.zeros_like(a(, dtype)),生成像a那样维度的全1数组
import numpy as np # 生成3行2列的全1数组 arr1=np.ones([3,2],dtype=np.int32) print("np.ones生成数组:\n",arr1) # 生成和[4,2]同一维度的全1数组,即:生成二维全1数组 arr2=np.ones_like([4,2],dtype=np.int32) print("np.ones_like生成数组:",arr2) ------------------------------- np.ones生成数组: [[1 1] [1 1] [1 1]] np.ones_like生成数组: [1 1] -------------------------------
3.3:Ndarray常见操作
1)Numpy的基本属性
属性名称 | 属性解释 |
---|---|
ndarray.ndim | 检查数组维数,即是几维的数组 |
ndarry.shape | 数组维度(形状),即几行几列 |
ndarray.size | 数组中总的元素个数 |
ndarray.dtype | 数组的数据类型 |
import numpy as np
# 二维数组
data = np.array([[1,2,3],[4,5,6]])
print(data.ndim) # 数组维度——2维
print(data.shape) # 数组形状——2行3列
print(data.size) # 数组元素个数——共6个
print(data.dtype) # 数组的数据类型——int64
-----------------------
2
(2, 3)
6
int64
-----------------------
2)Numpy的形状
定义:数组的形状是每个维中元素的数量。
操作一:获取数组的形状
通过
shape()函数
来查看数组的形状;通过参数ndmin
可以初始化数组的维度。import numpy as np # 原本有两个维度,现在通过ndmin参数增加至三个维度 arr=np.array([[1,2,3],[4,5,6],[7,8,9]],ndmin=3) print(arr.shape) -------------------- # 含有三个维度,第一个维度有1个元素 => [[1,2,3],[4,5,6],[7,8,9]] # 第二个维度有三个元素 => [1,2,3],[4,5,6],[7,8,9] # 第三个维度有三个元素 => 1,2,3 or 4,5,6 or 7,8,9 (1, 3, 3) --------------------
操作二:数组的重塑
通过
reshape()函数
进行数组的重塑。只要重塑的元素在两种形状中均相同。比如,可以将8元素的1D数组重塑为两行2D数组中的4个元素,但不可重塑为3元素3行2D数组。
从1维度重塑至2维度(升维)
import numpy as np # 一维数组 arr=np.array([1,2,3,4,5,6,7,8,9]) arr2=arr.reshape(3,3)# 重塑为二维 print(arr2) ------------------- [[1 2 3] [4 5 6] [7 8 9]] -------------------
从2维度重塑至1维度(降维)
可以将多维数组降为 1D 数组,可以使用
reshape(-1)
来完成这一点。import numpy as np arr=np.array([[1,2,3,4],[5,6,7,8]]) arr2=arr.reshape(-1) print(arr2) ------------------- [1 2 3 4 5 6 7 8] -------------------
3.4:Ndarray的访问
采用下标(索引)的方式进行访问元素。其中Numpy数组的索引是以0开头,意味着第一个元素的索引为0,第二个元素的索引为1,以此类推。【此处以二维数组为例】
import numpy as np
arr=np.array([[1,2,3],[41,5,4]])
print("第二维度中的第一个元素",arr[1,0]) #正索引:从头开始访问数组
print("倒数一个维度中的倒数第二个元素",arr[-1,-2]) # 负索引:从尾开始访问数组
-----------------------------
第二维度中的第一个元素 41
倒数一个维度中的倒数第二个元素 5
-----------------------------
3.5:Ndarray切片(裁剪)
两种基本格式:[start : end] 和 [start : end : step]。【其中end是不包含在内的】
注意:若不传start,默认从0开始;若不传end,默认到数组的末尾;若不传step,默认步长为1
import numpy as np
# 一维数组
arr=np.array([1,2,3,4])
# 二维数组
arr2=np.array([[1,2,3,4,5],[6,7,8,9,10]])
print("一维数组切片:")
print(arr[:2]) # 从索引0到索引(2-1)【不包含索引2】
print(arr[1:]) # 从索引1到末尾
print(arr[1:4:2]) # 从索引1开始到索引(4-1),步长为2 【不包含索引4】
print(arr[-3:-1]) # 从末尾开始的索引3到末尾开始的索引(-1-1)【不包含索引-1】
print("二维数组切片:")
print(arr2[1,1:4]) # 从第二个元素开始,取从索引1到索引4(不包含)的元素
print(arr2[0:2,2]) # 返回两个元素中的第2个元素
print(arr2[0:2,1:4]) # 两个元素,取各自的从索引1到索引4(不包含)的元素,构成2-D数组
------------------------
一维数组切片:
[1 2]
[2 3 4]
[2 4]
[2 3]
二维数组切片:
[7 8 9]
[3 8]
[[2 3 4]
[7 8 9]]
------------------------
3.6:副本 vs 视图
1)副本与视图的区别
Numpy中副本与视图的主要区别:副本是一个新的数组,视图是原始数组的视图。
- 副本是拥有数据:对副本所做的任何操作不会改变原始数组;同样对原始数组的任何改变不会影响副本
- 视图不拥有数据:对视图所做的任何操作会影响原始数组;对原始数组的任何改变同样会影响视图
2)副本
通过copy()
来创建副本【通过base来判断是否含有数据,若含有数据则返回None】
import numpy as np
arr=np.array([1,2,3]) # 原始数组
x=arr.copy() # 创建副本
# 对原始数组进行改变
arr[0]=17
print(arr) # 输出原始数组(已改变)
print(x) # 输出副本
print(x.base) # 判断是否含有数据
----------------------
[17 2 3]
[1 2 3]
None # 结果显示为None,表明含有数据
----------------------
3)视图
通过view()
来创建副本【通过base来判断是否含有数据,若含有数据则返回None】
import numpy as np
arr=np.array([1,2,3]) # 原始数组
x=arr.view() # 视图
# 对原始数组进行改变
arr[0]=17
print(arr) # 输出原始数组(已改变)
print(x) # 输出副本
print(x.base) # 判断是否含有数据
------------------------
[17 2 3]
[17 2 3]
[17 2 3] # 结果显示不为None,表明不含有数据
------------------------
四、Numpy数据类型
类型 | 描述 |
---|---|
np.bool | 布尔类型(True或是FALSE) |
np.int32 | 整数类型,32位 |
np.int64 | 整数类型,64位【默认】 |
np.uint32 | 无符号整数,32位【默认】 |
np.uint64 | 无符号整数,64位 |
np.float32 | 浮点数类型,32位 |
np.float64 | 浮点数类型,64位【默认】 |
S | 字符串 |
U | Unicode字符串 |
complex64 | 复数,分别用于两个32位浮点数表示实部和虚部 |
complex128 | 复数,分别用两个64位浮点数表示实部和虚部【默认】 |
import numpy as np
arr1=np.array([0,2,3],dtype=np.bool)
arr2=np.array([-1,2,3],dtype=np.int32)
arr3=np.array([1,2,3],dtype=np.uint32)
arr4=np.array([-1.67,2.56,3.14],dtype=np.float32)
arr5=np.array([1,2,3],dtype="S")
arr6=np.array([1,2,3],dtype="U")
arr7=np.array([-1,2,3],dtype=np.complex128)
print(arr1)
print(arr2)
print(arr3)
print(arr4)
print(arr5)
print(arr6)
print(arr7)
-----------------------------
[False True True]
[-1 2 3]
[1 2 3]
[-1.67 2.56 3.14]
[b'1' b'2' b'3']
['1' '2' '3']
[-1.+0.j 2.+0.j 3.+0.j]
-----------------------------
4.1:数据类型的查看
通过ndarray.dtype
进行数据类型的查看
import numpy as np
arr1=np.array([0,2,3])
print(arr1.dtype)
--------------------
int64
--------------------
4.2:数据类型的转换
通过astype()
进行数据类型的转换
import numpy as np
arr1=np.array([0,2,3])
arr2=arr1.astype(np.bool)
print(arr2)
----------------------
[False True True]
----------------------
五、Numpy 操作
5.1:遍历操作
方式一:通过for循环进行遍历
import numpy as np
arr1=np.array([1,2,3])
arr2=np.array([[1,2],[5,6]])
# 遍历一维数组
for i in arr1:
print(i)
print("===============")
# 遍历二维数组
for x in arr2:
for y in x:
print(y)
------------------------
1
2
3
===============
1
2
5
6
------------------------
方式二:nditer()函数
用法一:迭代每个元素
import numpy as np # 二维数组 arr=np.array([[1,2],[5,6]]) # nditer进行遍历 for i in np.nditer(arr): print(i) ----------------- 1 2 5 6 -----------------
用法二:以不同步长进行迭代
import numpy as np # 二维数组 arr=np.array([[1,2,3],[5,6,7]]) # 在2D数组中,遍历每个维度中的元素,步长为2 for i in np.nditer(arr[:,::2]): print(i) ------------------- 1 3 5 7 -------------------
方式三:ndenumerate()函数
ndenumerate()函数可以指出事务的序号,适用于在迭代时需要元素的相关索引
import numpy as np
arr1=np.array([1,2,3,4]) # 一维函数
arr2=np.array([[1,2],[5,6]]) # 二维数组
# 遍历一维数组:序号 + 元素
for index,x in np.ndenumerate(arr1):
print(index,x)
# 遍历二维数组:序号 + 元素
for index, x in np.ndenumerate(arr2):
print(index, x)
---------------------
(0,) 1
(1,) 2
(2,) 3
(3,) 4
(0, 0) 1
(0, 1) 2
(1, 0) 5
(1, 1) 6
---------------------
5.2:连接操作
concatenate()函数
含义:连接操作指的是将【两个或多个数组】的内容放在【单个数组】中。
基本格式:numpy.concatenate((a1, a2, ...), axis)
。
在Numpy中,**相同类型的数组序列(a1,a2,…)通过按轴(axis)**进行连接【默认轴(axis)为0】
import numpy as np
# 两个数组的维度相同
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print("第一个数组:")
print(a)
print("第二个数组:")
print(b)
print("沿轴0(纵轴【列】)连接两个数组:")
a1=np.concatenate((a, b)) # 默认 axis=0
print(a1)
print("沿轴1(横轴【行】)连接两个数组:")
b1=np.concatenate((a, b), axis=1)
print(b1)
---------------------------
第一个数组:
[[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]]
---------------------------
5.3:堆叠操作
Numpy 的堆叠操作可将多个数组按不同方式组合。主要有垂直堆叠vstack
、水平堆叠hstack
和深度堆叠dstack
。它们分别在垂直方向、水平方向和深度方向上增加维度来堆叠数组,方便数据的合并与处理,提高数据处理效率。
方式一:stack()函数【堆叠】
基本格式:numpy.stack(arrays, axis)
arrays:相同形状的数组序列
axis:返回数组中的轴,输入数组沿着它来堆叠,默认为0
import numpy as np
arr1=np.array([[1,2],[3,4]])
arr2=np.array([[5,6],[7,8]])
print("第一个数组:\n",arr1)
print("第二个数组:\n",arr2)
arr11=np.stack((arr1,arr2),axis=0)
arr22=np.stack((arr1,arr2),axis=1)
print("沿轴 0 (纵轴【列】)堆叠两个数组:\n",arr11)
print("沿轴 1 (横轴【行】)堆叠两个数组:\n",arr22)
------------------------------------
第一个数组:
[[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]]]
------------------------------------
方式二:hstack()函数【水平堆叠】
numpy.stack
函数的变体,通过堆叠来生成水平的单个数组。
import numpy as np
arr1=np.array([[1,2],[3,4]])
arr2=np.array([[5,6],[7,8]])
print("第一个数组:\n",arr1)
print("第二个数组:\n",arr2)
arr=np.hstack((arr1,arr2))
print("水平堆叠:\n",arr)
-------------------------------
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
水平堆叠:
[[1 2 5 6]
[3 4 7 8]]
-------------------------------
方式三:vstack()函数【垂直堆叠】
numpy.stack
函数的变体,通过堆叠来生成竖直的单个数组。
import numpy as np
arr1=np.array([[1,2],[3,4]])
arr2=np.array([[5,6],[7,8]])
print("第一个数组:\n",arr1)
print("第二个数组:\n",arr2)
arr=np.vstack((arr1,arr2))
print("垂直堆叠:\n",arr)
---------------------------------
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
垂直堆叠:
[[1 2]
[3 4]
[5 6]
[7 8]]
---------------------------------
方式四:dstack()函数【深度堆叠】
import numpy as np
arr1=np.array([[1,2],[3,4]])
arr2=np.array([[5,6],[7,8]])
print("第一个数组:\n",arr1)
print("第二个数组:\n",arr2)
arr=np.dstack((arr1,arr2))
print("深度堆叠:\n",arr)
-------------------------------
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
深度堆叠:
[[[1 5]
[2 6]]
[[3 7]
[4 8]]]
-------------------------------
5.4:拆分操作
拆分是与连接的反向操作。我们通过split()函数或array_split()函数来实现分割的操作。
区分:
split()
函数要求分割数量必须能整除数组的相应维度大小,否则会报错。array_split()
函数则可以接受不能整除的情况,它会尽量平均地分割数组,使得每个子数组的元素数量尽可能接近。
array_split()
函数场景:
import numpy as np
arr=np.array([1,2,3,4,5,6,7])
newarr=np.array_split(arr,2) # 将arr分为两个子数组
print(newarr)
print("第一个子数组:",newarr[0])
print("第二个子数组:",newarr[1])
-------------------------------------------
[array([1, 2, 3, 4]), array([5, 6, 7])]
第一个子数组: [1 2 3 4]
第二个子数组: [5 6 7]
-------------------------------------------
split()
函数场景:
import numpy as np
arr=np.array([1,2,3,4,5,6,7])
newarr=np.split(arr,2)
print(newarr)
--------------------------------------------------------------------
ERROR:ValueError: array split does not result in an equal division
--------------------------------------------------------------------
5.5:搜索操作
1)直接搜索【where()函数】
可以通过where()函数,在数组中从左开始搜索某个值,返回匹配的索引
【补充】:
np.where(condition, x, y)
的作用是:
- 如果
condition
为真,返回x
;- 如果
condition
为假,返回y
。
import numpy as np
arr=np.array([1,2,3,4,5,6,7])
# 查找值为偶数的索引
x=np.where(arr%2==1)
print(x)
--------------------------
(array([0, 2, 4, 6]),)
--------------------------
2)搜索排序【searchsorted()函数】
可以通过searchsorted()
函数,用于在一个已排序的一维数组中查找指定值的插入位置(下标【从0开始】),以确保插入后数组仍然有序。
- 可以选择插入点的侧边:
side='left'
或side='right'
。- 它适用于单个值或多个值的查找,并返回插入位置的索引。
当side=“left”时:
import numpy as np
arr=np.array([1,3,3,6,21,37,97])
x=np.searchsorted(arr,3,side="left")
print(x)
-------------
1 # 下标为1的位置
-------------
当side=“right”时:
import numpy as np
arr=np.array([1,3,3,6,21,37,97])
x=np.searchsorted(arr,3,side="right")
print(x)
-------------
3 # 下标为3的位置
-------------
当处理多个值时:
values
数组中的每个元素都得到了它在 arr
中应该插入的位置。
import numpy as np
arr = np.array([1, 3, 5, 7, 9])
values = np.array([2, 4, 6])
# 查找多个值的插入位置
indices = np.searchsorted(arr, values)
print(indices)
-------------------
[1 2 3]
-------------------
5.6:排序操作
通过sort()函数来实现排序操作,默认是升序。
import numpy as np
arr = np.array([7, -3, 17, 71, 1])
# 排序(升序)
sorted_arr=np.sort(arr)
print(sorted_arr)
---------------------
[-3 1 7 17 71]
---------------------
倒序:先使用
sort
函数对数组进行升序排序,然后使用切片操作[::-1]
将数组反转,从而实现倒序排列。import numpy as np arr = np.array([7, -3, 17, 71, 1]) sorted_arr=np.sort(arr) # 排序(升序) arr1=sorted_arr[::-1] # 数组反转 print(arr1) ---------------------- [71 17 7 1 -3] ----------------------
5.7:去重操作
通过unique()函数实现去重,其返回一个由目标数组中唯一值排序后形成的一维数组。
import numpy as np
arr = np.array([[7,-3,-1,5], [5,71,17,17]])
u_arr=np.unique(arr)
print(u_arr)
-----------------------
[-3 -1 5 7 17 71]
-----------------------
5.8:过滤操作
在Numpy中,我们一般通过布尔索引列表来过滤数组。若索引处的值为True,则该元素包含在过滤后的数组中;若索引处的值为False,则该元素将从过滤后的数组中排除。
import numpy as np
arr1=np.array([7,-3,-1,55,71,17,17])
arr2=np.array([False,True,False,True,True,False,True])
newarr=arr1[arr2] # 进行布尔索引操作【过滤】
print(newarr)
--------------------------
[-3 55 71 17]
--------------------------
【过滤器的搭建】
import numpy as np
arr1=np.array([7,-3,-1,55,71,17,17])
# 直接从数组创建过滤器
arr2=arr1>0 # 筛选出大于0的数
newarr=arr1[arr2] # 过滤
print(newarr)
----------------------
[ 7 55 71 17 17]
----------------------
---------------
> ```
### 5.7:去重操作
通过**unique()函数**实现去重,其返回一个由**目标数组中唯一值排序后**形成的**一维数组**。
```python
import numpy as np
arr = np.array([[7,-3,-1,5], [5,71,17,17]])
u_arr=np.unique(arr)
print(u_arr)
-----------------------
[-3 -1 5 7 17 71]
-----------------------