• 数据分析与数据挖掘


    一 认识科学计算

    在人工智能的研发中,其本质就是把一切问题转化为数学问题,所以数学运算非常重要。很多数学运算采用的都是numpy这个库,因为它提供了非常多的科学计算的方法,能让我们的工作变得非常便利,这一章我将从numpy的基本使用开始,逐渐解决掉那些数学问题,让Python与数学能够更紧密的结合在一起。

    二 认识numpy

    numpy的本质其实还是一个多维数组,虽然我们之前学习过数组对象(Python中的list或者tuple)和numpy的数据看似一样,但是数组是无法直接参与数值运算的,而numpy对象却可以。

    三 数组创建

    import numpy as np
    
    arr1 = np.array([1, 2, 3, 4, 5, 6])
    arr2 = np.array([[1, 2, 3, 4, ], [5, 6, 7, 8, ]])
    print(arr1, arr1.shape, arr1.dtype)
    print(arr2, arr2.shape, arr1.dtype)  # shape获取数组形状2行4列,dtype获取数组中元素类型
    

    如果我们创建数组时,元素类型不一样,numpy会给我们自动处理成一样的。

    arr3 = np.array([1, 2.5, 3])  # 只要数组元素中出现float类型,就会全部处理成float
    print(arr3, arr3.dtype)
    arr4 = np.array(['4', 5, 5.6])  # 只要数组元素中出现str,就会全部处理成str
    print(arr4, arr4.dtype)
    

    四 数组访问

    numpy的访问与Python中list或者tuple访问原理一样,方法也非常类似,只不过是加了一个纬度的概念。

    # 首先我们定义了一个二维数组
    arr5 = np.array([[1, 2, 3],
                     [4, 5, 6],
                     [7, 8, 9],
                     [10, 11, 12]])
    
    print(arr5[1])  # 第一行 [4 5 6]
    print(arr5[1][0])  # 第一行第0个 4
    print(arr5[:, 2])  # 所有行第2个 [ 3  6  9 12]
    print(arr5[:2])  # 前2行 [[1 2 3] [4 5 6]]
    print(arr5[1, :])  # 第1行所有列 [4 5 6]
    print(arr5[:, 1:2])  # 所有行第2到第3列 [[ 2] [ 5] [ 8] [11]]
    

    对于二维来说,如果有逗号,逗号前是行筛选,逗号后是列筛选。对于n维来说,第一个逗号前是第一维,后面依次是二维三维等。

    五 形状处理

    1 预览修改与真正修改

    numpy对象有一个shape属性,在Python基础中,对于形状并不敏感,而在科学计算中,形状却很重要,在后面的算法模型计算中,我们会使用地很频繁。

    # 定义一个6行3列的numpy数组对象
    arr6 = np.array([[1, 2, 3],
                     [4, 5, 6],
                     [7, 8, 9],
                     [10, 11, 12],
                     [13, 14, 15],
                     [16, 17, 18]])
    
    print(arr6.shape)  # 注意看每次打印的结果
    print(arr6.reshape(2, 9))  # 得到一个新的形状,原来的对象不变
    print(arr6.shape, arr6)
    print(arr6.resize(2, 9))  # 无返回值,真正修改
    print(arr6.shape, arr6)
    

    我们在这段代码中,分别使用了reshape和resize两种方法来对数组进行形状上的改变。其中reshape只是返回改变形状后的预览状态,或者说如果我们要使用这个结果只能把结果赋值给一个单独的变量,然后再进行使用。resize方法的返回结果为空,但是它却真正的改变了组数的形状,仔细看打印结果你就能够发现这两种形状操作方法的区别了。

    2 降维操作

    降维是人工智能算法中非常常用且重要的一个操作,原因是有时我们去描述一个事物的特征时,会有非常多的维度,但过多的维度会给我们的计算带来麻烦,这个时候我们就需要去降低它的维度,然后再进行计算。

    arr7 = np.array([[1, 10, 100], [2, 20, 200], [3, 30, 300]])
    
    # 按照数组的行顺序降至一维
    print(arr7)
    print(arr7.ravel())
    print(arr7.reshape(-1))
    print(arr7.flatten())
    
    # 按照大小顺序降至一维
    print(arr7.ravel(order="F"))
    print(arr7.reshape(-1, order="F"))
    print(arr7.flatten(order="F"))
    

    降维后再进行修改

    print('ravel:{}'.format(arr7.ravel()))
    arr7.ravel()[1] = 1000
    print(arr7)
    
    print('reshape: {}'.format(arr7.reshape(-1)))
    arr7.reshape(-1)[2] = 3000
    print(arr7)
    
    print('flatten: {}'.format(arr7.flatten()))
    arr7.flatten()[0] = 2000
    print(arr7)
    

    从结果中,我们看到通过flatten方法实现的降维返回的是复制的操作,如果要用,那么只能把结果赋值给另外的变量了。它并没有影响原来数组的结果。通过ravel和reshape两个方法,返回的则是视图,也就是通过对视图的修改,是会直接影响到原数组中的值的。

    3 数组堆叠

    arr8 = np.array([[1, 10, 100], [2, 20, 200], [3, 30, 300]])
    arr9 = np.array([1, 2, 3])
    arr10 = np.array([[5], [6], [7]])
    
    # 纵向堆叠
    print(np.vstack([arr8, arr9]))
    print(np.row_stack([arr8, arr9]))
    
    # 横向合并
    print(np.hstack([arr8, arr10]))
    print(np.column_stack([arr8, arr10]))
    

    需要注意的是:多个数组横向堆叠时,要保证行数相同,纵向合并,则要保证列数相同。

    六 基本运算

    1 四则运算

    在以前,我们如果要对两个同形状的数组进行对应位置的四则运算时,我们必须要对两个数组进行循环处理,代码量上来说并不少,并且容易出错。有了NumPy之后,这些运算将会变的非常的简单。

    import numpy as np
    
    arr1 = np.array([11, 12, 13])
    arr2 = np.array([21, 22, 23])
    arr3 = np.array([31, 32, 33])
    
    print(arr1 + arr2)
    print(arr1 + arr2 + arr3)
    print(arr1 - arr2)
    print(arr1 - arr2 - arr3)
    print(arr1 * arr2)
    print(arr1 * arr2 * arr3)
    print(arr1 / arr2)
    print(arr1 / arr2 / arr3)
    print(arr1 // arr2)
    print(arr1 % arr2)
    print(arr1 ** arr2)
    
    print(np.add(arr1, arr2))
    print(np.add(np.add(arr1, arr2), arr3))
    print(np.subtract(arr1, arr2))
    print(np.multiply(arr1, arr2))
    print(np.divide(arr1, arr2))
    

    从代码的运行结果中我们可以看到,当我们使用符号进行四则运算的时候,是可以连续进行操作的。当我们使用对象的方法进行四则运算的时候,不可以连续进行操作,因为这个方法只接收两个参数。如果我们想要对多个数组对象进行操作的时候,我们必须使用方法嵌套的方式来进行操作。除了四则运算,在学习Python基础时,所学习的取余数、整除、幂运算等都是支持的。

    2 比较运算

    print(arr1 <= arr2)
    print(arr1 == arr2)
    print(arr1 != arr2)
    
    print(np.greater(arr1, arr2))
    print(np.greater_equal(arr1, arr2))
    print(np.less(arr1, arr2))
    print(np.less_equal(arr1, arr2))
    print(np.equal(arr1, arr2))
    print(np.not_equal(arr1, arr2))
    

    从结果上看,运用比较运算符可以返回布尔类型的值,也就是True和False。那我们什么时候会用到这样的运算呢?第一种情况是从数组中查询满足条件的元素,第二种情况是根据判断的结果执行不同的操作,示例代码如下:

    arr3 = np.array([23, 12, 25])
    arr4 = np.array([21, 15, 23])
    
    print(arr3[arr3 > arr4])  # 取出arr3中元素大于arr4的
    print(arr3[arr3 > 24])  # 取出arr3中元素大于24的
    print(np.where(arr3 > 24, 0, arr3))  # 类似三元表达式,把大于24的修改成0,其他不变
    print(list(0 if x > 24 else x for x in arr3))
    print(np.where(arr4 > 16, 0, arr4))
    

    3 广播运算

    上面我们所有的运算都是基于相同形状的数组,那么当数组形状不同时,能够让它们之间进行运算吗?答案是肯定的,但是有相应的规则,不能随意计算,这种计算就叫做广播运算。

    # 1 广播运算,末尾的纬度值加上去
    arr3 = np.arange(60).reshape(5, 4, 3)
    arr4 = np.arange(12).reshape(4, 3)
    print(arr3)
    print(arr4)
    print(arr3 + arr4)
    
    # 2 纬度值有一个为1
    arr5 = np.arange(60).reshape(5, 4, 3)
    arr6 = np.arange(4).reshape(4, 1)
    print(arr5)
    print(arr6)
    print(arr5 + arr6)
    
    # 3 arr7会自动补齐,类似上面纬度值有一个为1
    arr7 = np.arange(12).reshape(4, 3)
    arr8 = np.array([1, 2, 3])
    print(arr7)
    print(arr8)
    print(arr7 + arr8)
    
    arr9 = np.arange(60).reshape(5, 4, 3)
    arr10 = np.arange(8).reshape(4, 2)
    print(arr9)
    print(arr10)
    # print(arr9 + arr10)  # 不在上述三种讨论范围内,无法运算
    

    其实,广播运算中的广播就是一对多,它的规律就是两者有相似的地方可以对应的上就能运算,缺少的部分,会自动用相同的部分补齐。

    七 数学函数

    numpy提供给我们一些常见的函数,除了np.pi或者np.e这样的常量函数,numpy也提供给我们很多数学函数供我们直接调用。

    import numpy as np
    
    arr1 = np.array([1.3, 1.5, -1.8, 2.4, 3.2])
    arr2 = np.array([1, 2, 3, 4, 5])
    
    print(np.fabs(arr1))  # 绝对值
    print(np.ceil(arr1))  # 向上取整
    print(np.floor(arr1))  # 向下取整
    print(np.round(arr1))  # 四舍五入
    print(np.fmod(arr2, arr1))  # 余数
    print(np.modf(arr1))  # 取小数部分和整数部分
    print(np.sqrt(arr2))  # 算法平方根
    print(np.square(arr2))  # 平方
    print(np.exp(arr2))  # 以e为底的指数
    print(np.power(arr2, 3))  # 各元素的3次方
    print(np.log2(arr2))  # 以2为底的对数
    print(np.log10(arr2))  # 以10为底的对数
    print(np.log(arr2))  # 以e为底的对数
    

    八 轴方向

    数组对象有几个维度就有几个轴,对于我们常见的二维数组来说,轴0是竖直方向,轴1是水平方向。

    import numpy as np
    
    arr1 = np.array([[3, 7, 25, 8, 15, 20],
                     [4, 5, 6, 9, 14, 21]])
    
    print(arr1)
    print(np.max(arr1))  # 所有数组元素最大值
    print(np.max(arr1, axis=1))  # 轴1最大值
    print(np.max(arr1, axis=0))  # 轴0最大值
    

    numpy提供了很多可以按照轴方向来计算的函数。

    print(np.min(arr1, axis=0))  # 最小值
    print(np.min(arr1, axis=1))
    print(np.mean(arr1, axis=0))  # 平均值
    print(np.median(arr1, axis=0))  # 中位数
    print(np.sum(arr1, axis=1))  # 求和
    
  • 相关阅读:
    Multi-Sensor, Multi- Network Positioning
    基于智能手机的3D地图导航
    2010上海世博会三维导航地图
    hdu 5452(树链刨分)
    蓝桥杯危险系数
    蓝桥杯横向打印二叉树(中序+先序遍历)
    蓝桥杯幸运数(线段树)
    hdu 5185(DP)
    2014江西理工大学C语言程序设计竞赛高级组题解
    uva 12730(期望经典)
  • 原文地址:https://www.cnblogs.com/mayite/p/13636770.html
Copyright © 2020-2023  润新知