• NumPy 学习(2): 数组的操作


    1. 简单一维数组的操作

      一维数组的操作类似于python自身的list类型。

    In [14]: arr = np.arange(10)
    
    In [15]: arr
    Out[15]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    # 第六个元素值
    In [16]: arr[5]
    Out[16]: 5
    # 第6,,7,8这三个元素的值
    In [17]: arr[5:8]
    Out[17]: array([5, 6, 7])

      注意: 和list类型有很大的不同的是,操作原数组的子序列的时候,实际上就是操作原数组的数据。这就意味着数组中的数据没有被复制,任何在其子序列上的操作都会映射到原数组上。这是因为NumPy是被设计成处理大量数据的工具,如果采用复制的方式,其计算性能会大大折扣。

    In [18]: arr_slice = arr[:4]
    
    In [19]: arr_slice[:] = 20
    
    In [20]: arr_slice
    Out[20]: array([20, 20, 20, 20])
    # arr_slice中更改映射到了arr中
    In [21]: arr
    Out[21]: array([20, 20, 20, 20,  4,  5,  6,  7,  8,  9])

      如果要执行显示的复制操作可以通过条用copy()函数: arr[:3].copy

    2. 高维维数组上的操作

     2.1 二维数组索引访问:

    # 产生1-9的数
    In [28]: arr2d = np.arange(1,10).reshape((3,3)) In [29]: arr2d Out[29]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 访问第一行数据 In [30]: arr2d[0] Out[30]: array([1, 2, 3]) # 访问第一行第二个数据 In [31]: arr2d[0][1] Out[31]: 2 In [32]: arr2d[0,1] Out[32]: 2

      2.2 以划分(slice)的方式来取得部分数据:

      

      2.3 索引(index)访问和划分(slice)的不同

        索引是通过坐标定位数据的位置并获取其值,arr2d[[0,1],[0,1]] 实际上是获取(0,0),(1,1)位置上的数据,是获取交汇点上的数据。

        划分是将设定范围的数据提取出来,arr2d[:2, :2]实际上就是把1-2行与1-2列中的数据划分出来,是一个区域。

    In [67]: arr2d = np.arange(1,10).reshape(3,3)
    # 划分的方式划分数据
    In [68]: arr2d[:2, :2] Out[68]: array([[1, 2], [4, 5]]) # 以索引方式访问数据 In [69]: arr2d[[0,1],[0,1]] Out[69]: array([1, 5])

        将8 * 4 的一个二维数组的1,3,5,7行,和 4,3,2,1列重新组成一个二维数组。如果用以下方法,肯定是不行的:

    In [71]: arr = np.arange(32).reshape(8,4)
    
    In [72]: arr
    Out[72]: 
    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]])
    # 错误的做法,其实是获取(0,3),(2,2),(4,1),(6,0)位置上的值
    In [73]: arr[[0,2,4,6],[3,2,1,0]]
    Out[73]: array([ 3, 10, 17, 24])

        正确的方法:

    # 先获取1,3,5,7行的数据
    In [74]: arr_temp = arr[[0,2,4,6]] In [75]: arr_temp Out[75]: array([[ 0, 1, 2, 3], [ 8, 9, 10, 11], [16, 17, 18, 19], [24, 25, 26, 27]]) # 划分数组,并组成新的数组 In [76]: arr_temp[:,[3,2,1,0]] Out[76]: array([[ 3, 2, 1, 0], [11, 10, 9, 8], [19, 18, 17, 16], [27, 26, 25, 24]])

        实现此功能还可以调用np.ix_() 函数:

    In [77]: arr[np.ix_([0,2,4,6],[3,2,1,0])]
    Out[77]: 
    array([[ 3,  2,  1,  0],
           [11, 10,  9,  8],
           [19, 18, 17, 16],
           [27, 26, 25, 24]])

      2.4 高维数组访问:

    # 用reshape生成三维数组
    In [33]: arr3d = np.arange(1,13).reshape((2,2,3)) In [34]: arr3d Out[34]: array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]]) # 用传统的array函数生成三维数组 In [35]: arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) In [36]: arr3d Out[36]: array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]]) # arr3d[0]是一个2*3的数组 In [37]: arr3d[0] Out[37]: array([[1, 2, 3], [4, 5, 6]]) # arr3d[0,0]是一个一维数组 In [38]: arr3d[0,0] Out[38]: array([1, 2, 3]) In [39]: arr3d[0,0,0] Out[39]: 1

      2.5 数组赋值操作:

    # 第一个2 * 3 数组的值全变为 32
    In [40]: arr3d[0] = 32 In [41]: arr3d Out[41]: array([[[32, 32, 32], [32, 32, 32]], [[ 7, 8, 9], [10, 11, 12]]]) In [42]: old_values = arr3d[0] # 将一个2 *3 的数组赋给arr3d[0] In [43]: arr3d[0] = old_values In [44]: arr3d Out[44]: array([[[32, 32, 32], [32, 32, 32]], [[ 7, 8, 9], [10, 11, 12]]])


    3. 布尔索引
      数据准备:

    # 七个名字
    In [2]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) In [3]: names Out[3]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='|S4') # 生成7行,4列的随机数组,每一行对应names中一个人的数据 In [4]: data = randn(7,4) In [5]: data Out[5]: array([[ 0.54643196, 0.98876451, 1.55499825, 1.88240798], [ 1.39695977, -1.59576937, 0.42445372, 1.73588157], [ 0.61992879, -0.13706965, 1.87869165, 1.28724149], [ 0.59114346, -0.50032077, 1.29182197, 0.54644327], [ 0.59344412, -0.06566168, -0.01759809, 0.22191015], [-1.57663889, -0.08607805, -0.36048361, -0.94029737], [-0.32203015, 0.59462972, 1.10737098, -1.9473386 ]])

      用布尔数组筛选二维数组的行,布尔数组的大小和二维数组的行数要相同


    In [12]: names=="Bob" Out[12]: array([ True, False, False, True, False, False, False], dtype=bool)
    # 选取 Bob 的数据 In [
    13]: data[names == "Bob"] Out[13]: array([[ 0.54643196, 0.98876451, 1.55499825, 1.88240798], [ 0.59114346, -0.50032077, 1.29182197, 0.54644327]])

      布尔索引和普通索引混合使用:

    In [13]: data[names == "Bob"]
    Out[13]: 
    array([[ 0.54643196,  0.98876451,  1.55499825,  1.88240798],
           [ 0.59114346, -0.50032077,  1.29182197,  0.54644327]])
    
    In [14]: data[names == "Bob",2:]
    Out[14]: 
    array([[ 1.55499825,  1.88240798],
           [ 1.29182197,  0.54644327]])

      “与或非“操作。 python 中的 and , or 等关键字在这里不能实现

    # 或操作
    In [20]: (names == 'Bob') | (names == 'Will')
    Out[20]: array([ True, False,  True,  True,  True, False, False], dtype=bool)
    # 与操作
    In [21]: (names == 'Bob') & (names == 'Will')
    Out[21]: array([False, False, False, False, False, False, False], dtype=bool)
    # 下边两种 非操作
    In [22]: names != "Bob"
    Out[22]: array([False,  True,  True, False,  True,  True,  True], dtype=bool)

    In [23]: -(names == "Bob")
    Out[23]: array([False,  True,  True, False,  True,  True,  True], dtype=bool)


      二维布尔类型索引:

    In [24]: data < 0
    Out[24]: 
    array([[False, False, False, False],
           [False,  True, False, False],
           [False,  True, False, False],
           [False,  True, False, False],
           [False,  True,  True, False],
           [ True,  True,  True,  True],
           [ True, False, False,  True]], dtype=bool)
    # 将小于0的元素的值改为0
    In [25]: data[ data < 0] = 0
    
    In [26]: data
    Out[26]: 
    array([[ 0.54643196,  0.98876451,  1.55499825,  1.88240798],
           [ 1.39695977,  0.        ,  0.42445372,  1.73588157],
           [ 0.61992879,  0.        ,  1.87869165,  1.28724149],
           [ 0.59114346,  0.        ,  1.29182197,  0.54644327],
           [ 0.59344412,  0.        ,  0.        ,  0.22191015],
           [ 0.        ,  0.        ,  0.        ,  0.        ],
           [ 0.        ,  0.59462972,  1.10737098,  0.        ]])

     

  • 相关阅读:
    前端开发者也可以酷酷地开发桌面程序
    手把手教你怎么搭建angular+gulp的项目(一)
    在Angular中,如果权限值是异步请求所得,如何将其设置为HTTP请求头的Authorization?
    AngularJs ng-repeat指令中怎么实现含有自定义指令的动态html
    第一篇随笔,练练手
    我参与 Seata 开源项目的一些感悟
    一次 kafka 消息堆积问题排查
    图解 Kafka 水印备份机制
    Seata 动态配置订阅与降级实现原理
    记一次 Kafka 集群线上扩容
  • 原文地址:https://www.cnblogs.com/linux-wangkun/p/5897030.html
Copyright © 2020-2023  润新知