• Python学习笔记(十六)——Numpy


    Numpy

    NumPy Numerical Python 的简称)是高性能科学计算和数据分析的基础包,
    其中包含了数组对象 ( 向量、矩阵、图像等 ) 以及线性代数等。

    NumPy库主要功能

    ndarray( 数组 ) 是具有矢量算术运算和复杂广播能力的多维数组。
    具有用于对数组数据进行快速运算的标准数学函数。
    具有用于读写磁盘数据、操作内存映射文件的工具。
    具有线性代数、随机数生成以及傅里叶变换功能。
    具有用于集成由 C C++ Fortran 等语言编写的代码的工具。

    NumPy库的安装

    CMD
    # 打开命令窗口
    pip install numpy # cmd 中输入
     

    NumPy库的调用

    import numpy as np #约定俗成

    数据维度的理解

    二维数据

    二维数据由多个一维数据构成,是一维数据的组合形式。
    表格是典型的二维数据。

    多维数据

    多维数据由一维或二维数据在新维度上扩展形成。 (比如在二维数据基础上加上时间轴)

    一维数据:列表和集合类型 一维数据:列表和集合类型

    [3.13, 4.13, 2,34] 有序
    {3.13, 4.13, 2,34} 无序
    二维数据:列表类型
    多维数据:列表类型
    高维数据:字典类型或数据表示格式

    举例:

    计算 A 2 +B 3 ,其中, A B 是一维数组。
    a=[0,1,2,3,4]
    b=[5,6,7,8,9]
    c=[]
    for i in range(0,5):
    c.append(a[i]**2+b[i]**3)
    import numpy as np
    a_array=np.array(a)
    b_array=np.array(b)
    c=a_array**2+b_array**3
    数组优势
    数组对象可以去掉元素间运算所需的循环,使一维向量更像单个数据
    设置专门的数组对象,经过优化,可以提升这类应用的运算速度
    观察:科学计算中,一个维度所有数据的类型往往相同
    数组对象采用相同的数据类型,有助于节省运算和存储空间

     数组

    NumPy 库处理的最基础数据类型是由同种元
    素构成的多维数组 (ndarry) , 简称“数组”。
    numpy 数组的维数称为秩,每一个线性的数组称为轴。
    同一个 numpy 数组中所有元素的类型一般是相同的。

    例子

    ndarray 在程序中的别名是: array.
    np.array() 输出成 [] 形式,元素由空格分割 .
    1. >>> import numpy as np
    2. >>> a=[[1,2],[3,4]]
    3. >>> a_array=np.array(a)
    4. >>> a_array
    5. array([[1, 2],
    6. [3, 4]])
    7. >>> type(a_array)
    8. numpy.ndarray

    数组创建

    Python 中的列表 、元组等类型创建 ndarray 数组
    使用 NumPy 中函数创建 ndarray 数组 ,如: arange ,ones, zeros 等。
    从字节流 ( raw bytes )中创建 ndarray 数组。
    从文件中读取特定格式 ,创建 ndarray 数组。

    内置数据结构创建数组

    基本格式: NumPy 将根据数据情况关联一个 dtype 类型
    np.array(list/tuple, dtype=np.float32)

     例子

    1. >>> np.array([[1,2],[3,4]])
    2. >>> np.array(((1,2),(3,4)))
    3. array([[1, 2],
    4. [3, 4]])

    有整数有浮点数则转浮点 

    1. >>> np.array([[1,1.1],(2,2.1)])
    2. array([[1. , 1.1],
    3. [2. , 2.1]])

    数组元素的类型

    dtype( 数据类型 ) 是一个特殊对象,它含有 ndarry 将一块内存解释为特定数 据类型所需要的信息。

     

     

    数组元素的类型:原因解释

    ndarray 为什么要支持这么多种元素类型?
            Python语法仅支持整数、浮点数和复数 3 种类型
    Ndarry 的优势
    科学计算涉及数据较多,对存储和性能都有较高要求
    对元素类型精细定义,有助于 NumPy 合理使用存储空间并优化性能
    对元素类型精细定义,有助于程序员对程序规模有合理评估
    常用创建数组的函数
    使用 Numpy 中函数创建 ndarry 数组,如 arrange ones zeros

    实例

    1. >>> np.arange(10)
    2. array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    3. >>> np.ones((3,6))
    4. array([[1., 1., 1., 1., 1., 1.],
    5. [1., 1., 1., 1., 1., 1.],
    6. [1., 1., 1., 1., 1., 1.]])
    7. >>> np.ones((2,4),dtype=np.int32) :
    8. array([[1, 1, 1, 1],
    9. [1, 1, 1, 1]])
    10. >>> np.eye(4)
    11. array([[1., 0., 0., 0.],
    12. [0., 1., 0., 0.],
    13. [0., 0., 1., 0.],
    14. [0., 0., 0., 1.]])
    15. >>> np.full((2,4),4)
    16. array([[4, 4, 4, 4],
    17. [4, 4, 4, 4]])

     已知尺度大小创建数组

    使用 NumPy 中函数创建 ndarray 数组,如: arange, ones, zeros

     

      数组对象的属性

    1. a = np.array([[0, 1, 2, 3], [4, 5, 6, 7]]) #二维数组
    2. b = np.array([0, 1, 2, 3]) #一维数组

     

    维度的改变

     对于创建后的ndarray数组,可以对其进行维度变换和元素类型变换。

    下方的输入为数组

    1. >>> a = np.ones((2,3,4), dtype=np.int32)
    2. >>> a.reshape((3,8))
    3. array([[1, 1, 1, 1, 1, 1, 1, 1],
    4. [1, 1, 1, 1, 1, 1, 1, 1],
    5. [1, 1, 1, 1, 1, 1, 1, 1]])
    6. >>> a #a的内容改变
    7. array([[[1, 1, 1, 1],
    8. [1, 1, 1, 1],
    9. [1, 1, 1, 1]],
    10. [[1, 1, 1, 1],
    11. [1, 1, 1, 1],
    12. [1, 1, 1, 1]]])
    1. >>> a.flatten() #平铺
    2. array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    3. 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1])
    4. >>> aa=np.arange(8).reshape((2,4))
    5. array([[0, 1, 2, 3],
    6. [4, 5, 6, 7]])
    7. In [27]: aa.transpose() #转置
    8. array([[0, 4],
    9. [1, 5],
    10. [2, 6],
    11. [3, 7]])
    1. #不确定数目
    2. >>> a.reshape((4,-1))
    3. array([[1, 1, 1, 1, 1, 1],
    4. [1, 1, 1, 1, 1, 1],
    5. [1, 1, 1, 1, 1, 1],
    6. [1, 1, 1, 1, 1, 1]])

    一维数组转换为列表

    数组转换为列表
    array.tolist()
    1. >>> np.arange(8).reshape((2,4))
    2. array([[0, 1, 2, 3],
    3. [4, 5, 6, 7]])
    1. >>> np.arange(8).reshape((2,4)).tolist()
    2. Out[42]: [[0, 1, 2, 3], [4, 5, 6, 7]

    二维数组:轴的概念

     二维数组:组合操作

     二维数组:分割操作

    1. >>> a=np.arange(9).reshape((3,3))
    2. array([[0, 1, 2],
    3. [3, 4, 5],
    4. [6, 7, 8]]
    5. >>> b=np.split(a, 3, axis=1)
    6. [array([[0],
    7. [3],
    8. [6]]),
    9. array([[1],
    10. [4],
    11. [7]]),
    12. array([[2],
    13. [5],
    14. [8]])]

    数组的索引

    一维数组的基本索引

    一维数组索引与 Python 的列表类似
    格式:array_name[索引值或序列]
    索引值0 开始从左递增,或 -1 开始从右递减
    起始编号 : 终止编号 ( 不含 ): 步长, 3 元素冒号分割
    1. >>> a=np.arange(1,6)
    2. >>> a
    3. array([1, 2, 3, 4, 5])
    1. ## 单个索引,切片索引
    2. >>> a[2]
    3. 3
    4. >>> a[1:4:2]
    5. array([2, 4])
    1. ## 索引值为序列
    2. >>> a[1,3] #列表
    3. array([2, 4])
    4. >>> a[np.array([1,3])] #数组
    5. array([2, 4])

    可变对象——数组

    数组是一个可变对象
    1. >>> a=np.arange(1,6)
    2. >>> b=a
    3. >>> b[-1]=8
    4. >>> b
    5. array([1, 2, 3, 4, 8])
    6. >>> a
    7. array([1, 2, 3, 4, 8])
    8. >>> b=a[:]
    9. >>> b[-1]=8
    10. >>> b
    11. array([1, 2, 3, 4, 8])
    12. >>> a
    13. array([1, 2, 3, 4, 8])

    数组切片与视图

    数组切片是原始数组的视图,数据不会被复制,视图上的任何修改都会直接反映到源 数组。
    1. >>> a=np.arange(1,6)
    2. >>> b=a[1:3]
    3. >>> b[-1]=8
    4. >>> b
    5. array([2, 8])
    6. >>> a
    7. array([1, 2, 8, 4, 5])
    1. >>> b=a[1:3].copy()
    2. >>> b[-1]=8
    3. >>> a
    4. array([1, 2, 8, 4, 5]) # 保持不变

     二维数组的基本索引

    0 索引值,轴 1 索引值。
    行索引值、列索引值与一维数组相同。
    ndarry [axis0_index,axis1_index]
    1. >>> arr2d =np.arange(9).reshape(3,3)
    2. >>> arr2d
    3. array([[0, 1, 2],
    4. [3, 4, 5],
    5. [6, 7, 8]])
    6. >>> arr2d[1,2]
    7. 5

    二维数组的切片索引

    二维数组默认沿着第 0 轴(即行索引)切片的。切片是沿着一个轴向选取元素的。
    ndarry[axis0_slice, axis1_slice]
    1. >>> arr2d =np.arange(9).reshape(3,3)
    2. >>> arr2d
    3. array([[0, 1, 2],
    4. [3, 4, 5],
    5. [6, 7, 8]])
    6. >>> arr2d[:2] #默认行索引
    7. array([[0, 1, 2],
    8. [3, 4, 5]])
    1. >>> arr2d[:2, : ] #:表示所有元素
    2. array([[0, 1, 2],
    3. [3, 4, 5]])

     二维数组的切片索引实例

    二维数组增删改查操作

     

     实例

    1. >>> np.insert(a,1,[0,0,0,0],0) #增加
    2. array([[ 0,1, 2,3],
    3. [0,0,0,0],
    4. [4,5,6,7],
    5. [8,9,10,11]])
    6. >>> np.delete(a,0,1) #删除含有0的列
    7. array([[ 1,2,3],
    8. [ 5,6,7],
    9. [ 9, 10, 11]])
    10. >>> np.append(a, [[1,2,3,4]], 0)
    11. #末尾修改
    12. array([[ 0,1, 2,3],
    13. [ 4,5,6,7],
    14. [ 8,9,10,11],
    15. [ 1,2,3,4]]) :
    16. >>> np.where(a==1)#查找含有1的
    17. (array([0], dtype=int64),
    18. array([1], dtype=int64))

    数组的矢量化

    矢量化 (vectorization) :数组不用编写循环即可实现对数据执行批量运算。
    大小相等的数组之间的任何算数运算都将应用至元素级。
    数组与标量之间的运算作用于数组的每一个元素
    1. >>> a=np.arange(1,9).reshape((2,4))
    2. >>> a
    3. array([[1, 2, 3, 4],
    4. [5, 6, 7, 8]])
    1. >>> a**2
    2. array([[ 1, 4, 9, 16],
    3. [25, 36, 49, 64]], dtype=int32)
    4. >>> 1/a
    5. array([[1, 0.5, 0.333333,0.25],
    6. [0.2 ,0.166667, 0.14285, 0.125])

    布尔型索引

    假设每个名字都对应 data 数组中的一行,而我们想要选出对应于名字 “Bob” 的所有行。
    布尔型数组的长度必须跟被索引的轴长度一致。

     布尔型索引:切边索引数组直接赋值

    切片索引 ( 整数型或布尔型 ) 后的数组均可直接赋值
    1. >>> data = np.random.randn(7, 4)
    2. >>> a
    3. array([[-1.04067731, -0.03879518, 0.98019589, -0.88795274],
    4. [-1.18705612, 0.4635102 , 0.91812337, -0.81458408],
    5. [ 0.86988195, 0.3959186 , 0.33063004, -0.1769584 ],
    6. [-0.46452414, -0.46827261, -0.20851302, 0.22864186],
    7. [-0.04973137, -0.23765974, 0.54263156, -0.06470696],
    8. [-0.89274831, 2.5559152 , 1.02892789, 2.16099481],
    9. [ 2.07400286, -1.96976106, -0.97007937, 1.84897368]])
    10. array([[ True, True, False, True], [ True, False, False, True], [False,
    11. False, False, True],
    12. [ True, True, True, False], [ True, True, False, True], [ True, False,
    13. False, False], [False, True, True, False]])
    14. >>> idx=(data<0)
    15. >>> data[data < 0] = 0
    16. >>> data
    17. array([[0., 0., 0.98019589, 0.],
    18. [0., 0.4635102 , 0.91812337, 0.],
    19. [0.86988195, 0.3959186 , 0.33063004, 0.],
    20. [0., 0., 0., 0.22864186],
    21. [0., 0., 0.54263156, 0.],
    22. [0., 2.5559152 , 1.02892789, 2.16099481],
    23. [2.07400286, 0., 0., 1.84897368]])

    用于布尔型数组的方法

    sum 经常被用来对布尔型数组中的 True 值计数。
    any 用于测试数组中是否存在一个或多个 True
    all 则检查数组中所有值是否都是 True
    1. >>> arr = np.random.randn(10)
    2. >>> arr
    3. array([-0.71497659, -0.97902783, -
    4. 0.18698594, 0.08350516, -0.42339716,
    5. -0.86465629, 0.70777104, -1.22436206, -
    6. 1.02389181, -1.30741898])
    7. >>> arr_bool=(arr>=0)
    8. array([False, False, False, True, False, False,
    9. True, False, False, False])
    10. >>> arr_bool.sum()
    11. 2 #大于0的个数
    12. >>> arr_bool.any()
    13. True #存在大于0
    14. >>> arr_bool.all()
    15. False #是否均大于0

    一元算数函数

    通用函数 (ufunc) 是一种对 ndarray 中的数据执行元素级运算的函数,可看作为简单函数的矢量化
    函数。
    ndarray 中的数据执行元素级运算的函数。

     ndarray中的数据执行元素级运算的函数

    例子

    1. >>> a=np.arange(1,10).reshape((3,3))
    2. array([[1, 2, 3],
    3. [4, 5, 6],
    4. [7, 8, 9]])
    5. >>> np.sqrt(a)
    6. array([[1. , 1.41421356, 1.73205081],
    7. [2. , 2.23606798, 2.44948974],
    8. [2.64575131, 2.82842712, 3. ]])
    9. >>> np.modf(b)
    10. array([[0., 0.41421356, 0.73205081],
    11. [0. , 0.23606798, 0.44948974],
    12. [0.64575131, 0.82842712, 0. ]]),
    13. array([[1., 1., 1.],[2., 2., 2.],[2., 2.,
    14. 3.]]))

    二元算数函数

    1. >>> np.nodf(b)
    2. >>> a=np.arange(1,10).reshape((3,3))
    3. >>> b=np.sqrt(a)
    4. >>>np.fmax(a,b)
    5. array([[1., 2., 3.],
    6. [4., 5., 6.],
    7. [7., 8., 9.]])
    8. >>> a>b
    9. array([[False,True, True],
    10. [ True, True, True],
    11. [ True, True, True]])

     meshgrid函数

    适用于生成网格型数据,可以接受两个一维数组生成两个二维矩阵,对应两个数组中所有的 (x,y) 对。
    xx,yy=np.meshgrid(x,y)
    其中生成的第一个二维数组是以 xarray 为行,共 y-dimesion 行的向量;第二个二维数 组是以
    yarray 的转置为列,共 x-dimesion 列的向量。

    1. >>> x=np.array([0,1,2,3]) #横坐标
    2. >>> y=np.array([0,1,2,3,4]) #纵坐标
    3. >>> xx,yy=np.meshgrid(x,y)
    4. >>> xx
    5. array([[0,1,2,3],
    6. [0,1,2,3],
    7. [0,1,2,3],
    8. [0,1,2,3],
    9. [0,1,2,3]])
    10. >>> yy
    11. array([[0,0,0,0],
    12. [1,1,1,1],
    13. [2,2,2,2],
    14. [3,3,3,3],
    15. [4,4,4,4])

     三元函数——where函数

    numpy.where 函数是三元表达式 x if condition else y 的矢量化版本
    x if condition else y
              ||
              V
    np.where(condition,x,y)

    1. >>> arr = np.random.randn(4,4)
    2. >>> arr >0
    3. array([[False, False, False, False],
    4. [ True, True, False, True],
    5. [ True, True, True, False],
    6. [ True, False, True, True]],
    7. dtype=bool)
    8. >>> np.where(arr>0, 2,- 1)
    9. array([[-2, -2, -2, -2],
    10. [ 2, 2, -2 ,2],
    11. [ 2, 2, 2 ,-2],
    12. [ 2, -2, 2 ,2]])

    集合逻辑

    NumPy 提供了一些针对一维 ndarray 的基本集合运算,其中 np.unique 用于找出数组中的唯一值并
    返回已排序的结果。

    统计函数

    通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算。聚合计算(aggregation通常叫做约简(reduction))

    注意轴操作:axis=0或1

    伪随机数的生成 

    numpy.random 模块对 Python 内置的 random 进行了补充,增加了一些用于高效生成多种概率分布
    的样本值的函数。
    Python 内置的 random 模块则只能一次生成一个样本值。
    1. >>> from random import normalvariate
    2. >>> N = 1000000
    3. >>> samples = [normalvariate(0, 1) for _ in range(N)]
    4. 1.77 s +- 126 ms per loop (mean +- std. dev. of 7 runs, 1 loop each)
    5. >>> np.random.normal(size=N)
    6. 61.7 ms +- 1.32 ms per loop (mean +- std. dev. of 7 runs, 10 loops each)

    常用分布函数的随机数

     线性代数

    线性代数是任何数组库的重要组成部分, linalg 模块中有标准的矩阵分解运算以及诸如求逆和行列
    式之类的函数

     

    实例

     

    专用函数

    sort 函数返回排序后的数组
    argsort 函数返回输入数组排序后的下标;
    lexsort 函数根据键值的字典序进行排序;
    例如: ind = np.lexsort((b,a)) # Sort by a, then by b
    ndarray 类的 sort 方法可对数组进行原地排序;
    msort 函数沿着第一个轴排序;
    sort_complex 函数对复数按照先实部后虚部的顺序进行排序增强可维护性

    Numpy文件操作

    tofile() fromfile()
    数据以二进制格式写进文件,事先知道存入文件时数组的维度和元素类型 。
    save() load()
    用的二进制格式保存数据,它们会自动处理元素类型和形状等信 息,以 .npy
    .npz 为扩展名。
    savetxt() loadtxt()
    读写 1 维和 2 维数组的文本文件。

    np.loadtxt函数

    np.loadtxt ( fname, dtype=, comments='#', delimiter=None,
    converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes',
    max_rows=None,*, like=None )
    fname
    被读取的文件名(文件的相对地址或绝对地址)
    dtype
    指定读取后数据的数据类型,例如 float32 int32
    comments 跳过文件中指定参数开头的行(即不读取)

    delimiter 指定读取文件中数据的分割符, ( 例如 ,csv 文件中的逗号 )
    skiprows
    选择跳过的行数,默认从第一读取。 ( 例如 skiprows =1 ,从第二行开始读取 )
    converters 对读取的数据进行预处理
    usecols
    指定仅读取的列
    unpack 选择是否将数据进行向量输出
    encoding 对读取的文件进行预编码。
    1. >>> converters={1:_is_num}
    2. #字典的形式,对指定 的列执行相关操作

    读文件

    np.loadtxt(frame,dtype=np.float, delimiter=None,unpack=False)

     

    写文件

     np.savetxt(frame, array, fmt='%.18e', delimiter=None)

     

     

     

    总结

     传送门:Python全套学习笔记

  • 相关阅读:
    在服务器上使用Docker buildx构建适用于jetson(linux/arm64/v8)平台的镜像
    JAVA高级——lambda
    安装虚拟机找不到虚拟网啦1(eth1)不出现
    今天刚下jdk11和netbeans12,在打开github的一个文件的时候没有任何反应,我看别人是可以打开的
    软件测试 —— 常见的自动化测试架构!
    目标检测算法改进系列之Backbone替换为RepViT
    NSFC申请不中的反思 (内部讨论)
    低代码与传统开发:综合比较
    mfc140.dll丢失如何修复,分享多种有效的修复方法
    睡眠质量记录64
  • 原文地址:https://blog.csdn.net/weixin_60535956/article/details/127850623