最近真是很忙,python的学习都搁置了好久了,NumPy
和 Pandas
一直都在入门过程中。总不能一直这样,赶紧抽时间往前推进,也记录一下笔记。
整理学习内容是巩固和结构化存储知识的一个非常有用的办法。
PS:文中大量借用了 《A Visual Intro to NumPy and Data Representation》 的图片。这是一篇很好的直观入门教程。但是相信我,最好不要看国内网上到处机翻的这篇文章,要么看原文,要么另找国内大神的教程!切记!!
了解 NumPy
NumPy是Python中科学计算的基础包。它是一个Python库,提供多维数组对象,各种派生对象(如掩码数组和矩阵),以及用于数组快速操作的各种API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等。
NumPy包的核心是 ndarray
对象。它封装了python原生的同数据类型的 n 维数组,为了保证其性能优良,其中有许多操作都是代码在本地进行编译后执行的。
这里有个习惯,那就是引入 NumPy
所实用的别称:
数组
刚才就提到了,数组就是 NumPy
的核心了。使用NumPy提供的这些数组,我们就可以以闪电般的速度执行各种有用的操作。
创建数组
我们可以通过传递一个 python 列表并使用 np.array()
来创建 NumPy 数组。下面的图片就是简单的示例。
在实际应用中,可能经常会需要初始化数组元素的值,NumPy 很贴心的提供了 ones()
、zeros()
、random.random()
等方法。这样,我们就只需要传递需要的元素数量即可:
数组运算
我们使用到 NumPy 了,那就肯定不只是保存数据这么简单,我们需要对数组进行计算。
这里我们来定义两个数组 data = np.array([1,2])
和 ones = op.ones(2)
,然后按元素位置相加,直接输入 data + ones
即可:
同理,不只是加法,减、乘、除都是没有问题,甚至可以像下面 data * 1.6
一样直接很方便的统一运算:
广播机制
这里引入了 NumPy 的 广播机制
,上面的例子中,标量 1.6
被拉伸为张量 [1,2]
的相同尺寸(2,)的向量。标量被拉伸以后的张量尺寸与待运算值完全适配,传递到空缺位进行计算。这个规则在某些地方被称为 “低维有1”
,即 数组维度相同,其中有个轴为1 。
但其实个人觉得没有必要这么去理解!
我们可以简单的解释为:广播主要发生在两种情况,一种是两个数组的维数不相等,但是它们的后缘维度的轴长相符,另外一种是有一方的长度为1。再简化一点,两个数组在任意轴上长度或维度(或长度+维度)相等,则可以触发广播。
后面的部分我们再去详细分析。
索引与聚合
NumPy 的索引应该说非常灵活了,直接上图,非常清晰:
常见的聚合操作 sum
、min
、max
可以从下图看到运算方式:
当然,NumPy 还支持以下聚合操作:
矩阵
之前一直是从一维数组的角度来初步理解 NumPy 的使用方式,但实际上从二维数组(矩阵)开始,才算是真正有 NumPy 的用武之地。
创建矩阵
我们可以使用 np.array([[1,2],[3,4]])
的方式来创建一个矩阵,也可以使用上个部分提到的 ones()
、zeros()
和 random.random()
方法来创建:
矩阵运算
如果矩阵尺寸完全一致,那么用算数运算符 加减乘除 来处理自然是不在话下。
但是如果对不同大小的矩阵执行的话,就需要 广播机制
了,比如下面的例子:
这里我们正好可以再深入理解 广播机制
。这里的 ones_row
是二维数组,但是每个维度只有1个元素,那么我们可以理解为:data
和 ones_row
两个数组在维度上相等,可以触发广播。
点乘
虽然在这里提点乘方法 dot()
,但是不代表他必须由矩阵使用。在直接上例子说明更好理解:
细心观察,图里特意标红了 3
,因为该图的作者在强调两个矩阵的临近边必须有相同数量的维度。
简单解析一下点乘的规则。如果我们计算 np.dot(A, B)
,A为二维m*n
的矩阵,B必须为n*l
的矩阵,也就是说A有多少列,B就必须有多少行,否则无法运算。下面的图可以简单说明原理:
也就是说,可以把开始的那个点乘例子理解为:
矩阵索引与聚合
矩阵的索引使得我们对数据的操作更加得心应手:
至于聚合,除了之前一维数组提到的基本操作外,我们还可以给出 axis
参数来指定行间、列间的聚合。例如:
矩阵旋转与重塑
又是两个超实用的方法。首先是旋转矩阵,例如需要对两个矩阵执行点乘运算并对齐它们共享的维度时,我们就可以用方法 T
来执行:
在某些情况下,我们得到的数据(例如问卷采集、爬虫等)并不符合计算模型的要求,这是我们就可以用 reshape()
来重塑这些数据集:
N维数组
好了,现在可以回到我们一开始提到的 ndarray
对象了, n dimension array ,N维数组。
创建三维数组
在 NumPy 中,多加一个维度有时只是多加一个参数的事儿:
三维数组运算
其他基础运算无需多提,只是在这里可以特别把三维数组的 广播机制
拿出来强调一下,这样可以加深我们对它的理解。
我们来看这个情况:
这个情况里,(3,4,2)
和 (4,2)
的维度是不相同的,前者为3维,后者为2维。但是它们后缘维度的轴长相同,都为 (4,2)
,所以可以沿着0轴进行广播。
再想象一下其他情况,例如 (4,2,3)
和 (2,3)
是可以计算的,甚至 (4,2,3)
和 (3)
也是可以计算的。只是后者需要在同时两个轴上面进行扩展。
公式
这个部分我还没有学习太多,但是有个初步了解。例如我们可以看到,均方差公式:
是如何在 NumPy 中实现的:
精彩的就是,NumPy毫不关心 predictions
和 labels
分别有多少个值,只要他们长度对齐,就一定会得出结果。
顺带说下,均方差公式是监督机器学习模型处理回归问题的核心。
数据表达
其实通过抽象思维,很多现实中的资料、现象都可以数据化,从而进行处理、构建模型。在 NumPy 的学习更深入以后,我会继续学习的 Pandas 也是基于 NumPy 构建的。
表格
表格应该是最好理解的了,因为通常它就是1个或多个二维数组。
音频
一条音轨可以视为一维数组,每个数字代表音频信号的一部分。例如CD 质量的音频每秒包含 44,100 个样本,每个样本是-65535 到 65536 之间的整数,想要提取音频的第一秒,只需将文件加载到 audio 的 NumPy 数组中,然后获取 audio[:44100]
。
图像
图像也是经典的像素矩阵。如果图像是灰度,则每个像素可以使用单个数字表示 0-255 的灰度值,整张图就可以使用二维数组来表达:
如果是彩色图像,那每个像素就需要三个值RGB(如果不考虑透明度的话),那整张图就需要一个三维数组来表达:
语言
这部分挺有意思,虽然我还没有办法实践,但是也花了相当多实践去理解它是如何实现和表达的。
这里有个关键概念 词嵌入(embeddings)
。它是指把一个维数为所有词的数量的高维空间嵌入到一个维数低得多的连续向量空间中,每个单词或词组被映射为实数域上的向量。
其实最后的数据图相对更难理解,但是我相信通过下图,反而会很好理解:
上图是问卷对于一个人的特征进行表达(参见 《The Illustrated Word2vec》 )。如果能从上图得到一些启发,那么回到我们说的更直观的语言,或者说文学,我们就可以更好的理解了。
首先我们将一段英文按单词拆分为词汇表,然后使用 词汇向量化
转化为 嵌入值
(原文是50维词汇向量化)。
这样,就得到了一个基于 词嵌入维度 * 序列长度
的数据表达。别看第一眼觉得好像很抽象,实际上我们平时一致在使用的输入法、智能音箱等等,都在使用相应的自然语言处理相关内容。
体会
emmm...确实没想到只是入个门而已,最后查了无数资料,学了这么久 ????
多查资料多实践,时刻提醒自己不要妄想妄言。
路还很长,学无止境。
[2022年12月31日原始发布于本作者博客]
????点击“阅读原文”可恢复文章内所有链接哦!
阅读原文:https://www.gsgundam.com/2022/2022-12-31-z14-introduction-of-python-numpy/