• Python Numpy知识点


    一、Numpy简介

        一个用python实现的科学计算,包括:1、一个强大的N维数组对象Array;2、比较成熟的(广播)函数库;3、用于整合C/C++和Fortran代码的工具包;4、实用的线性代数、傅里叶变换和随机数生成函数。numpy和稀疏矩阵运算包scipy配合使用更加方便。
        NumPy(Numeric Python)提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。多为很多大型金融公司使用,以及核心的科学计算组织如:Lawrence Livermore,NASA用其处理一些本来使用C++,Fortran或Matlab等所做的任务。

                                                                                                                             ---《百度百科》

    二、Numpy知识点

    1.安装Numpy包,并且导入

    1. pip install numpy
    2. import numpy as np

    2.创建数组

    1. a = np.array([1, 2, 3, 4, 5])
    2. b = np.arange(0, 6, 1)
    3. c = np.random.random((3, 3))
    4. d = np.random.randint(0, 9, size=(3, 3))
    5. print("a:", a)
    6. print("b:", b)
    7. print("c:", c)
    8. print("d:", d)

    ①np.array直观创建数组,输入是啥生成就是啥。

    ②np.arange创建数组,需要给定起始值、终止值的后一位数字、步长。

    ③np.random.random创建数组,需要给定数组的维度,其元素是0-1之间的随机数。

    ④np.random.randint创建一个N阶数组,需要给定元素属于的区间、数组的维度。元素是整数。

    1. a: [1 2 3 4 5]
    2. b: [0 1 2 3 4 5]
    3. c: [[0.10739085 0.99541616 0.76174493]
    4. [0.30140398 0.87467374 0.30959958]
    5. [0.23803194 0.47848497 0.38842102]]
    6. d: [[2 0 4]
    7. [7 0 7]
    8. [3 4 5]]

    3.特殊函数

    1. zeros = np.zeros((1, 4))
    2. ones = np.ones((2, 2))
    3. full = np.full((2, 3), 9)
    4. eye = np.eye(3)

    ①np.zeros生成指定维数,元素全为0的数组

    ②np.ones生成指定维数,元素全为1的数组

    ③np.full需要指定数组的维度以及填充数组的数字

    ④np.eye生成N阶数组,除了对角线元素为1,其它元素为0

    1. zero: [[0. 0. 0. 0.]]
    2. ones: [[1. 1.]
    3. [1. 1.]]
    4. full [[9 9 9]
    5. [9 9 9]]
    6. eye: [[1. 0. 0.]
    7. [0. 1. 0.]
    8. [0. 0. 1.]]

    注意:数组中的数据类型必须是一致的,包括整型以及浮点型。

    4.数据类型

    数据类型描述唯一标识符
    bool用一个字节存储的布尔类型(True或False)b
    int8一个字节大小,-128 至 127i1
    int16整数,16 位整数(-32768 ~ 32767)i2
    int32整数,32 位整数(-2147483648 ~ 2147483647)i4
    int64整数,64 位整数(-9223372036854775808 ~ 9223372036854775807)i8
    uint8无符号整数,0 至 255u1
    uint16无符号整数,0 至 65535u2
    uint32无符号整数,0 至 2 ** 32 - 1u4
    uint64无符号整数,0 至 2 ** 64 - 1u8
    float16半精度浮点数:16位,正负号1位,指数5位,精度10位f2
    float32单精度浮点数:32位,正负号1位,指数8位,精度23位f4
    float64单精度浮点数:64位,正负号1位,指数11位,精度52位f8
    complex64复数,分别用两个32位浮点数表示实部和虚部c8
    complex128复数,分别用两个64位浮点数表示实部和虚部c16
    object_python对象U
    string_字符串S
    unicode_unicode类型U

    ①创建数组指定数据类型

    1. zeros = np.zeros((1, 4), dtype='int16')
    2. ones = np.ones((2, 2), dtype='float32')
    1. zero: [[0 0 0 0]]
    2. ones: [[1. 1.]
    3. [1. 1.]]

    ②查询数据类型

    1. full = np.full((2, 3), 9, dtype='int8')
    2. eye = np.eye(3, dtype='float16')
    3. print(full.dtype)
    4. print(eye.dtype)
    1. int8
    2. float16

    ③修改数据类型

    1. full = np.full((2, 3), 9, dtype='int8')
    2. print(full.dtype)
    3. full = full.astype('int16')
    4. print(full.dtype)
    1. int8
    2. int16

    注意:

      1.Numpy是基于C语言编写的,引用了C语言的数据类型。

      2.针对不同的数据赋予不同的数据类型,可以有效节省空间。

    5.多维数组

    (大白话来说,第一个出现的数字前面有多少个'[',那么这个数组就是几维的。)

    ①定义1维、2维、3维数组

    1. arr1 = np.array([1,2,3]) # 一维数组
    2. arr2 = np.array([[1,2,3],[4,5,6]]) # 二维数组
    3. arr3 = np.array([ # 三维数组
    4. [
    5. [1,2,3],
    6. [4,5,6]
    7. ],
    8. [
    9. [7,8,9],
    10. [10,11,12]
    11. ]
    12. ])

    ②数组维度查询

    1. print(arr1.shape)
    2. print(arr2.shape)
    3. print(arr3.shape)

    ③修改数组形状

    1. a1 = np.array([ # 创建新数组a1
    2. [
    3. [1,2,3],
    4. [4,5,6]
    5. ],
    6. [
    7. [7,8,9],
    8. [10,11,12]
    9. ]
    10. ])
    11. a2 = a1.reshape((2,6)) # 保持元素个数不变的情况下,修改形状为2*6
    12. a3 = a2.flatten() # 铺平为一维向量

     ④查看元素个数与所占内存

    1. print(a1.size)
    2. print(a1.itemsize)
    3. print(a1.itemsize * a1.size)

    其中:

      1.a1.size代表数组元素个数

      2.a1.itemsize代表单个元素所占的内存,单位是字节

      3.两者相乘代表数组一共所占用的内存

    6.数组索引和切片

    ①一维数组

    1. a1 = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
    2. print(a1[4]) # 索引操作
    3. print(a1[4:6]) # 切片操作
    4. print(a1[::2]) # 使用步长
    5. print(a1[-1]) # 使用负数作为索引(从右往左数第一位数字)
    1. [0 1 2 3 4 5 6 7 8 9]
    2. 4
    3. [4 5]
    4. [0 2 4 6 8]
    5. 9

    ②二维数组

    1. arr2 = np.random.randint(0,10,size=(4,6))
    2. print(arr2[0]) # 获取第0行数据
    3. print(arr2[1:3]) # 获取第1,2行数据
    4. print(arr2[[0, 2, 3]]) # 获取0,2,3行数据
    5. print(arr2[2, 1]) # 获取第二行第一列数据
    6. print(arr2[[1, 2], [4,5]]) # 获取多个数据 例:第一行第四列、第二行第五列数据
    7. print(arr2[1:3, 4:6]) # 获取多个数据 例:第一、二行的第四、五列的数据
    8. print(arr2[:, 1]) # 获取某一列数据 例:第一列的全部数据
    9. print(arr2[:, [1,3]]) # 获取多列数据 例:第一、三列的全部数据

    ③布尔索引

    1. a3 = np.arange(24).reshape((4,6))
    2. print(a3[a3<10]) # 挑选出小于10的元素
    3. print(a3[(a3 < 5) | (a3 > 10)]) # 挑选出小于5或者大于10的元素

    说明:

      1.布尔索引是通过相同数据上的True还是False来进行提取的

      2.同时满足用&,满足其一即可用|

      3.有多个条件时,每个条件用圆括号括起来

    7.数组元素值的替换:

    ①索引

    1. a3 = np.random.randint(0,10,size=(3,5))
    2. a3[1] = 0 # 将第一行数据全部更换为0
    3. a3[1] = np.array([1,2,3,4,5]) # 将a3数组第一行数据更换为[1,2,3,4,5]

    ②条件索引

    a3[a3 < 3] = 1   # 数组中值小于3的元素全部替换为1

    ③函数(用where函数来实现替换值)

    result = np.where(a3<5,0,1)

    代码的作用是a3数组中小于5的值全部更换为0,其余的元素更换为1

    8.数组的广播机制

      数组的广播原则:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,那么他们是广播兼容的。广播会在全是和(或)长度为1的维度上进行。

      ①数组与数字运算

    1. a1 = np.random.randint(0,5,size=(3,5))
    2. print(a1*2) # 数组中的所有元素都乘2
    3. print(a1.round(2)) # 数组中所有的元素只保留2位小数

      ②数组与数组运算

    1. a1 = np.random.randint(0,5,size=(3,5))
    2. a2 = np.random.randint(0,5,size=(3,5)) # a1+a2满足数组广播机制:形状一致
    3. a3 = np.random.randint(0,5,size=(3,4)) # a1+a3不满足:形状不一致的数组不能相加减
    4. a4 = np.random.randint(0,5,size=(3,1)) # a1+a4满足:俩数组行数相同,其中一个数组列数为1
    5. a5 = np.random.randint(0,5,size=(1,5)) # a1+a5满足,俩数组列数相同,其中一个数组行数为1

    总结:

      1.数组可以直接和数字进行运算

      2.两个shape想要的数组是可以进行运算的

      3.如果两个shape不同的数组想要进行运算,那要看看二者满不满足广播原则

    9.数组形状的操作

      ①数组形状的改变

    1. a1 = np.random.randint(0,10,size=(3,4))
    2. a2 = a1.reshape((2,6)) # 有返回
    3. a1.resize((4,3)) # 无返回

    reshape和resize的区别:

      reshape和resize都是用来修改数组形状的,但是结果不一样。reshape是将数组转换为指定的形状,然后返回转换后的结果。resize是将数组转换为指定的形状,会直接修改数组本身,并且不会返回任何值。

      ②flatten与ravel(都是将多维数组转换为一维数组,但是方式不一样)

    1. a3 = np.random.randint(0,10,size=(3,4))
    2. a4 = a3.flatten() # 拷贝一份返回
    3. a5 = a3.ravel() # 返回这个视图的引用

     也就是说:

        修改a4的值不会对a3造成影响;但是修改a5的值会一并修改a3的值。

      ③数组的叠加

      vstack:代表在垂直方向叠加,想要叠加成功必须满足列数一致;

      hstack:代表在水平方向叠加,要想叠加成功必须满足行数一致;

      concatenate:可以手动指定axis参数具体在哪个方向叠加。

            1>axis = 0代表在水平方向叠加

            2>axis = 1代表在垂直方向叠加

            3>axis = None代表先进行叠加,再转化为1维数组

    1. vstack1 = np.random.randint(0,10,size=(3,4)) # 垂直方向待叠加的数组
    2. vstack2 = np.random.randint(0,10,size=(2,4)) # 垂直方向待叠加的数组
    3. vstack3 = np.vstack([vstack1,vstack2]) # 垂直叠加方法一
    4. vstack4 = np.concatenate([vstack1,vstack2],axis=0) # 垂直叠加方法二
    5. h1 = np.random.randint(0,10,size=(3,4)) # 水平方向待叠加的数组
    6. h2 = np.random.randint(0,10,size=(3,1)) # 水平方向待叠加的数组
    7. h3 = np.hstack([h2,h1]) # 水平叠加方法一
    8. h4 = np.concatenate([h2,h1],axis=1) # 水平叠加方法二
    9. h5 = np.concatenate([h2,h1],axis=None) # 先识别垂直或者水平叠加,后转换为一维数组

        ④数组的切割

      hsplit:代表在水平方向切割,按列进行切割。切割方式如下:

                        1.直接指定平均切割成多少列

                        2.指定切割的下标值

      vsplit:代表在垂直方向切割,按行进行切割。切割方式与hsplit相同。

    1. hs1 = np.random.randint(0, 10, size=(3, 4))
    2. np.hsplit(hs1, 2) # 水平方向平均分为2份,要求列数可被此整数整除
    3. np.hsplit(hs1, (1, 2)) # 水平方向分为1,1,2列(在1,2处切割)
    1. [array([[9, 4],
    2. [4, 2],
    3. [4, 7]]), array([[4, 6],
    4. [9, 6],
    5. [7, 3]])]
    6. [array([[9],
    7. [4],
    8. [4]]), array([[4],
    9. [2],
    10. [7]]), array([[4, 6],
    11. [9, 6],
    12. [7, 3]])]
    1. vs1 = np.random.randint(0, 10, size=(4, 5))
    2. np.vsplit(vs1, 4) # 垂直方向平均分为4份
    3. np.vsplit(vs1, (1, 3)) # 垂直方向分为1,2,1行
    1. [array([[0, 3, 7, 4, 7]]), array([[0, 1, 2, 1, 1]]), array([[9, 8, 4, 7, 5]]), array([[9, 8, 2, 7, 1]])]
    2. [array([[0, 3, 7, 4, 7]]), array([[0, 1, 2, 1, 1],
    3. [9, 8, 4, 7, 5]]), array([[9, 8, 2, 7, 1]])]

      ⑤矩阵转置

    1. t1 = np.random.randint(0,10,size=(3,4))
    2. t1.T # 数组t1转置
    3. t2 = t1.transpose() # 返回的是一个view,对返回值上进行修改会影响到原来的数组

    10.View和拷贝

    ①如果只是简单的赋值,那么就不会进行拷贝

    1. a = np.arange(12)
    2. b = a
    3. print(b is a) # 返回为True,说明b和a是相同的

    ②浅拷贝

      有些情况,会进行变量的拷贝,但他们所指向的内存空间都是一样的,那么这种情况叫做浅拷贝,或者叫做View(视图)

    1. c = a.view()
    2. print(c is a) # 返回false,说明c和a栈区空间不同,但是所指向的内存空间是一样的
    3. c[0] = 100 # 修改c的值,a也会受到影响

    ③深拷贝

      将之前数据完完整整的拷贝一份放到另外一块内存空间中,这样就是两个完全不同的值了。

    1. d = a.copy()
    2. print(d is a) # 返回false,说明在不同栈区
    3. d[1]=200 # 数组d被修改,而a原封不动,说明两者内存空间不一样。

    总结:

    在数组操作中分成三种拷贝:

      1.不拷贝:直接赋值,那么栈区没有拷贝,只是用同一个栈区定义了不同的名称。

      2.浅拷贝:只拷贝栈区,栈区指定的堆区并没有拷贝。 

      3.深拷贝:栈区和堆区都拷贝

    未完待续~

  • 相关阅读:
    基金合作保密协议
    C++标准模板(STL)- 算法 (std::copy_n)
    软件测试之随机测试
    【C语言深入理解指针(4)】
    异常
    会议OA项目之我的会议排座&批审功能
    Python爬虫——BeautifulSoup的基本使用
    宇凡微发布2.4G合封芯片YE08,融合高性能MCU与射频收发功能
    视频素材从哪里找?看这篇就对了
    中尺度混凝土二维有限元求解——运行弯曲、运行光盘、运行比较、运行半圆形(Matlab代码实现)
  • 原文地址:https://blog.csdn.net/m0_64007201/article/details/127656327