• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    NumPy实现ndarray多维数组操作

    简介

    NumPy一个非常重要的作用就是可以进行多维数组的操作,多维数组对象也叫做ndarray。我们可以在ndarray的基础上进行一系列复杂的数学运算。

    本文将会介绍一些基本常见的ndarray操作,大家可以在数据分析中使用。

    创建ndarray

    创建ndarray有很多种方法,我们可以使用np.random来随机生成数据:

    import numpy as np
    # Generate some random data
    data = np.random.randn(2, 3)
    data
    
    array([[ 0.0929,  0.2817,  0.769 ],
           [ 1.2464,  1.0072, -1.2962]])
    

    除了随机创建之外,还可以从list中创建:

    data1 = [6, 7.5, 8, 0, 1]
    arr1 = np.array(data1)
    array([6. , 7.5, 8. , 0. , 1. ])
    

    从list中创建多维数组:

    data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
    arr2 = np.array(data2)
    array([[1, 2, 3, 4],
           [5, 6, 7, 8]])
    

    使用np.zeros创建初始值为0的数组:

    np.zeros(10)
    array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
    

    创建2维数组:

    np.zeros((3, 6))
    array([[0., 0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0., 0.]])
    

    使用empty创建3维数组:

    np.empty((2, 3, 2))
    array([[[0., 0.],
            [0., 0.],
            [0., 0.]],
    
           [[0., 0.],
            [0., 0.],
            [0., 0.]]])
    
    

    注意,这里我们看到empty创建的数组值为0,其实并不是一定的,empty会从内存中随机挑选空间来返回,并不能保证这些空间中没有值。所以我们在使用empty创建数组之后,在使用之前,还要记得初始化他们。

    使用arange创建范围类的数组:

    np.arange(15)
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
    

    指定数组中元素的dtype:

    arr1 = np.array([1, 2, 3], dtype=np.float64)
    arr2 = np.array([1, 2, 3], dtype=np.int32)
    

    ndarray的属性

    可以通过data.shape获得数组的形状。

    data.shape
    (2, 3)
    

    通过ndim获取维数信息:

    arr2.ndim
    2
    

    可以通过data.dtype获得具体的数据类型。

    data.dtype
    dtype('float64')
    

    ndarray中元素的类型转换

    在创建好一个类型的ndarray之后,还可以对其进行转换:

    arr = np.array([1, 2, 3, 4, 5])
    arr.dtype
    dtype('int64')
    
    float_arr = arr.astype(np.float64)
    float_arr.dtype
    dtype('float64')
    
    

    上面我们使用astype将int64类型的ndarray转换成了float64类型的。

    如果转换类型的范围不匹配,则会自动进行截断操作:

    arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
    arr.astype(np.int32)
    
    array([ 3, -1, -2,  0, 12, 10], dtype=int32)
    
    

    注意,这里是把小数截断,并没有向上或者向下取整。

    ndarray的数学运算

    数组可以和常量进行运算,也可以和数组进行运算:

    arr = np.array([[1., 2., 3.], [4., 5., 6.]])
    
    arr * arr
    
    array([[ 1.,  4.,  9.],
           [16., 25., 36.]])
    
    arr + 10
    
    array([[11., 12., 13.],
           [14., 15., 16.]])
    
    arr - arr
    
    array([[0., 0., 0.],
           [0., 0., 0.]])
    
    1 / arr
    
    array([[1.    , 0.5   , 0.3333],
           [0.25  , 0.2   , 0.1667]])
    
    arr ** 0.5
    
    array([[1.    , 1.4142, 1.7321],
           [2.    , 2.2361, 2.4495]])
    
    

    数组之间还可以进行比较,比较的是数组中每个元素的大小:

    arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
    
    arr2 > arr
    
    array([[False,  True, False],
           [ True, False,  True]])
    
    

    index和切片

    基本使用

    先看下index和切片的基本使用,index基本上和普通数组的使用方式是一样的,用来访问数组中某一个元素。

    切片要注意的是切片后返回的数组中的元素是原数组中元素的引用,修改切片的数组会影响到原数组。

    # 构建一维数组
    arr = np.arange(10)
    
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    # index访问
    arr[5]
    5
    
    # 切片访问
    arr[5:8]
    array([5, 6, 7])
    
    # 切片修改
    arr[5:8] = 12
    array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])
    
    # 切片可以修改原数组的值
    arr_slice = arr[5:8]
    arr_slice[1] = 12345
    arr
    
    array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,
               9])
    
    # 构建二维数组
    arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    arr2d[2]
    
    array([7, 8, 9])
    
    # index 二维数组
    arr2d[0][2]
    3
    
    # index二维数组
    arr2d[0, 2]
    3
    
    # 构建三维数组
    arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
    arr3d
    
    array([[[ 1,  2,  3],
            [ 4,  5,  6]],
    
           [[ 7,  8,  9],
            [10, 11, 12]]])
    
    # index三维数组
    arr3d[0]
    
    array([[1, 2, 3],
           [4, 5, 6]])
    
    # copy是硬拷贝,和原数组的值相互不影响
    old_values = arr3d[0].copy()
    arr3d[0] = 42
    
    arr3d
    
    array([[[42, 42, 42],
            [42, 42, 42]],
    
           [[ 7,  8,  9],
            [10, 11, 12]]])
    
    arr3d[0] = old_values
    arr3d
    
    array([[[ 1,  2,  3],
            [ 4,  5,  6]],
    
           [[ 7,  8,  9],
            [10, 11, 12]]])
    
    # index 三维数组
    arr3d[1, 0]
    
    array([7, 8, 9])
    
    x = arr3d[1]
    x
    
    array([[ 7,  8,  9],
           [10, 11, 12]])
    
    x[0]
    
    array([7, 8, 9])

    index with slice

    slice还可以作为index使用,作为index使用表示的就是一个index范围值。

    作为index表示的slice可以有多种形式。

    有头有尾的,表示index从1开始到6-1结束:

    arr[1:6]
    array([ 1,  2,  3,  4, 64])
    

    无头有尾的,表示index从0开始,到尾-1结束:

    arr2d[:2]
    array([[1, 2, 3],
           [4, 5, 6]])
    

    有头无尾的,表示从头开始,到所有的数据结束:

    arr2d[:2, 1:]
    array([[2, 3],
           [5, 6]])
    arr2d[1, :2]
    array([4, 5])
    

    boolean index

    index还可以使用boolean值,表示是否选择这一个index的数据。

    我们先看下怎么构建一个boolean类型的数组:

    names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
    names == 'Bob'
    
    array([ True, False, False,  True, False, False, False])
    
    

    上面我们通过比较的方式返回了一个只包含True和False的数组。

    这个数组可以作为index值来访问数组:

    #  构建一个7 * 4 的数组
    data = np.random.randn(7, 4)
    
    array([[ 0.275 ,  0.2289,  1.3529,  0.8864],
           [-2.0016, -0.3718,  1.669 , -0.4386],
           [-0.5397,  0.477 ,  3.2489, -1.0212],
           [-0.5771,  0.1241,  0.3026,  0.5238],
           [ 0.0009,  1.3438, -0.7135, -0.8312],
           [-2.3702, -1.8608, -0.8608,  0.5601],
           [-1.2659,  0.1198, -1.0635,  0.3329]])
    
    # 通过boolean数组来访问:
    data[names == 'Bob']
    array([[ 0.275 ,  0.2289,  1.3529,  0.8864],
           [-0.5771,  0.1241,  0.3026,  0.5238]])
    
    

    在索引行的时候,还可以索引列:

    data[names == 'Bob', 3]
    array([0.8864, 0.5238])
    

    可以用 ~符号来取反:

    data[~(names == 'Bob')]
    array([[-2.0016, -0.3718,  1.669 , -0.4386],
           [-0.5397,  0.477 ,  3.2489, -1.0212],
           [ 0.0009,  1.3438, -0.7135, -0.8312],
           [-2.3702, -1.8608, -0.8608,  0.5601],
           [-1.2659,  0.1198, -1.0635,  0.3329]])
    
    

    我们可以通过布尔型数组设置值,在实际的项目中非常有用:

    data[data  0] = 0
    array([[0.275 , 0.2289, 1.3529, 0.8864],
           [0.    , 0.    , 1.669 , 0.    ],
           [0.    , 0.477 , 3.2489, 0.    ],
           [0.    , 0.1241, 0.3026, 0.5238],
           [0.0009, 1.3438, 0.    , 0.    ],
           [0.    , 0.    , 0.    , 0.5601],
           [0.    , 0.1198, 0.    , 0.3329]])
    
    data[names != 'Joe'] = 7
    array([[7.    , 7.    , 7.    , 7.    ],
           [0.    , 0.    , 1.669 , 0.    ],
           [7.    , 7.    , 7.    , 7.    ],
           [7.    , 7.    , 7.    , 7.    ],
           [7.    , 7.    , 7.    , 7.    ],
           [0.    , 0.    , 0.    , 0.5601],
           [0.    , 0.1198, 0.    , 0.3329]])
    
    

    Fancy indexing

    Fancy indexing也叫做花式索引,它是指使用一个整数数组来进行索引。

    举个例子,我们先创建一个 8 * 4的数组:

    arr = np.empty((8, 4))
    for i in range(8):
        arr[i] = i
    arr
    array([[0., 0., 0., 0.],
           [1., 1., 1., 1.],
           [2., 2., 2., 2.],
           [3., 3., 3., 3.],
           [4., 4., 4., 4.],
           [5., 5., 5., 5.],
           [6., 6., 6., 6.],
           [7., 7., 7., 7.]])
    

    然后使用一个整数数组来索引,那么将会以指定的顺序来选择行:

    arr[[4, 3, 0, 6]]
    array([[4., 4., 4., 4.],
           [3., 3., 3., 3.],
           [0., 0., 0., 0.],
           [6., 6., 6., 6.]])
    

    还可以使用负值来索引:

    arr[[-3, -5, -7]]
    array([[5., 5., 5., 5.],
           [3., 3., 3., 3.],
           [1., 1., 1., 1.]])
    

    花式索引还可以组合来使用:

    arr = np.arange(32).reshape((8, 4))
    arr
    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, 30, 31]])
    

    上面我们构建了一个8 * 4的数组。

    arr[[1, 5, 7, 2], [0, 3, 1, 2]]
    array([ 4, 23, 29, 10])
    

    然后取他们的第2列的第一个值,第6列的第三个值等等。最后得到一个1维的数组。

    数组变换

    我们可以在不同维度的数组之间进行变换,还可以转换数组的轴。

    reshape方法可以将数组转换成为任意的形状:

    arr = np.arange(15).reshape((3, 5))
    arr
    array([[ 0,  1,  2,  3,  4],
           [ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14]])
    

    数组还提供了一个T命令,可以将数组的轴进行对调:

    arr.T
    array([[ 0,  5, 10],
           [ 1,  6, 11],
           [ 2,  7, 12],
           [ 3,  8, 13],
           [ 4,  9, 14]])
    

    对于高维数组,可以使用transpose来进行轴的转置:

    arr = np.arange(16).reshape((2, 2, 4))
    arr
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7]],
    
           [[ 8,  9, 10, 11],
            [12, 13, 14, 15]]])
            
    arr.transpose((1, 0, 2))
    array([[[ 0,  1,  2,  3],
            [ 8,  9, 10, 11]],
    
           [[ 4,  5,  6,  7],
            [12, 13, 14, 15]]])
    
    

    上面的transpose((1, 0, 2)) 怎么理解呢?

    其含义是将x,y轴对调,z轴保持不变。

    上面我们通过使用reshape((2, 2, 4))方法创建了一个3维,也就是3个轴的数组。 其shape是 2 * 2 * 4 。

    先看下对应关系:

    (0,0)-》 [ 0, 1, 2, 3]

    (0,1)-》 [ 4, 5, 6, 7]

    (1,0)-》 [ 8, 9, 10, 11]

    (1,1)-》 [12, 13, 14, 15]

    转换之后:

    (0,0)-》 [ 0, 1, 2, 3]

    (0,1)-》 [ 8, 9, 10, 11]

    (1,0)-》[ 4, 5, 6, 7]

    (1,1)-》 [12, 13, 14, 15]

    于是得到了我们上面的的结果。

    多维数组的轴转换可能比较复杂,大家多多理解。

    还可以使用 swapaxes 来交换两个轴,上面的例子可以重写为:

    arr.swapaxes(0,1)

    到此这篇关于NumPy实现ndarray多维数组操作的文章就介绍到这了,更多相关NumPy ndarray多维数组操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • numpy 声明空数组详解
    • Numpy将二维数组添加到空数组的实现
    • 在NumPy中创建空数组/矩阵的方法
    • 如何在向量化NumPy数组上进行移动窗口
    • 如何将numpy二维数组中的np.nan值替换为指定的值
    • 解决numpy数组互换两行及赋值的问题
    • python 将numpy维度不同的数组相加相乘操作
    • python numpy.power()数组元素求n次方案例
    • Python 用NumPy创建二维数组的案例
    • Numpy ndarray 多维数组对象的使用
    • 浅谈Python numpy创建空数组的问题
    上一篇:Python基础之logging模块知识总结
    下一篇:python scipy.misc.imsave()函数的用法说明
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    NumPy实现ndarray多维数组操作 NumPy,实现,ndarray,多维,数组,