zoukankan      html  css  js  c++  java
  • 一、Numpy基础--数组

    (一)Numpy数组对象

    Numpy中的nadrray是一个多维数组对象,该对象由两部分组成:

    • 实际的数据
    • 描述这些数据的元数据

    大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据。

    数组的数据类型:

    In: a = arange(5)
    In: a.dtype
    Out: dtype('int64')

    数组的维度:

    In [4]: a
    Out[4]: array([0, 1, 2, 3, 4])
    In: a.shape
    Out: (5,)

    数组的shape属性返回一个元组(tuple),元组中的元素即为NumPy数组每一个维度上的大小。上面例子中的数组是一维的,

    因此元组中只有一个元素。

    (二)动手实践:创建多维数组

    创建一个多维数组

    显示该数组的维度

    In: m = array([arange(2), arange(2)])
    In: m
    Out:
    array([[0, 1],
              [0, 1]])

    In: m.shape
    Out: (2, 2)

    我们将arange函数创建的数组作为列表元素,把这个列表作为参数传给array函数。

    array函数可以依据给定的对象生成数组。给定的对象应该是类数组,如Python中的列表。

    (1)选取数组元素

    In: a = array([[1,2],[3,4]])
    In: a
    Out:
    array([[1, 2],
        [3, 4]])

    在创建这个多维数组时,我们给array函数传递的对象是一个嵌套的列表。

    数组的下标是从0开始的。

    In: a[0,0]
    Out: 1

    In: a[1,1]
    Out: 4

    (2)Numpy数据类型

    a.每一种数据类型均有对应的类型转换函数

    In: float64(42)
    Out: 42.0
    In: int8(42.0)
    Out: 42
    In: bool(42)
    Out: True
    In: bool(0)
    Out: False
    In: bool(42.0)
    Out: True
    In: float(True)
    Out: 1.0
    In: float(False)
    Out: 0.0

    b.许多函数的参数中可以指定数据类型,通常这个参数是可选的:

    In: arange(7, dtype=uint16)
    Out: array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)

    注意:

    a.复数是不能转换为整数的

    b.复数也不能转换为浮点数

    c.浮点数可以转换为复数

    (3)数据类型对象

    数据类型对象是numpy.dtype类的实例。

    数据类型对象可以给出单个数组元素在内存中占用的字节数,即dtype的itemsize属性:

    In: a.dtype.itemsize
    Out: 8

    (4)字符编码

    Numpy可以使用字符编码来表示数据类型,这是为了兼容NumPy的前身Numeric。

    不推荐使用字符编码,应该优先使用dtype对象来表示数据类型。

    但有时会用到,因此下面列出了字符编码的对应表。

    下面的编码创建了一个单精度浮点数组:

    In: arange(7, dtype='f')
    Out: array([ 0., 1., 2., 3., 4., 5., 6.], dtype=float32)

    (5)自定义数据类型

    我们有很多可以自定义数据类型的方法,以浮点型为例:

    • 可以使用python中的浮点数类型

    In: dtype(float)
    Out: dtype('float64')

    • 可以使用字符编码来指定单精度浮点数类型

    In: dtype('f')
    Out: dtype('float32')

    • 可以将两个字符作为参数传给数据类型的构造函数,此时:

    第一个字符表示数据类型,第二个字符表示该类型在内存中占用的字节数(2,4,8分别代表精度为16,32,64位)

    In: dtype('f8')
    Out: dtype('float64')

    完整的的Numpy数据类型列表可以在sctypeDict.keys()中找到:

    In: sctypeDict.keys()
    Out: [0, ...
    'i2',
    'int0']

    (6)dtype类的属性

    • 获取数据类型的字符编码:char属性

    In: t = dtype('Float64')
    In: t.char
    Out: 'd'

    • 数组元素的数据类型:type属性

    In: t.type
    Out: <type 'numpy.float64'>

    • 给出数据类型的字符串表示:str属性

    该字符串的首个字符表示字节序(endianness),后面如果还有字符的话,将是一个字符编码,接着一个数字表示每个数组元素存储所需的字节数。

    字节序是指长为32或64的字(word)存储的顺序:

    大端序(big-endian):是将最高位字节存储在最低的内存地址处,用>表示;

    小端序(little-endian):是将最低位字节存储在最低的内存地址处,用<表示.

    In: t.str
    Out: '<f8'

    (三)动手实践:创建自定义数据类型

    自定义数据类型是一种异构数据类型,可以当做用来记录电子表格或数据库中一行数据的结构。

    (1)创建数据类型

    In: t = dtype([(,name', str_, 40), ('numitems', int32), ('price',float32)])
    In: t
    Out: dtype([('name', '|S40'), ('numitems', '<i4'), ('price', '<f4')])

    (2)查看数据类型(也可以查看某一字段数据类型)

    In: t['name']
    Out: dtype('|S40')

    (3)创建自定义数据类型的数组

    In: itemz = array([('Meaning of life DVD', 42, 3.14), ('Butter', 13, 2.72)], dtype=t)
    In: itemz[1]
    Out: ('Butter', 13, 2.7200000286102295)

    必须在参数中指定数据类型,否则将触发TypeError错误

    (四)一维数组的索引和切片

    • 用下标3~7来选取元素3~6:

    In: a = arange(9)
    In: a[3:7]
    Out: array([3, 4, 5, 6])

    • 以2为步长选取元素:

    In: a[:7:2]
    Out: array([0, 2, 4, 6])

    • 利用负数下标翻转数组:

    In: a[::-1]
    Out: array([8, 7, 6, 5, 4, 3, 2, 1, 0])

    (五)动手实践:多维数组的切片和索引

    (1)创建一个三维数组:

    先用arange函数创建一个数组,用reshape函数改变其维度,使之变为一个三维数组

    In: b = arange(24).reshape(2,3,4)

    In: b.shape
    Out: (2, 3, 4)
    In: b
    Out:
    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]]])

    多维数组b中有0~23的整数,共24个元素,是一个2×3×4的三维数组。我们可以形象地把它
    看做一个两层楼建筑,每层楼有12个房间,并排列成3行4列。

    (2) 我们可以用三维坐标来选定任意一个房间,即楼层、行号和列号。

    In: b[0,0,0]
    Out: 0

    (3) 如果我们不关心楼层,也就是说要选取所有楼层的第1行、第1列的房间,那么可以将第1
    个下标用英文标点的冒号:来代替:

    In: b[:,0,0]
    Out: array([ 0, 12])
    This selects the first floor
    In: b[0]
    Out:
    array([[ 0, 1, 2, 3],
    [ 4, 5, 6, 7],
    [ 8, 9,10,11]])

    我们还可以这样写,选取第1层楼的所有房间:
    In: b[0, :, :]
    Out:
    array([[ 0, 1, 2, 3],
    [ 4, 5, 6, 7],
    [ 8, 9,10,11]])
    多个冒号可以用一个省略号(...)来代替,因此上面的代码等价于:
    In: b[0, ...]
    Out:
    array([[ 0, 1, 2, 3],
    [ 4, 5, 6, 7],
    [ 8, 9, 10, 11]])

    进而可以选取第1层楼、第2排的所有房间:
    In: b[0,1]
    Out: array([4, 5, 6, 7])

    (4) 再进一步,我们可以在上面的数组切片中间隔地选定元素:
    In: b[0,1,::2]
    Out: array([4, 6])
    (5) 如果要选取所有楼层的位于第2列的房间,即不指定楼层和行号,用如下代码即可:
    In: b[...,1]
    Out:
    array([[ 1, 5, 9],
    [13,17,21]])
    类似地,我们可以选取所有位于第2行的房间,而不指定楼层和列号:
    In: b[:,1]
    Out:
    array([[ 4, 5, 6, 7],
    [16,17,18,19]])
    如果要选取第1层楼的所有位于第2列的房间,在对应的两个维度上指定即可:
    In: b[0,:,1]
    Out: array([1, 5, 9])
    (6) 如果要选取第1层楼的最后一列的所有房间,使用如下代码:
    In: b[0,:,-1]
    Out: array([ 3, 7, 11])
    如果要反向选取第1层楼的最后一列的所有房间,使用如下代码:
    In: b[0,::-1, -1]
    Out: array([11, 7, 3])
    在该数组切片中间隔地选定元素:
    In: b[0,::2,-1]
    Out: array([ 3, 11])
    如果在多维数组中执行翻转一维数组的命令,将在最前面的维度上翻转元素的顺序,在我们
    的例子中将把第1层楼和第2层楼的房间交换:
    In: b[::-1]
    Out:
    array([[[12,13,14,15],
    [16,17,18,19],
    [20,21,22,23],
    [[ 0, 1, 2, 3],

    [ 4, 5, 6, 7],

    [ 8, 9,10,11]]])

    (六)动手实践:改变数组的维度

    (1)ravel 用ravel函数完成展平的操作:

    In: b
    Out:
    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]]])
    In: b.ravel()
    Out:
    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])

    (2) flatten 与ravel函数的功能相同,不过,

    flatten函数会请求内存来保存结果,

    而ravel函数只是返回数组的一个视图(view)

    In: b.flatten()
    Out:
    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])

    (3)用元组设置维度(也可以使用reshape函数:b.reshape(6,4))

    In: b.shape = (6,4)
    In: b
    Out:
    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]],

    (4)transpose 多维数组转置

    In: b.transpose()
    Out:
    array([[ 0, 4, 8, 12, 16, 20],
    [ 1, 5, 9, 13, 17, 21],
    [ 2, 6,10, 14, 18, 22],
    [ 3, 7,11, 15, 19, 23]])

    (5)resize resize函数和reshape函数功能一样,但是resize函数会直接修改所操作的数组

    In: b.resize((2,12))---书上这样写,其实写为b.resize(2,12)就可以
    In: b
    Out:
    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]])

    (七)数组的组合

    Numpy数组有水平组合、垂直组合和深度组合等多种方式

    首先创建一些数组:

    In: a = arange(9).reshape(3,3)
    In: a
    Out:
    array([[0, 1, 2],
    [3, 4, 5],
    [6, 7, 8]])
    In: b = 2 * a
    In: b
    Out:
    array([[ 0, 2, 4],
    [ 6, 8, 10],
    [12, 14,16]])

    (1)水平组合 hstack函数、concatenate函数

    In: hstack((a, b))
    Out:
    array([[ 0, 1, 2, 0, 2, 4],
    [ 3, 4, 5, 6, 8,10],
    [ 6, 7, 8,12,14,16]])

    也可以用concatenate函数实现同样的效果。

    In: concatenate((a, b), axis=1)
    Out:
    array([[ 0, 1, 2, 0, 2, 4],
    [ 3, 4, 5, 6, 8,10],
    [ 6, 7, 8,12,14,16]])

    (2)垂直组合 vstack函数和concatenate函数

    In: vstack((a, b))
    Out:
    array([[ 0, 1, 2],
    [ 3, 4, 5],
    [ 6, 7, 8],
    [ 0, 2, 4],
    [ 6, 8,10],
    [12,14,16]])

    In: concatenatel((a, b), axis = 0)
    Out:
    array([[ 0, 1, 2],
    [ 3, 4, 5],
    [ 6, 7, 8],
    [ 0, 2, 4],
    [ 6, 8,10],
    [12,14,16]]) 

    (3)深度组合 dstack

    所谓深度组合,就是将一系列数组沿着纵轴(深度)方向进行层叠组合。

    In: dstack((a, b))
    Out:
    array([[[0, 0],
    [1, 2],
    [2, 4]],
    [[3, 6],
    [4, 8],
    [5,10]],
    [[6,12],
    [7,14],
    [8,16]]])

    (4)列组合

    column_stack函数对于一维数组将按列方向进行组合。效果等同于dstack

    In: oned = arange(2)
    In: oned
    Out: array([0, 1])
    In: twice_oned = 2 * oned
    In: twice_oned
    Out: array([0, 2])
    In: column_stack((oned, twice_oned))
    Out:
    array([[0, 0],
    [1, 2]])

    对于二维数组,column_stack与hstack的效果是相同的。

    In: column_stack((a, b))
    Out:
    array([[ 0, 1, 2, 0, 2, 4],
    [ 3, 4, 5, 6, 8,10],
    [ 6, 7, 8,12,14,16]])
    In: column_stack((a, b)) == hstack((a, b))
    Out:
    array([[ True, True, True, True, True, True],
    [ True, True, True, True, True, True],
    [ True, True, True, True, True, True]], dtype=bool)

    可以用==运算符来比较两个NumPy数组

     (八)数组的分割

    Numpy数组可以进行水平,垂直或深度分割。相关的函数有hsplit、vsplit、dsplit和split。

    我们可以将数组分割成相同大小的子数组,也可以指定原数组中需要分割的位置。

    (1)水平分割

    In: a
    Out:
    array([[0, 1, 2],
    [3, 4, 5],
    [6, 7, 8]])
    In: hsplit(a, 3)
    Out:
    [array([[0],
    [3],
    [6]]),
    array ([[1],
    [4],
    [7]]),
    array ([[2],
    [5],
    [8]])]

    对同样的数组,调用split函数并在参数中指定参数axis=1,对比一下结果:
    In: split(a, 3, axis=1)
    Out:
    [array([[0],
    [3],
    [6]]),
    array ([[1],
    [4],
    [7]]),
    array ([[2],
    [5],
    [8]])]

    (2) 垂直分割 vsplit函数将把数组沿着垂直方向分割:

    In: vsplit(a, 3)
    Out: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
    同样,调用split函数并在参数中指定参数axis=0,也可以得到同样的结果:
    In: split(a, 3, axis=0)
    Out: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]

    (3)深度分割 dsplit函数将按深度方向分割数组

    In: c = arange(27).reshape(3, 3, 3)
    In: c
    Out:
    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]]])
    In: dsplit(c, 3)
    Out:
    [array([[[ 0],
    [ 3],
    [ 6]],
    [[ 9],
    [12],
    [15]],
    [[18],
    [21],
    [24]]]),
    array([[[ 1],
    [ 4],
    [ 7]],
    [[10],

    [13],
    [16]],
    [[19],
    [22],
    [25]]]),
    array([[[ 2],
    [ 5],
    [ 8]],
    [[11],
    [14],
    [17]],
    [[20],
    [23],
    [26]]])]

    只能用于三维或三维以上的数组。

    (九)数组的属性

    除了shape属性和dtype属性以外,ndarray对象还有很多其他的属性。

    •  ndim属性,给出数组的维数,或数组轴的个数:

    In: b
    Out:
    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]])
    In: b.ndim
    Out: 2

    •  size属性,给出数组元素的总个数,如下所示:

    In: b.size
    Out: 24

    • itemsize属性,给出数组中的元素在内存中所占的字节数:

    In: b.itemsize
    Out: 8

    • 如果你想知道整个数组所占的存储空间,可以用nbytes属性来查看。这个属性的值其实

    就是itemsize和size属性值的乘积:
    In: b.nbytes
    Out: 192
    In: b.size * b.itemsize
    Out: 192

    • T属性的效果和transpose函数一样,如下所示:

    In: b.resize(6,4)
    In: b
    Out:
    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]])
    In: b.T
    Out:
    array([[ 0, 4, 8, 12,16, 20],
    [ 1, 5, 9, 13,17, 21],
    [ 2, 6,10, 14,18, 22],
    [ 3, 7,11, 15,19, 23]])

    •  对于一维数组,其T属性就是原数组:

    In: b.ndim
    Out: 1
    In: b.T
    Out: array([0, 1, 2, 3, 4])

    • 在NumPy中,复数的虚部是用j表示的。例如,我们可以创建一个由复数构成的数组:

    In: b = array([1.j + 1, 2.j + 3])
    In: b
    Out: array([ 1.+1.j, 3.+2.j])

    • real属性,给出复数数组的实部。如果数组中只包含实数元素,则其real属性将输出原

    数组:
    In: b.real
    Out: array([ 1., 3.])

    •  imag属性,给出复数数组的虚部:

    In: b.imag
    Out: array([ 1., 2.])

    •  如果数组中包含复数元素,则其数据类型自动变为复数型:

    In: b.dtype
    Out: dtype('complex128')
    In: b.dtype.str
    Out: '<c16'

    • flat属性将返回一个numpy.flatiter对象, 这是获得flatiter对象的唯一方式——我

    们无法访问flatiter的构造函数。这个所谓的“扁平迭代器”可以让我们像遍历一维数
    组一样去遍历任意的多维数组,如下所示:

    In: b = arange(4).reshape(2,2)
    In: b
    Out:
    array([[0, 1],
    [2, 3]])
    In: f = b.flat
    In: f
    Out: <numpy.flatiter object at 0x103013e00>
    In: for item in f: print item
    .....:
    0
    1
    2
    3
    我们还可以用flatiter对象直接获取一个数组元素:
    In: b.flat[2]
    Out: 2
    或者获取多个元素:
    In: b.flat[[1,3]]
    Out: array([1, 3])
    flat属性是一个可赋值的属性。对flat属性赋值将导致整个数组的元素都被覆盖:
    In: b.flat = 7
    In: b
    Out:
    array([[7, 7],
    [7, 7]])
    or selected elements
    In: b.flat[[1,3]] = 1
    In: b
    Out:
    array([[7, 1],
    [7, 1]])

     (十)数组的转换

     (1)tolist函数将Numpy数组转换成python列表

    In: b
    Out: array([ 1.+1.j, 3.+2.j])
    In: b.tolist()
    Out: [(1+1j), (3+2j)]

    (2)astype函数可以在转换数组时指定数据类型

    In: b
    Out: array([ 1.+1.j, 3.+2.j])
    In: b.astype(int)
    /usr/local/bin/ipython:1: ComplexWarning: Casting complex values to real discards the
    imaginary part
    #!/usr/bin/python
    Out: array([1, 3])

  • 相关阅读:
    数据挖掘中所需的概率论与数理统计知识、上
    pig语法学习 FOREACH GENERATE group AS
    pig flatten
    F-stack及其Nginx、redis的编译安装
    f-stack中nginx配置后make出现error: ignoring return value of ‘ftruncate’
    高速网络流量测量方法的记录
    DPDK测试用例(sample)编译
    VPP(Vector Packet Processing)配置工具
    DMA(Direct Memory Access)简介
    VPP(Vector Packet Processing)浅析
  • 原文地址:https://www.cnblogs.com/data-ccz/p/6122890.html
Copyright © 2011-2022 走看看