zoukankan      html  css  js  c++  java
  • Numpy 数组ndarray和常用函数速查

    转自:DawnRanger的专栏
    https://blog.csdn.net/DawnRanger/article/details/53125945





    1. 简介

    Numeric Python的简称,是几乎所有python科学计算工具的基础。主要功能:

    • ndarray: 一个具有矢量运算和复杂广播能力的快速并且节省空间的多维数组
    • 面向数组的运算: 对于数组进行快速运算的标准数学函数
    • 磁盘读写、内存映射
    • 线性代数、随机数、傅里叶变换

    NumPy本身并没有提供什么高级的数据分析能力,但是理解NumPy数组以及面向数组的计算将有利于使用pandas等工具。

    2. ndarray:一种多维数组对象

    ndarray是一个通用的同构数据多维容器,其中的所有元素必须是相同类型的。ndarray含有两个属性:

    • shape: 一个表示各维度大小的数组
    • dtype:一个用于说明数据类型的对象

    2.1 创建ndaray

    1) array函数

    它接受一切序列型的对象(list/set/tuple/ndarray/…)。除非显式说明,np.array会尝试为新建的这个数组推断出一个较为合适的数据类型:

    import numpy as np
    arr1 = np.array([1,2,3,4,5])
    arr2 = np.array([[1,2,3,4], [5,6,7,8]]) # 二维数组
    
    • 1
    • 2
    • 3
    • 4

    2) zeros/ones/empty函数
    创建指定长度或形状的全0或全1或空数组,只需传入一个表示形状的元组(tuple)即可:

    np.zeros(10)
    np.ones((3,6)
    np.empty((2,3,2)) #注意返回的并不是全0数组,而是未初始化的随机值
    
    • 1
    • 2
    • 3
    • 4

    3) linspace函数linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
    返回在start到stop之间均匀分布的num个数字,可以选择是否包括stop. retstep表示是否返回步长.

    np.linspace(1,5,5,True)
    Out[4]: array([ 1.,  2.,  3.,  4.,  5.])
    
    np.linspace(1,5,5,False)
    Out[5]: array([ 1. ,  1.8,  2.6,  3.4,  4.2])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3) arange函数arange([start,] stop[, step,], dtype=None)
    python内置函数range的数组版

    np.arange(15)
    
    • 1
    • 2

    4) 其它函数:
    由于NumPy关注的是数值计算,因此,如果没有特别指定,数据类型基本都是float64(浮点数)

    • array 将输入转换为ndarray,默认直接复制输入数据
    • asarray 将输入转换为ndarray,如果输入本身就是一个ndarray就不进行复制
    • ones_like/zeros_like/empty_like 以另一个数组为参数,并根据其形状和dtype创建一个全0/全1/空数组
    • eye/identify 创建一个N×N” role=”presentation”>N×NN×N单位矩阵(对角线为1,其余为0)

    2.2 ndaray的数据类型

    dtype含有ndarray将一块内存解释为特定数据类型所需要的信息

    arr1 = np.array([1,2,3], dtype = np.float64)
    arr2 = np.array([1,2,3], dtype = np.int32)
    arr2 = np.array([1,2,3], dtype = 'i4')  # 也可以写类型代码
    arr1.dtype
    Out[5]: dtype('float64')
    arr2.dtype
    Out[6]: dtype('int32')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    NumPy的数据类型

    • int8/int16/int32/int64 有符号8/16/32/64位整数,类型代码 i1/i2/i4/i8 (分别为1/2/4/8个字节)
    • uint8/uint16/uint32/uint64 无符号8/16/32/64位整数,类型代码 u1/u2/u4/u8
    • float16/float32/float64/float128 浮点数,类型代码 f2/f4/f8/f16
    • complex64/complex128/complex256 复数,类型代码 c8/c16/c32
    • bool 布尔类型 ,类型代码 ?
    • object Python对象类型,类型代码 O
    • string_ 固定长度的字符串类型(每个字符一个字节),类型代码 S 。例如,要创建一个长度为10的字符串,应使用S10
    • unicode 固定长度的unicode类型,类型代码 U 。同字符串(如U10)

    数据类型转换: astype方法

    int_arr = np.array([1,2,3,4,5])
    float_arr = int_arr.astype(np.float64)
    
    numeric_str = np.array (['1.25', '-9.6', '42'], dtype = np.string_)
    float_arr = numeric_str.astype(float)  # 这里的float是Python的数据类型,NumPy会自动的将其映射到等价的dtype上,即np.float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意:astype无论如何都会创建出一个新的数组(原始数据的一分拷贝)

    2.3 ndaray与标量的计算

    使用数组运算的好处是不写循环即可对数据进行批量运算,即矢量化(vectorization)。需要注意的是:

    • 大小相等的数组之间的任何算术运算都会将运算应用到元素级
    • 数组与标量的算术运算会将标量值传播到各个元素

    不同大小的数组之间的运算叫做广播(broadcasting)。

    2.4 索引与切片

    2.4.1 一维数组
    一维数组的索引与切片和Python列表的功能类似,区别在于,数组切片是原始数组的视图,这意味着数据不会被复制,对视图的任何修改都会直接反映到原数组上。NumPy如此设计的目的是为了处理大数据,如果采取复制的方法可能产生性能和内存的问题。

    arr = np.arange(10)
    arr[5:8] = 12
    arr
    Out[10]:array([0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果一定要复制可以使用copy方法显式的复制。

    2.4.2 多维数组
    多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray。例如,二维数组中,各索引位置上的元素不再是标量而是一维数组。

    arr2d = np.array([[1,2,3], [4,5,6], [7,8,9]])
    arr2d[2]
    Out[11]:array([7, 8, 9])
    arr2d[0][2]
    arr2d[0,2]  # 这两种索引方法等价
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.4.3 多维数组切片
    多维数组切片与一维数组稍有不同

    arr2d = np.array([[1,2,3], [4,5,6], [7,8,9]])
    arr2d[:2]
    Out[1]: array([[1,2,3], 
                   [4,5,6]])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可以看出,它是按第0轴(第一个轴)切片的。切片是沿着一个轴向选取元素的。
    可以一次传入多个切片,也可以将整数索引和切片混合:

    arr2d[:2, 1:]
    Out[2]: aray([[2,3], 
                  [5,6])
    arr2d[1, :2]
    Out[3]: array([4, 5])
    arr2d[:, :1]
    Out[4]: aray([[1], 
                  [4], 
                  [7]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.4.4 布尔型索引
    与算数运算类似,数组的比较运算(如==)也是矢量化的。

    names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
    data = np.random.randn(7, 4)  # 产生7x4的随机数组
    names == 'Bob'
    Out[5]: array([True, False, False, True, False, False, False], dtype = bool)
    data[names == 'Bob'] # 布尔索引
    data[names = 'Bob', 2:] # 布尔索引与切片
    data[-(names == 'Bob')]
    mask = (names == 'Bob') | (names = 'Will') # 多个布尔条件用&(与)、|(或)等连接起来。(and/or无效)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    通过布尔型索引选取数组中的数据,将总是创建副本,即使返回一模一样的数组。通过布尔型数组设置值是常用的手段。例如:

    data[data<0] = 0  # 将data中的所有的负值都设为0
    data[names != 'Joe'] = 7  # 将不为Joe的值设为7 
    
    • 1
    • 2
    • 3

    2.4.5 花式索引(Fancy indexing)
    利用整数数组进行索引。

    正常情况下的索引:

    In [17]: arr = np.empty((8,4))
    In [18]: for i in range(8):
        ...:     arr[i] = i # 矢量化赋值
    In [19]: arr
    Out[19]:
    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.]])
    
    In [23]: arr[[4,3,0,6]]  # 选取多行,注意要加括号[]
    Out[23]: 
    array([[ 4.,  4.,  4.,  4.],
           [ 3.,  3.,  3.,  3.],
           [ 0.,  0.,  0.,  0.],
           [ 6.,  6.,  6.,  6.]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    一次传入多个索引数组时,它返回的是一个一维数组,其中的元素对应各个索引元组。

    In [24]: arr = np.arange(32).reshape((8,4))
    In [25]: arr
    Out[25]:
    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]])
    In [26]: arr[[1,5,7,2], [0,2,1,3]]
    Out[26]: array([ 4, 22, 29, 11])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    最终选出的元素是(1, 0)、(5, 3)、(7, 1)、(2, 2)。
    如果想要选取数组的行列子集,可以采用以下方法:

    In [33]: arr[[1,5,7,2]][:,[0,3,1,2]]  # 可以把左右两个[]分开来理解
    Out[33]: 
    array([[ 4,  7,  5,  6],
           [20, 23, 21, 22],
           [28, 31, 29, 30],
           [ 8, 11,  9, 10]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    另一种方法是使用 np.ix_ 函数,它可以将两个一维整数数组转换为一个用于选取方形区域的索引器:

    In [34]: arr[np.ix_([1,5,7,2],[0,3,1,2])]
    Out[34]: 
    array([[ 4,  7,  5,  6],
           [20, 23, 21, 22],
           [28, 31, 29, 30],
           [ 8, 11,  9, 10]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    与切片不同,花式索引总是将数据复制到新数组中

    2.5 数组转置和轴变换

    返回原数据的视图,不会进行任何复制。数组有transpose/swapaxes方法和T属性。

    3. numpy通用函数

    一元函数:

    • abs/fabs 绝对值。对于非复数,可以使用更快的fabs
    • sqrt/square/exp/log/log10/log2/log1p 平方根/平方/指数/自然对数/底数为10的log/底数为2的log
    • sign 返回元素的符号:1(正数)、0(零)、-1(负数)
    • ceil/floor 取上界/下界整数
    • rint 四舍五入到整数
    • modf 返回数组的小数和正数两个独立的数组
    • isnan 返回布尔数组,判断是否为数字
    • isfinite/isinf 是否有穷/无穷
    • cos/cosh/sin/sinh/tan/tanh 普通和双曲三角函数

    二元函数:

    • add/subtract/multiply/divide/floor_divide 加/减/乘/除/向下圆整除法
    • power 第一个数组中的是底数,第二个数组中的是指数
    • maximum/fmax/minimum/fmin 最大最小值(fmax/fmin忽略NaN)
    • mod 取模
    • copysign 将第二个数组中的值的符号复制给第一个数组中
    • greater/greater_equal/less/less_equal 元素级比较,产生布尔数组。
    • logical_and/logical_or/logical_xor 元素级真值逻辑运算。&、|、^。

    4. 利用数组进行数据处理

    一般来说矢量化数组运算要比等价的纯Python方式快上一两个数量级,尤其是各种数值计算。广播是一种针对矢量化计算的强大手段。

    4.1 将条件逻辑表述为数组运算

    numpy.where 函数是三元表达式 x if condition else y 的矢量化版本:where(condition, [x, y])

    arr = randn(4,4)
    np.where(arr>0, 2, -2) # 争执设置为2,负值设置为-2
    np.where(arr>0, 2, arr) # 只讲正值设置为2 
    
    • 1
    • 2
    • 3
    • 4

    条件是可以嵌套的:

    np.where(cond1 & cond2, 0,
             np.where(cond1, 1,
                     np.where(cond2, 2, 3)))
    
    • 1
    • 2
    • 3
    • 4

    4.2 数学和统计方法

    聚合计算(aggregation):既能当数组的实例方法调用,也可以当做顶级NumPy函数使用;可接受一个 axis 参数
    - sum/mean/std/var/min/max/argmin/argmax 求和,平均数,标准差,方差,最大值,最小值,最大最小元素的索引

    不聚合,产生一个由中间结果组成的数组:
    - cumsumcumprod 所有元素的累积和/累计积

    4.3 用于布尔型数组的方法

    bools = np.array([False, False, True, False])
    (bools>0).sum() # 正值的数量
    bools.any() # 测试数组中是否存在一个或多个True
    bools.all() # 检查数组中所有值是否都是True
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.4 排序

    Numpy数组自带sort方法,如果需要在某一个轴向上进行排序,只需要将轴编号传递给sort.
    顶级方法np.sort返回的是数组已排序的副本,而数组自带sort方法则会直接修改数组本身.

    arr = randn(5, 3)
    arr.sort(1)
    large_arr = randn(1000)
    large_arr.sort()
    large_arr[int(0.05 * len(large_arr))] # 5%分位数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.5 唯一化以及其它的集合逻辑

    集合运算函数:

    • unique(x) 返回唯一元素
    • intersect1d(x,y) 交集
    • union1d(x,y) 并集
    • in1d(x,y) 布尔型数组,表示x中的元素是否存在于y中
    • setdiff1d(x,y)
    • setxor1d(x,y) 异或

    5. 用于数组的文件操作

    二进制文件: np.savenp.load
    文本文件: np.loadtxtnp.savetxt

    6. 线性代数

    常用numpy.linalg函数

    • dot 矩阵乘法。两个一维数组计算点乘,两个多维数组计算叉乘
    • diag 返回矩阵对角线元素
    • trace 对角线元素和
    • det 行列式
    • eig 特征值、特征向量
    • inv
    • qr QR分解
    • svd 奇异值分解
    • solve 解线性方程Ax=b
    • lstsq 计算Ax=b的最小二乘解

    7. 随机数生成

    生成随机数的方法:


    • rand 均匀分布的样本值
    • randint 给定上下限的随机整数
    • randn 标准正态分布
    • binomial 二项分布
    • normal 正态分布
    • chisquare 卡方分布
    • gamma Gamma分布
    • uniform [0,1]之间的均匀分布



  • 相关阅读:
    fullCalendar改造计划之带农历节气节假日的万年历(转)
    Linked List Cycle
    Remove Nth Node From End of List
    Binary Tree Inorder Traversal
    Unique Binary Search Trees
    Binary Tree Level Order Traversal
    Binary Tree Level Order Traversal II
    Plus One
    Remove Duplicates from Sorted List
    Merge Two Sorted Lists
  • 原文地址:https://www.cnblogs.com/siucaan/p/9623151.html
Copyright © 2011-2022 走看看