前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据分析与数据挖掘 - 04科学计算

数据分析与数据挖掘 - 04科学计算

作者头像
马一特
发布2020-09-10 18:30:02
5450
发布2020-09-10 18:30:02
举报
文章被收录于专栏:马一特马一特

一 认识科学计算

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

二 认识numpy

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

三 数组创建

代码语言:javascript
复制
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会给我们自动处理成一样的。

代码语言:javascript
复制
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访问原理一样,方法也非常类似,只不过是加了一个纬度的概念。

代码语言:javascript
复制
# 首先我们定义了一个二维数组
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基础中,对于形状并不敏感,而在科学计算中,形状却很重要,在后面的算法模型计算中,我们会使用地很频繁。

代码语言:javascript
复制
# 定义一个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 降维操作

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

代码语言:javascript
复制
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"))

降维后再进行修改

代码语言:javascript
复制
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 数组堆叠
代码语言:javascript
复制
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之后,这些运算将会变的非常的简单。

代码语言:javascript
复制
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 比较运算
代码语言:javascript
复制
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。那我们什么时候会用到这样的运算呢?第一种情况是从数组中查询满足条件的元素,第二种情况是根据判断的结果执行不同的操作,示例代码如下:

代码语言:javascript
复制
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 广播运算

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

代码语言:javascript
复制
# 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也提供给我们很多数学函数供我们直接调用。

代码语言:javascript
复制
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是水平方向。

代码语言:javascript
复制
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提供了很多可以按照轴方向来计算的函数。

代码语言:javascript
复制
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))  # 求和
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 认识科学计算
  • 二 认识numpy
  • 三 数组创建
  • 四 数组访问
  • 五 形状处理
    • 1 预览修改与真正修改
      • 2 降维操作
        • 3 数组堆叠
        • 六 基本运算
          • 1 四则运算
            • 2 比较运算
              • 3 广播运算
              • 七 数学函数
              • 八 轴方向
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档