• NumPy基础


    1.1 NumPy 数组对象

    NumPy中的ndarray是一个多维数组对象,该对象由两部分组成:  实际的数据;  描述这些数据的元数据。 大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据。 NumPy数组的下标也是从0开始的。数组元素的数据类型用专门的对象表示。 我们再次用arange函数创建数组,并获取其数据类型: In: a = arange(5) In: a.dtype Out: dtype('int64') 数组a的数据类型为int64(在我的机器上是这样),当然如果你使用32位的Python,得到的 结果可能是int32。不论是哪种情形,该数组的数据类型都是整数(64位或32位)。除了数据类 型,数组的维度也是重要的属性。

    >>> import array

    >>> import numpy

    >>> m= array([arange(2),arange(2)])

    Traceback (most recent call last): File "", line 1, in

    NameError: name 'arange' is not defined

    >>> import array

    >>> from numpy import *

    >>> m= array([arange(2),arange(2)])

    >>> m array([[0, 1], [0, 1]])

    >>> m.shape (2, 2)

    我们将arange函数创建的数组作为列表元素,把这个列表作为参数传给array函数,从而 创建了一个2×2的数组 数组的shape属性 返回一个元组(tuple),元组中的元素即为NumPy数组每一个维度上的大小。上面例子中的数组 是一维的,因此元组中只有一个元素。 选取数组元素

    >>> import array

    >>> from numpy import *

    >>> a =array([[1,2],[3,4]])

    >>> a array([[1, 2], [3, 4]])

    >>> a[1,2]

    Traceback (most recent call last): File "", line 1, in

    IndexError: index 2 is out of bounds for axis 1 with size 2

    >>> a[1,1]

    4

    对于数组a,只需要用a[m,n]选取各数组元素,其 中m和n为元素下标

    NumPy 数据类型

    bool 用一位存储的布尔类型(值为TRUE或FALSE)

    inti 由所在平台决定其精度的整数(一般为int32或int64)

    int8 整数,范围为128至127

    int16 整数,范围为32 768至32 767

    int32 整数,范围为-2exp31~2exp31-1

    int64 整数,范围为-2exp63~2exp63-1

    uint8 无符号整数,范围为0至255

    uint16 无符号整数,范围为0至65 535

    uint32 无符号整数,范围为0至2exp32-1

    uint64. 无符号整数,范围为0至2exp64-1

    float16 半精度浮点数(16位):其中用1位表示正负号,5位表示指数,10位表示尾数

    float32 单精度浮点数(32位):其中用1位表示正负号,8位表示指数,23位表示尾数

    float64或float 双精度浮点数(64位):其中用1位表示正负号,11位表示指数,52位表示尾数

    complex64 复数,分别用两个32位浮点数表示实部和虚部

    complex128或complex. 复数,分别用两个64位浮点数表示实部和虚部

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

    >>> arange(7,dtype= uint16)

    array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)

    数据类型对象

    数据类型对象是numpy.dtype类的实例。如前所述,NumPy数组是有数据类型的,更确切 地说,NumPy数组中的每一个元素均为相同的数据类型。

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

    >>> a=array([[1,2],[3,4]])

    >>> a.dtype.itemsize

    8

    >>> a =arange(7,dtype= uint16)

    >>> a.dtype.itemsize

    2

    字符编码.

    整数 i

    无符号整数 u

    单精度浮点数 f

    双精度浮点数 d

    布尔值 b

    复数 D

    字符串 S

    unicode字符串 U

    void (空) V

    >>> from numpy import *

    >>> arange(7,dtype('D'))

    Traceback (most recent call last): File "", line 1,

    in TypeError: unsupported operand type(s) for -: 'numpy.dtype' and 'int'

    >>> arange(7,dtype='D')

    array([ 0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j])

    >>> arange(7,dtype='f')

    array([ 0., 1., 2., 3., 4., 5., 6.], dtype=float32)

    dtype类的属性 获取数据类型的字符编码 数组元素的数据类型 str属性可以给出数据类型的字符串表示,该字符串的首个字符表示字节序(endianness), 后面如果还有字符的话,将是一个字符编码,接着一个数字表示每个数组元素存储所需的字节数。 这里,字节序是指位长为32或64的字(word)存储的顺序,包括大端序(big-endian)和小端序 (little-endian)。大端序是将最高位字节存储在最低的内存地址处,用>表示;与之相反,小端序 是将最低位字节存储在最低的内存地址处,用<表示

    >>> t=dtype('Float64')

    >>> t.char

    'd'

    >>> t.type <type 'numpy.float64'>

    >>> t.str

    '<f8'

    1.2 创建自定义数据类型

    自定义数据类型是一种异构数据类型,可以当做用来记录电子表格或数据库中一行数据的结 构。 我们用一个长度为40个字 符的字符串来记录商品名称,用一个32位的整数来记录商品的库存数量,最后用一个32位的单精 度浮点数来记录商品价格。下面是具体的步骤。

    >>> t = dtype([('name',str,40),('numitems',int32),('price',float32)])

    >>> t dtype([('name', 'S40'), ('numitems', '<i4'), ('price', '<f4')])

    >>> t['name'] dtype('S40')

    >>> itemz=array([('python',40,3.333),('php',333,2.22)],dtpye=t)

    Traceback (most recent call last): File "", line 1, in

    TypeError: 'dtpye' is an invalid keyword argument for this function

    >>> itemz=array([('python',40,3.333),('php',333,2.22)],dtype=t)

    >>> itemz[1]

    ('php', 333, 2.2200000286102295)

    我们创建了一种自定义的异构数据类型,该数据类型包括一个用字符串记录的名字、一个用 整数记录的数字以及一个用浮点数记录的价格。

    1.3索引和切片

    一维数组的索引和切片

    用下标3~7来选取元素3~6 下标0~7,以2为步长选取元素 利用负数下标翻转数组

    >>> a =arange(9)

    >>> a[3:7]

    array([3, 4, 5, 6])

    >>> a[:7:2]

    array([0, 2, 4, 6])

    >>> a[::-1]

    array([8, 7, 6, 5, 4, 3, 2, 1, 0])

    多维数组的切片和索引

    ndarray支持在多维数组上的切片操作。为了方便起见,我们可以用一个省略号(...)来表示遍历剩下的维度。

    我们先用arange函数创建一个数组并改变其维度,使之变成一个三维数组:

    >>> a=arange(24).reshape(2,3,4)

    >>> a.shape (2, 3, 4)

    >>> a

    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]

    ]])

    我们可以形象地把它 看做一个两层楼建筑,每层楼有12个房间,并排列成3行4列 各种方法对一个NumPy多维数组进行了切片操作:

    选取第1层楼的所有房间

    >>> a[0]

    array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])

    我们还可以这样写,选取第1层楼的所有房间

    >>> a[0,:,:]

    array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])

    多个冒号可以用一个省略号(...)来代替

    >>> a[0,...]

    array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])

    进而可以选取第1层楼、第2排的所有房间

    >>> a[0,1]

    array([4, 5, 6, 7])

    再进一步,我们可以在上面的数组切片中间隔地选定元素

    >>> a[0,1,::2]

    array([4, 6])

    我们可以选取所有位于第2行的房间,而不指定楼层和列号

    >>> a[:,1]

    array([[ 4, 5, 6, 7], [16, 17, 18, 19]])

    如果要选取第1层楼的所有位于第2列的房间,在对应的两个维度上指定即可

    >>> a[0,:,1]

    array([1, 5, 9])

    如果要选取第1层楼的最后一列的所有房间,使用如下代码

    >>> a [0,:,-1]

    array([ 3, 7, 11])

    如果要反向选取第1层楼的最后一列的所有房间,使用如下代码

    >>> a[0,::-1,-1]

    array([11, 7, 3])

    在该数组切片中间隔地选定元素:

    >>> a[0,::2,-1]

    array([ 3, 11])

    如果在多维数组中执行翻转一维数组的命令,将在最前面的维度上翻转元素的顺序,

    在我们 的例子中将把第1层楼和第2层楼的房间交换:

    >>> a[::-1]

    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.4改变数组的维度

    已经学习了怎样使用reshape函数,现在来学习一下怎样将数组展平 ravel

    我们可以用ravel函数完成展平的操作

    >>> a

    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]]])

    >>> a.ravel()

    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]) f

    latten 这个函数恰如其名,flatten就是展平的意思,与ravel函数的功能相同。不过,flatten函数会请求分配内存来保存结果,而ravel函数只是返回数组的一个视图(view) >>> a.flatten()

    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])

    用元组设置维度 除了可以使用reshape函数,我们也可以直接用一个正整数元组来设置数组的维度

    >>> a.shape=(6,4)

    >>> a

    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成了一个6×4的多维数组。

    transpose 在线性代数中,转置矩阵是很常见的操作。

    >>> a.transpose()

    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]])

    1.5数组的组合

    NumPy数组有水平组合、垂直组合和深度组合等多种组合方式,我们将使用vstack、 dstack、hstack、column_stack、row_stack以及concatenate函数来完成数组的组合。

    组合数组:

    >>> a=arange(9).reshape(3,3)

    >>> a

    array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])

    >>> b=2*a

    >>> b

    array([[ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]])

    水平组合 我们先从水平组合开始练习。将ndarray对象构成的元组作为参数,传给 hstack函数。

    >>> c=hstack((a,b))

    >>> c

    array([[ 0, 1, 2, 0, 2, 4], [ 3, 4, 5, 6, 8, 10], [ 6, 7, 8, 12, 14, 16]])

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

    >>> d=concatenate((a,b),axis=1)

    >>> d

    array([[ 0, 1, 2, 0, 2, 4], [ 3, 4, 5, 6, 8, 10], [ 6, 7, 8, 12, 14, 16]])

    垂直组合

    垂直组合同样需要构造一个元组作为参数,只不过这次的函数变成了 vstack。

    >>> e=vstack((a,b))

    >>> e

    array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]])

    我们将concatenate函数的axis参数设置为0即可实现同样的效果。这也是axis参 数的默认值:

    >>> f=concatenate((a,b),axis=0)

    >>> f

    array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]])

    深度组合 将相同的元组作为参数传给dstack函数,即可完成数组的深度组合。

    深度组合,就是将一系列数组沿着纵轴(深度)方向进行层叠组合。 举个例子,有若干张二维平面内的图像点阵数据,我们可以将这些图像数据沿纵轴方向层叠在一起,这就形象地解释了什么 是深度组合。

    >>> g=dstack((a,b))

    >>> g

    array([[[ 0, 0], [ 1, 2], [ 2, 4]], [[ 3, 6], [ 4, 8], [ 5, 10]], [[ 6, 12], [ 7, 14], [ 8, 16]]])

    列组合

    column_stack函数对于一维数组将按列方向进行组合,而对于二维数组,column_stack与hstack的效果是相同的

    >>> h=column_stack((a,b))

    >>> h

    array([[ 0, 1, 2, 0, 2, 4], [ 3, 4, 5, 6, 8, 10], [ 6, 7, 8, 12, 14, 16]])

    行组合

    当然,NumPy中也有按行方向进行组合的函数,它就是row_stack。

    对于两个一维数组,将直接层叠起来组合成一个二维数组。对于二维数组,row_stack与vstack的效果是相同的.

    >>> i=row_stack((a,b))

    >>> i

    array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]])

    1.6数组的分割

    >>> a=arange(9).reshape(3,3)

    >>> a

    array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])

    水平分割

    下面的代码将把数组沿着水平方向分割为3个相同大小的子数组:

    >>> hsplit(a,3)

    [array([[0], [3], [6]]), array([[1], [4], [7]]), array([[2], [5], [8]])]

    对同样的数组,等同调用split函数并在参数中指定参数axis=1

    >>> split(a,3,axis=1)

    [array([[0], [3], [6]]), array([[1], [4], [7]]), array([[2], [5], [8]])]

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

    >>> vsplit(a,3)

    [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]

    调用split函数并在参数中指定参数axis=0,也可以得到同样的结果

    >>> split(a,3,axis=0)

    [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]

    深度分割

    不出所料,dsplit函数将按深度方向分割数组。我们先创建一个三维数组

    >>> c = arange(27).reshape(3, 3, 3)

    >>> c

    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]]])

    >>> dsplit(c,3)

    [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]]])]

    1.7数组的属性

    除了shape和dtype属性以外,ndarray对象还有很多其他的属性,在下面一一列出。

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

    >>> a=arange(10).reshape(2,5)

    >>> a

    array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])

    >>> a.ndim

    2

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

    >>> a.size

    10

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

    >>> a.itemsize

    8

    如果你想知道整个数组所占的存储空间,可以用nbytes属性来查看。这个属性的值是itemsize和size属性值的乘积:

    >>> a.nbytes

    80

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

    >>> a.T

    array([[0, 5], [1, 6], [2, 7], [3, 8], [4, 9]])

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

    >>> b=array([1.j+1,2.j+3])

    >>> b

    array([ 1.+1.j, 3.+2.j])

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

    >>> b.real

    array([ 1., 3.])

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

    >>> b.imag

    array([ 1., 2.])

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

    >>> b.dtype

    dtype('complex128')

    >>> b.dtype.str '<c16'

    flat属性将返回一个numpy.flatiter对象,这是获得flatiter对象的唯一方式——我 们无法访问flatiter的构造函数。这个所谓的“扁平迭代器”可以让我们像遍历一维数 组一样去遍历任意的多维数组

    >>> c=arange(9).reshape(3,3)

    >>> c array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])

    >>> c.flat

    >>> d =c.flat

    >>> d

    >>> for item in d : print item ...

    0 1 2 3 4 5 6 7 8

    我们还可以用flatiter对象直接获取一个数组元素:

    >>> d[3]

    3

    1.8 数组的转换

    使用tolist函数将NumPy数组转换成Python列表。

    >>> c

    array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])

    >>> c.tolist

    >>> c.tolist()

    [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

    astype函数可以在转换数组时指定数据类型:

    >>> c.astype(float)

    array([[ 0., 1., 2.], [ 3., 4., 5.], [ 6., 7., 8.]])

  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/vincentqliu/p/numpy.html
Copyright © 2020-2023  润新知