• 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]之间的均匀分布



  • 相关阅读:
    深刻剖析spring三种注入方式以及使用注解的原理
    springcloud(一):大话Spring Cloud
    springcloud学习资料汇总
    springboot(一):入门篇
    springboot学习资料汇总
    jvm系列(七):如何优化Java GC「译」
    jvm系列(六):Java服务GC参数调优案例
    jvm系列(五):Java GC 分析
    jvm系列(四):jvm调优-命令篇
    android view、viewgroup 事件响应拦截处理机制
  • 原文地址:https://www.cnblogs.com/siucaan/p/9623151.html
Copyright © 2020-2023  润新知