zoukankan      html  css  js  c++  java
  • AI炼丹

    深度学习必备库 - Numpy

    Numpy是Numerical Python的简称,是Python中高性能科学计算和数据分析的基础包。Numpy提供了一个多维数组类型ndarray,它具有矢量算术运算和复杂广播的能力,可以实现快速的计算并且能节省存储空间。

    在本文中将会介绍:

    1. 基础数据结构ndarray数组

    ndarray数组是Numpy中的基础数据结构式, 本小结将介绍:

    1.1 为什么引入ndarray数组

    在Python中使用list列表可以非常灵活的处理多个元素的操作,但是其效率却比较低。ndarray数组相比于Python中的list列表具有以下特点:

    • ndarray数组中所有元素的数据类型是相同的,数据地址是连续的,批量操作数组元素时速度更快;list列表中元素的数据类型可以不同,需要通过寻址方式找到下一个元素

    • ndarray数组中实现了比较成熟的广播机制,矩阵运算时不需要写for循环

    • Numpy底层是用c语言编写的,内置了并行计算功能,运行速度高于纯Python代码

    例1. ndarray数组和list列表分别完成对每个元素增加1的计算

    # Python原生的list
    # 假设有两个list
    a = [1, 2, 3, 4, 5]
    b = [2, 3, 4, 5, 6]
    
    # 完成如下计算
    # 1 对a的每个元素 + 1
    # a = a + 1 不能这么写,会报错
    # a[:] = a[:] + 1 也不能这么写,也会报错
    for i in range(5):
        a[i] = a[i] + 1
    a
    [2, 3, 4, 5, 6]
    
    ########################################################
    # 使用ndarray
    import numpy as np
    a = np.array([1, 2, 3, 4, 5])
    a = a + 1
    a
    
    array([2, 3, 4, 5, 6])
    

    例2. ndarray数组和list列表分别完成相加计算

    #  计算 a和b中对应位置元素的和,是否可以这么写? python中的+运算?
    a = [1, 2, 3, 4, 5]
    b = [2, 3, 4, 5, 6]
    c = a + b
    # 检查输出发现,不是想要的结果
    c
    [1, 2, 3, 4, 5, 2, 3, 4, 5, 6]
    
    ########################################################
    # 使用for循环,完成两个list对应位置元素相加
    c = []
    for i in range(5):
        c.append(a[i] + b[i])
    c
    [3, 5, 7, 9, 11]
    
    #########################################################
    # 使用numpy中的ndarray完成两个ndarray相加
    import numpy as np
    a = np.array([1, 2, 3, 4, 5])
    b = np.array([2, 3, 4, 5, 6])
    c = a + b 
    c
    array([ 3,  5,  7,  9, 11])
    

    ndarray数组的矢量计算能力使得不需要写for循环,就可以非常方便的完成数学计算,在操作矢量或者矩阵时,可以像操作普通的数值变量一样编写程序,使得代码极其简洁。
    另外,ndarray数组还提供了广播机制: 当两个数组的形状并不相同的时候,可以通过扩展数组的方法来实现相加、相减、相乘等操作,简单点理解就是两个数组中,从末尾开始计算,数组的维度符合运算要求(后缘维度),就可以进行计算。

    例3. 广播机制,1维数组和2维数组相加

    # 二维数组维度 2x5
    # array([[ 1,  2,  3,  4,  5],
    #         [ 6,  7,  8,  9, 10]])
    d = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
    # c是一维数组,维度5
    # array([ 4,  6,  8, 10, 12])
    c = np.array([ 4,  6,  8, 10, 12])
    e = d + c
    e
    
    array([[ 5,  8, 11, 14, 17],
           [10, 13, 16, 19, 22]])
    

    1.2 如何创建ndarray数组

    • 从list列表开始创建
    • 指定起止范围及间隔创建
    • 创建值全为0的ndarray数组
    • 创建值全为1的ndarray数组

    例4. 创建ndarray的几种常见方法

    import numpy as np
    # 从list创建array
    a = [1,2,3,4,5,6]
    b = np.array(a)
    b
    
    array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
    
    #########################################################
    # 通过np.array创建
    # 通过指定start, stop (不包括stop),interval来产生一个1为的ndarray
    # 类似于python中常用的range函数,用法一致
    a = np.arange(0, 20, 2)
    a
    
    array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
    
    #########################################################
    # 创建全0的ndarray
    a = np.zeros([3,3])    # 注意此处为zeros,[],()都可以
    # a = np.zeros((3,3))
    a
    
    array([[0., 0., 0.],
           [0., 0., 0.],
           [0., 0., 0.]])
    #########################################################
    # 创建全1的ndarray
    a = np.ones([3,3])
    a
    
    array([[1., 1., 1.],
           [1., 1., 1.],
           [1., 1., 1.]])
    #########################################################
    # 创建单位矩阵的ndarray
    a = np.eyes(3)    # 因为单位矩阵,所以是eye,只需传入一个参数
    a
    
    array([[1., 0., 0.],
           [0., 1., 0.],
           [0., 0., 1.]])
    

    查看ndarray数组的属性
    ndarray的属性包括形状shape、数据类型dtype、元素个数size和维度ndim等,下面的程序展示如何查看这些属性

    例5. 查看ndarray属性

    # 数组的数据类型 ndarray.dtype
    # 数组的形状 ndarray.shape,1维数组(N, ),二维数组(M, N),三维数组(M, N, K)
    # 数组的维度大小,ndarray.ndim, 其大小等于ndarray.shape所包含元素的个数
    # 数组中包含的元素个数 ndarray.size,其大小等于各个维度的长度的乘积
    
    a = np.ones([3, 3])
    print('a, dtype: {}, shape: {}, size: {}, ndim: {}'.format(a.dtype, a.shape, a.size, a.ndim))
    
    a, dtype: float64, shape: (3, 3), size: 9, ndim: 2
    

    例6. 改变ndarray数组的数据类型和形状

    # 转化数据类型
    # 不同数据类型的数组可以进行计算,但计算完之后的结果会改变
    a = np.ones((3, 3))
    b = a.astype(np.int64)
    c = a.astype(np.float32)
    d = b + c
    print('b, dtype: {}, shape: {}'.format(b.dtype, b.shape))
    print('c, dtype: {}, shape: {}'.format(c.dtype, c.shape))
    print('d, dtype: {}, shape: {}'.format(d.dtype, d.shape))
    
    b, dtype: int64, shape: (3, 3)
    c, dtype: float32, shape: (3, 3)
    d, dtype: float64, shape: (3, 3)
    
    #######################################################
    
    # 改变形状
    c = a.reshape([1, 9])
    print('c, dtype: {}, shape: {}'.format(c.dtype, c.shape))
    
    

    1.3 ndarray 数组的基本运算

    ndarray数组可以像普通的数值型变量一样进行加减乘除操作,这一小节将介绍两种形式的基本运算:

    • 标量和ndarray数组之间的运算
    • 两个ndarray数组之间的运算

    例7. 标量和ndarray数组之间的运算

    # 标量除以数组,用标量除以数组的每一个元素
    arr = np.array([[1., 2., 3.], [4., 5., 6.]])
    1. / arr
    
    array([[1.        , 0.5       , 0.33333333],
           [0.25      , 0.2       , 0.16666667]])
    
    
    #######################################################
    # 标量乘以数组,用标量乘以数组的每一个元素
    arr = np.array([[1., 2., 3.], [4., 5., 6.]])
    2.0 * arr
    
    array([[ 2.,  4.,  6.],
           [ 8., 10., 12.]])
    
    
    #######################################################
    # 标量加上数组,用标量加上数组的每一个元素
    arr = np.array([[1., 2., 3.], [4., 5., 6.]])
    2.0 + arr
    
    array([[3., 4., 5.],
           [6., 7., 8.]])
    
    
    #######################################################
    # 标量减去数组,用标量减去数组的每一个元素
    arr = np.array([[1., 2., 3.], [4., 5., 6.]])
    2.0 - arr
    
    array([[ 1.,  0., -1.],
           [-2., -3., -4.]])
    

    例8. 两个ndarray数组之间的运算

    # 数组 减去 数组, 用对应位置的元素相减
    arr1 = np.array([[1., 2., 3.], [4., 5., 6.]])
    arr2 = np.array([[11., 12., 13.], [21., 22., 23.]])
    arr1 - arr2
    
    array([[12., 14., 16.],
           [25., 27., 29.]])
    
    
    #######################################################
    # 数组 乘以 数组,用对应位置的元素相乘
    arr1 * arr2
    array([[ 11.,  24.,  39.],
           [ 84., 110., 138.]])
    
    
    #######################################################
    # 数组开根号,将每个位置的元素都开根号
    arr ** 0.5
    array([[1.        , 1.41421356, 1.73205081],
           [2.        , 2.23606798, 2.44948974]])
    
    

    1.4 ndarray数组的索引和切片

    在程序中,通常需要访问或者修改ndarray数组某个位置的元素,也就是要用到ndarray数组的索引;有些情况下可能需要访问或者修改一些区域的元素,则需要使用数组的切片。索引和切片的使用方式与Python中的list类似,ndarray数组可以基于 -n ~ n-1 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。

    例9. ndarray数组索引和切片

    # 1维数组索引和切片
    a = np.arange(30)
    a[10]     # 从0开始计算第10号位置
    10
    
    
    #######################################################
    a = np.arange(30)
    b = a[4:7]
    b
    array([4, 5, 6])
    
    
    #######################################################
    # 将一个标量值赋值给一个切片时,该值会自动传播到整个选区(如下图所示)
    # 切片并不是生成一列新的数组,而仅仅只把其中一段拿出来操作,对切片的操作会影响原始数据
    a = np.arange(30)
    a[4:7] = 10
    a
    array([ 0,  1,  2,  3, 10, 10, 10,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
           17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
    
    
    #######################################################
    # 数组切片是原始数组的视图。这意味着数据不会被复制,
    # 视图上的任何修改都会直接反映到源数组上
    a = np.arange(30)
    arr_slice = a[4:7]
    arr_slice[0] = 100
    a, arr_slice
    
    (array([  0,   1,   2,   3, 100,   5,   6,   7,   8,   9,  10,  11,  12,
             13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,
             26,  27,  28,  29]), array([100,   5,   6]))
    
    
    #######################################################
    # 通过copy给新数组创建不同的内存空间
    a = np.arange(30)
    arr_slice = a[4:7]
    arr_slice = np.copy(arr_slice)
    arr_slice[0] = 100
    a, arr_slice
    
    (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
            17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]),
     array([100,   5,   6]))
    
    
    #######################################################
    # 多维数组索引和切片
    a = np.arange(30)
    arr3d = a.reshape(5, 3, 2)  # 可以理解为按从大块往小块分
    arr3d
    
    array([[[ 0,  1],
            [ 2,  3],
            [ 4,  5]],
    
           [[ 6,  7],
            [ 8,  9],
            [10, 11]],
    
           [[12, 13],
            [14, 15],
            [16, 17]],
    
           [[18, 19],
            [20, 21],
            [22, 23]],
    
           [[24, 25],
            [26, 27],
            [28, 29]]])
    
    #######################################################
    # 只有一个索引指标时,会在第0维上索引,后面的维度保持不变
    arr3d[0]
    
    array([[0, 1],
           [2, 3],
           [4, 5]])
    
    
    # 两个索引指标
    arr3d[0][1]
    
    array([2, 3])
    
    

    1.5 ndarray数组的统计计算

    例10. ndarray的数组统计运算:

    • mean 均值
    • std 标准差
    • var 方差
    • sum 求和
    • max 最大值
    • min 最小值
    # 计算均值,使用arr.mean() 或 np.mean(arr),二者是等价的
    arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
    arr.mean(), np.mean(arr)
    (5.0, 5.0)
    
    
    # 求和
    arr.sum(), np.sum(arr)
    (45, 45)
    
    
    # 求最大值
    arr.max(), np.max(arr)
    (9, 9)
    
    
    
    # 求最小值
    arr.min(), np.min(arr)
    (1, 1)
    
    
    #######################################################
    # 指定计算的维度
    # axis = 0 表示列
    # axis = 1 表示行
    
    # 沿着第1维求平均,也就是将[1, 2, 3]取平均等于2,[4, 5, 6]取平均等于5,[7, 8, 9]取平均等于8
    arr.mean(axis = 1)
    array([2., 5., 8.])
    
    
    # 沿着第0维求和,也就是将[1, 4, 7]求和等于12,[2, 5, 8]求和等于15,[3, 6, 9]求和等于18
    arr.sum(axis=0)
    array([12, 15, 18])
    
    
    # 沿着第0维求最大值,也就是将[1, 4, 7]求最大值等于7,[2, 5, 8]求最大值等于8,[3, 6, 9]求最大值等于9
    arr.max(axis=0)
    array([7, 8, 9])
    
    
    # 沿着第1维求最小值,也就是将[1, 2, 3]求最小值等于1,[4, 5, 6]求最小值等于4,[7, 8, 9]求最小值等于7
    arr.min(axis=1)
    array([1, 4, 7])
    
    
    # 计算标准差
    arr.std()
    2.581988897471611
    
    
    # 计算方差
    arr.var()
    6.666666666666667
    
    
    # 找出最大元素的索引
    arr.argmax(), arr.argmax(axis=0), arr.argmax(axis=1)
    (8, array([2, 2, 2]), array([2, 2, 2]))
    
    
    # 找出最小元素的索引
    arr.argmin(), arr.argmin(axis=0), arr.argmin(axis=1)
    (0, array([0, 0, 0]), array([0, 0, 0]))
    
    

    2. 随机数np.random

    2.1 创建随机ndarray数组

    例10. 创建随机数组

    # 生成均匀分布随机数,随机数取值范围在[0, 1)之间
    a = np.random.rand(3, 3)
    a
    array([[0.08833981, 0.68535982, 0.95339335],
           [0.00394827, 0.51219226, 0.81262096],
           [0.61252607, 0.72175532, 0.29187607]])
    
    
    # 生成均匀分布随机数,指定随机数取值范围和数组形状
    a = np.random.uniform(low = -1.0, high = 1.0, size=(2,2))
    a
    array([[ 0.83554825,  0.42915157],
           [ 0.08508874, -0.7156599 ]])
    
    
    # 生成标准正态分布随机数
    a = np.random.randn(3, 3)
    a
    array([[ 1.484537  , -1.07980489, -1.97772828],
           [-1.7433723 ,  0.26607016,  2.38496733],
           [ 1.12369125,  1.67262221,  0.09914922]])
    
    
    # 生成正态分布随机数,指定均值loc和方差scale
    a = np.random.normal(loc = 1.0, scale = 1.0, size = (3,3))
    a
    array([[2.39799638, 0.72875201, 1.61320418],
           [0.73268281, 0.45069099, 1.1327083 ],
           [0.52385799, 2.30847308, 1.19501328]])
    

    2.2 设置随机种子

    例11. 随机种子

    # 可以多次运行,观察程序输出结果是否一致
    # 如果不设置随机数种子,观察多次运行输出结果是否一致
    np.random.seed(10)
    a = np.random.rand(3, 3)
    a
    array([[0.77132064, 0.02075195, 0.63364823],
           [0.74880388, 0.49850701, 0.22479665],
           [0.19806286, 0.76053071, 0.16911084]])
    

    2.3 随机打乱ndarray数组顺序

    # 生成一维数组
    a = np.arange(0, 30)
    # 打乱一维数组顺序
    print('before random shuffle: ', a)
    np.random.shuffle(a)
    print('after random shuffle: ', a)
    ('before random shuffle: ', array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
           17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]))
    ('after random shuffle: ', array([10, 21, 26,  7,  0, 23,  2, 17, 18, 20, 12,  6,  9,  3, 25,  5, 13,
           14, 24, 29,  1, 28, 11, 15, 27, 16, 19,  4, 22,  8]))
    
    
    # 生成一维数组
    a = np.arange(0, 30)
    # 将一维数组转化成2维数组
    a = a.reshape(10, 3)
    # 打乱一维数组顺序
    print('before random shuffle: 
    {}'.format(a))
    np.random.shuffle(a)
    print('after random shuffle: 
    {}'.format(a))
    before random shuffle: 
    [[ 0  1  2]
     [ 3  4  5]
     [ 6  7  8]
     [ 9 10 11]
     [12 13 14]
     [15 16 17]
     [18 19 20]
     [21 22 23]
     [24 25 26]
     [27 28 29]]
    after random shuffle: 
    [[15 16 17]
     [12 13 14]
     [27 28 29]
     [ 3  4  5]
     [ 9 10 11]
     [21 22 23]
     [18 19 20]
     [ 0  1  2]
     [ 6  7  8]
     [24 25 26]]
    

    2.4 随机选取元素

    例12. 随机选取元素

    # 随机选取一选部分元素
    a = np.arange(30)
    b = np.random.choice(a, size=5)
    b
    array([ 0, 24, 12,  5,  4])
    

    3. 线性代数操作

    Numpy中实现了线性代数中常用的各种操作,并形成了numpy.linalg线性代数相关的模块。其中包括:

    • diag 以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0)
    • dot 矩阵乘法
    • trace 计算对角线元素的和
    • det 计算矩阵行列式
    • eig 计算方阵的特征值和特征向量
    • inv 计算方阵的逆

    例13. numpy的线性代数操作

    # 矩阵相乘
    a = np.arange(12)
    b = a.reshape([3, 4])
    c = a.reshape([4, 3])
    # 矩阵b的第二维大小,必须等于矩阵c的第一维大小
    d = b.dot(c) # 等价于 np.dot(b, c)
    print('a: 
    {}'.format(a))
    print('b: 
    {}'.format(b))
    print('c: 
    {}'.format(c))
    print('d: 
    {}'.format(d))
    a: 
    [ 0  1  2  3  4  5  6  7  8  9 10 11]
    b: 
    [[ 0  1  2  3]
     [ 4  5  6  7]
     [ 8  9 10 11]]
    c: 
    [[ 0  1  2]
     [ 3  4  5]
     [ 6  7  8]
     [ 9 10 11]]
    d: 
    [[ 42  48  54]
     [114 136 158]
     [186 224 262]]
    
    
    # numpy.linalg  中有一组标准的矩阵分解运算以及诸如求逆和行列式之类的东西
    # np.linalg.diag 以一维数组的形式返回方阵的对角线(或非对角线)元素,
    # 或将一维数组转换为方阵(非对角线元素为0)
    e = np.diag(d)
    f = np.diag(e)
    print('d: 
    {}'.format(d))
    print('e: 
    {}'.format(e))
    print('f: 
    {}'.format(f))
    d: 
    [[ 42  48  54]
     [114 136 158]
     [186 224 262]]
    e: 
    [ 42 136 262]
    f: 
    [[ 42   0   0]
     [  0 136   0]
     [  0   0 262]]
    
    
    # trace, 计算对角线元素的和
    g = np.trace(d)
    g
    440
    
    
    # det,计算行列式
    h = np.linalg.det(d)
    h
    1.3642420526593978e-11
    
    
    # eig,计算特征值和特征向量
    i = np.linalg.eig(d)
    i
    (array([4.36702561e+02, 3.29743887e+00, 3.13152204e-14]),
     array([[ 0.17716392,  0.77712552,  0.40824829],
            [ 0.5095763 ,  0.07620532, -0.81649658],
            [ 0.84198868, -0.62471488,  0.40824829]]))
    
    
    # inv,计算方阵的逆
    tmp = np.random.rand(3, 3)
    j = np.linalg.inv(tmp)
    j
    array([[-0.59449952,  1.39735912, -0.06654123],
           [ 1.56034184, -0.40734618, -0.48055062],
           [ 0.10659811, -0.62164179,  1.30437759]])
    

    4. Numpy保存与导入文件

    例14. numpy文件操作

    # 使用np.fromfile从文本文件'housing.data'读入数据
    # 这里要设置参数sep = ' ',表示使用空白字符来分隔数据
    # 空格或者回车都属于空白字符,读入的数据被转化成1维数组
    d = np.fromfile('./work/housing.data', sep = ' ')
    d
    array([6.320e-03, 1.800e+01, 2.310e+00, ..., 3.969e+02, 7.880e+00,
           1.190e+01])
    
    # Numpy还提供了save和load接口,直接将数组保存成文件(保存为.npy格式),或者从.npy文件中读取数组
    
    
    # 产生随机数组a
    a = np.random.rand(3,3)
    np.save('a.npy', a)
    
    
    # 从磁盘文件'a.npy'读入数组
    b = np.load('a.npy')
    
    

    5. Numpy应用举例

    5.1 计算激活函数

    例15. 计算激活函数

    使用ndarray数组可以很方便的构建数学函数,而且能利用其底层的矢量计算能力快速实现计算。神经网络中比较常用激活函数是Sigmoid和ReLU,其定义如下。

    下面使用numpy和matplotlib计算函数值并画出图形

    # ReLU和Sigmoid激活函数示意图
    import numpy as np
    # %matplotlib inline    # 在Jupyter notebook 中在图框中显示
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    
    #设置图片大小
    plt.figure(figsize=(8, 3))
    
    # x是1维数组,数组大小是从-10. 到10.的实数,每隔0.1取一个点
    x = np.arange(-10, 10, 0.1)
    # 计算 Sigmoid函数
    s = 1.0 / (1 + np.exp(- x))
    
    # 计算ReLU函数
    # clip 函数, x表示输入的值, a_min表示小于a_min都赋值为a_min; a_max同理; None表示不进行操作。
    y = np.clip(x, a_min = 0., a_max = None)
    
    #########################################################
    # 以下部分为画图程序
    
    # 设置两个子图窗口,将Sigmoid的函数图像画在左边
    # 121 表示 一行2列, 占第一列
    f = plt.subplot(121)
    # 画出函数曲线
    plt.plot(x, s, color='r')
    # 添加文字说明
    plt.text(-5., 0.9, r'$y=sigma(x)$', fontsize=13)
    # 设置坐标轴格式
    currentAxis=plt.gca()
    currentAxis.xaxis.set_label_text('x', fontsize=15)
    currentAxis.yaxis.set_label_text('y', fontsize=15)
    
    # 将ReLU的函数图像画在左边
    # 122 表示 一行2列, 占第二列
    f = plt.subplot(122)
    # 画出函数曲线
    plt.plot(x, y, color='g')
    # 添加文字说明
    plt.text(-3.0, 9, r'$y=ReLU(x)$', fontsize=13)
    # 设置坐标轴格式
    currentAxis=plt.gca()
    currentAxis.xaxis.set_label_text('x', fontsize=15)
    currentAxis.yaxis.set_label_text('y', fontsize=15)
    
    plt.show()
    
    

    5.2 图像处理

    例16. 图像翻转和裁剪

    图像是由像素点构成的矩阵,其数值可以用ndarray来表示。可以将上面章节中介绍的操作用在图像数据对应的ndarray上,并且通过图像直观的展示出它的效果来。

    # 导入需要的包
    # 后续会有教程解释 matplotlib 和 PIL 这两个库
    import numpy as np
    import matplotlib.pyplot as plt
    from PIL import Image
    
    # 读入图片
    image = Image.open('./car.jpg')    # 可改成绝对路径
    image = np.array(image)
    # 查看数据形状,其形状是[H, W, 3],
    # 其中H代表高度, W是宽度,3代表RGB三个通道
    plt.imshow(image)
    

    (612, 612, 3)

    # 垂直方向翻转
    # 这里使用数组切片的方式来完成,
    # 相当于将图片最后一行挪到第一行,
    # 倒数第二行挪到第二行,..., 
    # 第一行挪到倒数第一行
    # 对于行指标,使用::-1来表示切片,
    # 负数步长表示以最后一个元素为起点,向左走寻找下一个点
    # 对于列指标和RGB通道,仅使用:表示该维度不改变
    image2 = image[::-1, :, :]
    plt.imshow(image2)
    

    # 水平方向翻转
    image3 = image[:, ::-1, :]
    plt.imshow(image3)
    

    # 保存图片
    im3 = Image.fromarray(image3)
    im3.save('im3.jpg')
    
    #  高度方向裁剪
    H, W = image.shape[0], image.shape[1]
    # 注意此处用整除,H_start必须为整数
    H1 = H // 2 
    H2 = H
    image4 = image[H1:H2, :, :]
    plt.imshow(image4)
    

    # 调整亮度
    image6 = image * 0.5
    plt.imshow(image6.astype('uint8'))
    

    #间隔行列采样,图像尺寸会减半,清晰度变差
    image10 = image[::2, ::2, :]
    plt.imshow(image10)
    image10.shape
    

    (306, 306, 3)

  • 相关阅读:
    深入探究JVM之垃圾回收器
    深入探究JVM之对象创建及分配策略
    深入探究JVM之内存结构及字符串常量池
    【深度思考】如何优雅告知用户,网站正在升级维护?
    Redis系列(九):Redis的事务机制
    [C#.NET 拾遗补漏]07:迭代器和列举器
    [C#.NET 拾遗补漏]06:单例模式最佳实践
    深入理解 EF Core:使用查询过滤器实现数据软删除
    简化RESTful开发,Spring Data REST让你少掉发
    如何查看Docker容器环境变量,如何向容器传递环境变量
  • 原文地址:https://www.cnblogs.com/hp-lake/p/12108358.html
Copyright © 2011-2022 走看看