小蛇学python(16)numpy高阶用法

作者: 跌跌撞撞小红豆 | 来源:发表于2018-07-12 15:25 被阅读91次

    如果只是从事简单的数据分析,其实numpy的用处并不是很大。简单了解一下numpy,学好pandas已经够用,尤其是对于结构化或表格化数据。但是精通面向数组的编程和思维方式是成为python科学计算牛人的关键一步。

    而且使用numpy的代码往往比普通数组要快,因为数组运算一般都比纯python循环要快得多。大量使用列表,将无可避免的使用循环。

    当大家对numpy足够熟悉的时候,我建议大家这样做:

    1. 将python循环和条件逻辑转换为数组运算和布尔数组运算。
    2. 尽量使用广播。
    3. 避免复制数据,尽量使用数组视图,即切片。
    4. 利用ufunc及其它各种方法。

    线性代数

    import numpy as np
    
    x = np.array([[1, 2, 3], [4, 5, 6]])
    
    y = np.array([[6, 23], [-1, 7], [8, 9]])
    print(x)
    print(y)
    
    print(x.dot(y))
    
    
    image.png

    这是最基础的矩阵计算。比较常用的矩阵计算函数如下。

    函数 说明
    diag 以一位数组形式返回对角线元素
    dot 矩阵乘法
    trace 矩阵迹
    det 行列式值
    eig 本征值与本征向量
    inv 求逆
    pinv Moore-Penrose伪逆
    qr QR分解
    svd 奇异值分解
    solve 解线性方程组Ax=b
    lstsq 计算Ax=b的最小二乘解

    高级数据操作

    ndarray数组视图不复制任何数据的原因是因为,ndarray不只是一块内存和一个dtype,更准确的说它还有跨度信息,这使得数组能以各种步幅在内存中移动。(其实移动的是指针)也因此,ndarray数组有很多我们意想不到的功能。

    import numpy as np
    
    arr = np.arange(8)
    print(arr)
    new_arr = arr.reshape((4, 2))
    print(arr)
    print(new_arr)
    
    image.png

    同样,既然可以重塑,那也可以扁平化,即展开。

    import numpy as np
    
    arr = np.arange(8)
    new_arr = arr.reshape((4, 2))
    print(new_arr)
    new_new_arr = new_arr.ravel()
    print(new_new_arr)
    
    
    image.png

    在这里要提及一点。与其他科学计算环境相反(R或matlab),numpy允许更为灵活地控制数据在内存中的布局。具体来说,比如展开数组时是按列优先还是按行优先。

    pandas的操作对象主要是结构化数据,numpy的操作对象主要是ndarray数组。这两者之间有很多功能函数是一一对应的,比如,pandas有对表格的拼接,ndarray也有对数组的拼接。

    import numpy as np
    
    arr1 = np.array([[1, 2, 3], [4, 5, 6]])
    arr2 = np.array([[7, 8, 9], [10 ,11, 12]])
    print(np.concatenate([arr1, arr2], axis=0))
    print(np.concatenate([arr1, arr2], axis=1))
    
    image.png

    有拼接就有拆分,split函数用于将一个数组沿指定轴拆分为多个数组。

    import numpy as np
    from numpy.random import  randn
    
    arr = randn(8, 2)
    first, second, third = np.split(arr, [2, 3])
    print(first)
    print(second)
    print(third)
    
    image.png

    还有很多功能不一一介绍,其实非常简单,在这里只是引起大家注意,知道numpy功能的强大。

    还需要注意一点的是,这些函数都是建立在ndarray数组之上的,列表,元组等并无此功能

    广播机制

    所谓广播是说不同形状的数组之间的算术运算的执行方式。

    将标量值和数组进行组合时就会发生最简单的广播。

    import numpy as np
    
    
    arr = np.arange(5)
    print(arr)
    print(arr-1)
    
    image.png

    如图所示,当数组和数字之间运算时,并没有报错,而是每个数组元素和该数字做了运算。这在很多科研数据处理的时候,会方便很多。

    ufunc高级应用

    ufunc除了一些通用的施行特定矢量化运算的特殊方法外,还可以自定义函数对数组进行运算。

    import numpy as np
    
    def add_elements(x, y):
        return x + y
    
    add_them = np.frompyfunc(add_elements, 2, 1)
    print(add_them(np.arange(8), np.arange(8)))
    
    image.png

    当然,不幸的是,这种创造ufunc的手段虽然很灵活,却非常慢。因为它们在计算的时候都要执行一次python函数调用,这自然会比numpy自带的基于C编写的ufunc慢很多。

    为此,python科学计算社区正在开发一些项目,力求使自定义ufunc的性能接近内置的那些。

    相关文章

      网友评论

        本文标题:小蛇学python(16)numpy高阶用法

        本文链接:https://www.haomeiwen.com/subject/dnfrpftx.html