• NumPy-快速处理数据--ndarray对象--数组的创建和存取


    本文摘自《用Python做科学计算》,版权归原作者所有。

    NumPy为Python提供了快速的多维数组处理的能力,而SciPy则在NumPy基础上添加了众多的科学计算所需的各种工具包,有了这两个库,Python就有几乎和Matlab一样的处理数据和计算的能力了。可以直接按照书中写的下载Python(x,y),也可以单独配置各个模块。配置方法见:Numpy、SciPy、MatPlotLib在Python2.7.9下的安装与配置

    一、为什么需要Numpy处理数据?

    1. 标准安装的Python中用列表(list)可以用来当作数组使用,但是列表中所保存的是对象(任意对象)的指针。对于数值运算来说这种结构显然比较浪费内存和CPU计算时间。

    2. Python还提供了一个array模块,array对象和列表不同,它直接保存数值。但是由于它只支持一维数组,也没有各种运算函数,因此也不适合做数值运算。

    NumPy提供了两种基本的对象,解决标准Python的不足:

    • ndarray(N-dimensional array object)N维数组(简称数组)对象,存储单一数据类型的N维数组
    • ufunc(universal function object)通用函数对象,对数组进行处理的函数。

    二、ndarray对象

    函数库导入:

    1 import numpy as np#给numpy其一个别名叫np

    2.1 创建数组

    2.1.1 创建一维数组:

    1  a = np.array([1, 2, 3, 4])#方法一,使用列表
    2  b = np.array((1, 2, 3, 4))#方法二,只用元组

    2.1.2 创建二维数组:

    1 c = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])#每一行用中括号括起来

    2.1.3 shape属性获取数组大小:

    1 >>> a.shape
    2 (4,)        #一个数字表示一维数组
    3 >>> c.shape
    4 (3, 4)     #两个数字表示二维数组,第0轴长度为3,第1轴长度为4

    2.1.4 修改shape属性:

     1 >>> c.shape = 4,3  #将数组改为4行3列
     2 >>> c              #注意不是对数组转置,只是改变每个轴的大小,数组元素在内存中的位置并没有改变
     3 array([[ 1,  2,  3],
     4        [ 4,  5,  6],
     5        [ 7,  8,  9],
     6        [10, 11, 12]])
     7 >>> c.shape
     8 (4, 3)
     9 >>> c.shape = 2, -1#第二个参数设置为-1系统会自动计算第二个参数
    10 >>> c
    11 array([[ 1,  2,  3,  4,  5,  6],
    12        [ 7,  8,  9, 10, 11, 12]])

    2.1.5 reshape方法,返回一个改变了尺寸的新数组,原数组的shape保持不变:

     1 >>> d = a.reshape((2, 2))
     2 >>> d
     3 array([[1, 2],
     4        [3, 4]])
     5 >>> a
     6 array([1, 2, 3, 4])
     7 >>> a[0] = 100     #a和d共享同一块内存,修改a[0]也会改变d[0, 0]
     8 >>> d
     9 array([[100,   2],
    10        [  3,   4]])

    2.1.6 dtype属性创建浮点数组,复数数组

    1 >>> np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.float)#默认dtype=int32,即默认创建数组元素是整数,并且32位长整型
    2 array([[  1.,   2.,   3.,   4.],
    3        [  5.,   6.,   7.,   8.],
    4        [  9.,  10.,  11.,  12.]])
    5 >>> np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.complex)#创建复数数组
    6 array([[  1.+0.j,   2.+0.j,   3.+0.j,   4.+0.j],
    7        [  5.+0.j,   6.+0.j,   7.+0.j,   8.+0.j],
    8        [  9.+0.j,  10.+0.j,  11.+0.j,  12.+0.j]])

    以上介绍的数组创建的方法都是先创建序列,在使用array()函数转化为数组,下面介绍使用专门的函数创建数组:

    2.1.7 arange(开始值, 终值, 步长):类似Python的range(),注意不包括终值

    1 >>> np.arange(0, 1, 0.1)#不包括终值!!!
    2 array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

    2.1.8 linspace(开始值, 终值, 元素个数): 默认包括终值,可以使用endpoint设置是否包括终值

    1 >>> np.linspace(0, 1, 8)#0~1之间,8个元素
    2 array([ 0.        ,  0.14285714,  0.28571429,  0.42857143,  0.57142857,
    3         0.71428571,  0.85714286,  1.        ])

    2.1.9 logspace(开始值, 终值, 元素个数): 创建等比数列,下面的例子产生1(10^0)到100(10^2)、有10个元素的等比数列:

    1 >>> np.logspace(0, 2, 10)
    2 array([   1.        ,    1.66810054,    2.7825594 ,    4.64158883,
    3           7.74263683,   12.91549665,   21.5443469 ,   35.93813664,
    4          59.94842503,  100.        ])

    2.1.10 fromstring(字符串, dtype=?):从字节创建数组

    1 >>> np.fromstring(s, dtype=np.int8)#字符对应的ASCII码
    2 array([ 97,  98,  99, 100, 101, 102, 103], dtype=int8)

    2.1.11 fromfunction(计算每个数组元素的函数, 数组大小即shape)

     1 >>> def func1(i):
     2         return i%4+1
     3 >>> np.fromfunction(func1, (10,))#第二个参数必须是一个序列,本例中用(10,)创建一个10元素的一维数组
     4 array([ 1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.,  1.,  2.])
     5 #创建一个二维数组表示九九乘法表
     6 >>> def func2(i, j):
     7         return (i+1) * (j+1)
     8 >>> np.fromfunction(func2, (9, 9))
     9 array([[  1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.],
    10        [  2.,   4.,   6.,   8.,  10.,  12.,  14.,  16.,  18.],
    11        [  3.,   6.,   9.,  12.,  15.,  18.,  21.,  24.,  27.],
    12        [  4.,   8.,  12.,  16.,  20.,  24.,  28.,  32.,  36.],
    13        [  5.,  10.,  15.,  20.,  25.,  30.,  35.,  40.,  45.],
    14        [  6.,  12.,  18.,  24.,  30.,  36.,  42.,  48.,  54.],
    15        [  7.,  14.,  21.,  28.,  35.,  42.,  49.,  56.,  63.],
    16        [  8.,  16.,  24.,  32.,  40.,  48.,  56.,  64.,  72.],
    17        [  9.,  18.,  27.,  36.,  45.,  54.,  63.,  72.,  81.]])

    2.2 存取元素

    2.2.1 数组的存取方法与Python的标准方法相同

     1 >>> a = np.arange(10)
     2 >>> a[5]    # 用整数作为下标可以获取数组中的某个元素
     3 5
     4 >>> a[3:5]  # 用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]
     5 array([3, 4])
     6 >>> a[:5]   # 省略开始下标,表示从a[0]开始
     7 array([0, 1, 2, 3, 4])
     8 >>> a[:-1]  # 下标可以使用负数,表示从数组后往前数
     9 array([0, 1, 2, 3, 4, 5, 6, 7, 8])
    10 >>> a[2:4] = 100,101    # 下标还可以用来修改元素的值
    11 >>> a
    12 array([  0,   1, 100, 101,   4,   5,   6,   7,   8,   9])
    13 >>> a[1:-1:2] # 范围中的第三个参数表示步长,2表示隔一个元素取一个元素
    14 array([  1, 101,   5,   7])
    15 >>> a[::-1]   # 省略范围的开始下标和结束下标,步长为-1,整个数组头尾颠倒
    16 array([  9,   8,   7,   6,   5,   4, 101, 100,   1,   0])
    17 >>> a[5:1:-2] # 步长为负数时,开始下标必须大于结束下标
    18 array([  5, 101])

    和Python的列表序列不同,通过下标范围获取的新的数组是原始数组的一个视图。它与原始数组共享同一块数据空间:

    1 >>> b = a[3:7] # 通过下标范围产生一个新的数组b,b和a共享同一块数据空间
    2 >>> b
    3 array([101,   4,   5,   6])
    4 >>> b[2] = -10 # 将b的第2个元素修改为-10
    5 >>> b
    6 array([101,   4, -10,   6])
    7 >>> a # a的第5个元素也被修改为10
    8 array([  0,   1, 100, 101,   4, -10,   6,   7,   8,   9])

    除了使用下表范围存取元素之外,NumPy还提供了两种存取元素的高级方法。

    2.2.2 使用整数序列

    当使用整数序列对数组元素进行存取时,将使用整数序列中的每个元素作为下标,整数序列可以是列表(如第4行)或者数组(如第6行)。使用整数序列作为下标获得的数组不和原始数组共享数据空间。

     1 >>> x = np.arange(10,1,-1)
     2 >>> x
     3 array([10,  9,  8,  7,  6,  5,  4,  3,  2])
     4 >>> x[[3, 3, 1, 8]] # 获取x中的下标为3, 3, 1, 8的4个元素,组成一个新的数组
     5 array([7, 7, 9, 2])
     6 >>> b = x[np.array([3,3,-3,8])]  #np.array(序列)作用是将序列转化为数组,下标可以是负数
     7 >>> b[2] = 100
     8 >>> b
     9 array([7, 7, 100, 2])
    10 >>> x   # 由于b和x不共享数据空间,因此x中的值并没有改变
    11 array([10,  9,  8,  7,  6,  5,  4,  3,  2])
    12 >>> x[[3,5,1]] = -1, -2, -3 # 整数序列下标也可以用来修改元素的值
    13 >>> x
    14 array([10, -3,  8, -1,  6, -2,  4,  3,  2])

    2.2.3 使用布尔数组

    当使用布尔数组b作为下标存取数组x中的元素时,将收集数组x中所有在数组b中对应下标为True的元素。使用布尔数组作为下标获得的数组不和原始数组共享数据空间,注意这种方式只对应于布尔数组,不能使用布尔列表。

     1 >>> x = np.arange(5,0,-1)
     2 >>> x
     3 array([5, 4, 3, 2, 1])
     4 >>> x[np.array([True, False, True, False, False])]
     5 >>> # 下标为True的取出来,布尔数组中下标为0,2的元素为True,因此获取x中下标为0,2的元素
     6 array([5, 3])
     7 >>> x[[True, False, True, False, False]]#Error,这不是我们想要的结果
     8 >>> # 如果是布尔列表,则把True当作1, False当作0,按照整数序列方式获取x中的元素
     9 array([4, 5, 4, 5, 5])
    10 >>> x[np.array([True, False, True, True])]
    11 >>> # 布尔数组的长度不够时,不够的部分都当作False
    12 array([5, 3, 2])
    13 >>> x[np.array([True, False, True, True])] = -1, -2, -3#只修改下标为True的元素
    14 >>> # 布尔数组下标也可以用来修改元素
    15 >>> x
    16 array([-1,  4, -2, -3,  1])

    布尔数组一般不是手工产生,而是使用布尔运算的ufunc函数产生,关于ufunc函数请参照 ufunc运算 一节。

     1 >>> x = np.random.rand(10) # 产生一个长度为10,元素值为0-1的随机数的数组
     2 >>> x
     3 array([ 0.72223939,  0.921226  ,  0.7770805 ,  0.2055047 ,  0.17567449,
     4         0.95799412,  0.12015178,  0.7627083 ,  0.43260184,  0.91379859])
     5 >>> x>0.5
     6 >>> # 数组x中的每个元素和0.5进行大小比较,得到一个布尔数组,True表示x中对应的值大于0.5
     7 array([ True,  True,  True, False, False,  True, False,  True, False,  True], dtype=bool)
     8 >>> x[x>0.5]# x>0.5是一个布尔数组
     9 >>> # 使用x>0.5返回的布尔数组收集x中的元素,因此得到的结果是x中所有大于0.5的元素的数组
    10 array([ 0.72223939,  0.921226  ,  0.7770805 ,  0.95799412,  0.7627083 ,
    11         0.91379859])
    http://www.cnblogs.com/moon1992/
  • 相关阅读:
    【练习】flushback基于时间的闪回查询
    【练习】审计
    【练习】新建虚拟机
    织梦安全防护教程首页被挟持、被串改、被挂马、被入侵之后如何解决?
    织梦手机站下一篇变上一篇而且还出错Request Error!
    织梦图集上传错误提示ERROR: Upload Error!
    织梦炒鸡简单3部曲修改文档标题长度限制
    织梦dede:arclist和dede:list输出每个文章的内容有多少页
    织梦后台管理模板无法正常显示模板文件列表解决方法
    织梦列表页多种属性排序[ajax]-支持select方式和降序升序切换
  • 原文地址:https://www.cnblogs.com/moon1992/p/4946114.html
Copyright © 2020-2023  润新知