我是一名从2007年开始工作的程序员,截至到现在主要使用C 和Java进行开发,40岁的年龄在职涯紧迫与人工智能的双重冲击下,我不得不学习Python及其热门库,以期后续能够继续靠程序员这份职业吃饭。
我的学习方式很简单,就是不停地刷Python相关的题目,以期能够在实践中完成Python生态的入门与精进!如果你也有此想法,请跟我一起来吧,今天是Numpy的第7练:在横向与纵向上堆叠数组!
横向堆叠的预期效果
纵向堆叠的预期效果
应用场景想一想如何回答上面的2道题?再想一想数组在横向或纵向上的堆叠在实际的开发过程中有哪些具体的应用场景?
在实际应用中,NumPy数组的横向或纵向堆叠非常常见,这些技术广泛应用于数据处理、机器学习、科学计算等领域。下面是一些实际案例:
- 数据处理和整合:
- 在处理不同数据源的数据时,我们可能需要将它们合并到一起以进行进一步分析。例如,假设你有两个数据集,一个包含用户的基本信息(姓名、年龄等),另一个包含用户的购买历史。通过横向堆叠(使用numpy.hstack),可以将用户基本信息与其购买历史并排放置在同一个数组中。
- 如果数据是按时间序列排列的,可能需要将新获取的数据(如新一周的销售数据)添加到现有数据集的底部。这时,可以使用纵向堆叠(使用numpy.vstack)来实现。
- 图像处理:
- 在图像处理中,堆叠可以用来合并不同的图像通道。例如,如果你分别有红色、绿色、蓝色三个颜色通道的图像数据(假设它们都是二维数组),可以通过纵向堆叠将它们合并成一个三维数组,从而形成一个完整的RGB图像。
- 同样,如果你想比较两幅图像或将它们放在一起显示,可以使用横向堆叠将它们并排放置。
- 机器学习和数据挖掘:
- 在特征工程中,可能需要将不同来源或不同性质的特征组合起来。例如,如果你有一组表示图像特征的数组和另一组表示文本特征的数组,可以通过横向堆叠将它们组合成一个更大的特征集,以便用于机器学习模型的训练。
- 在处理时间序列数据时,比如要构造一个具有时间滑动窗口特性的数据集,可以通过纵向堆叠不同时间点的数据实现。
- 实际案例
假设你正在处理一个天气数据集,其中包含了过去几年每天的最高温度和最低温度。现在你想要将这两个数据集合并,以便每一天都有一个包含最高温度和最低温度的数据点。在这种情况下,你可以使用横向堆叠将最高温度数组和最低温度数组合并成一个二维数组,其中每一行代表一天,第一列是最高温度,第二列是最低温度。这样就可以更方便地进行数据分析和可视化,比如计算每天的温差或绘制温度趋势图。
NumPy中的数组堆叠下面我将介绍如何在NumPy中以及使用原生Python方法来实现数组的横向和纵向堆叠,并探讨每种方法的优缺点以及适合的应用场景。
咱们先一起看一看当前的numpy数组a和b分别是什么,然后开始对其进行堆叠:
纵向堆叠:
- numpy.vstack (Vertical Stack):
- 优点:直观、易用,适用于当你有两个或多个数组且想按行(纵向)合并时。
- 缺点:需要所有输入数组的列数相同。
- 应用场景:合并具有相同特征空间的数据集,如时间序列数据或不同来源的相同类型数据。
- numpy.concatenate (along axis 0):
- 优点:提供了更多的灵活性,可以指定沿哪个轴进行连接。
- 缺点:稍微不那么直观,需要指定轴参数。
- 应用场景:当需要更细致控制合并方式时,如在多维数组上进行操作。
横向堆叠:
- numpy.hstack (Horizontal Stack):
- 优点:直接且易于理解,适用于需要按列(横向)合并的场景。
- 缺点:需要所有输入数组的行数相同。
- 应用场景:适用于特征扩展,例如在机器学习数据预处理中将新特征添加到现有数据集。
- numpy.concatenate (along axis 1):
- 优点:灵活性高,可以自定义合并的维度。
- 缺点:相较于hstack,需要更明确的知道各个数组的维度。
- 应用场景:适用于更复杂或多维的数组合并需求。
快捷方式法:
np.r_是NumPy中的一个非常灵活的对象,用于数组的快速横向或纵向堆叠。它实际上是一个简化的方法,用于在不同的情况下快速构造数组,可以看作是np.concatenate、np.vstack或np.hstack等函数的快捷方式。它主要通过不同的参数来控制堆叠的方式。
- 优点:极其灵活,可以根据提供的索引或切片参数进行不同类型的数组拼接。代码简洁,可以在一行内完成多种不同的堆叠操作。对于快速原型制作或交互式使用特别方便。
- 缺点:相对于np.vstack、np.hstack等函数,np.r_的使用可能不够直观,尤其是对于初学者。参数多样化导致它的行为可能难以一眼看明白,尤其是在复杂的应用场景中。
- 应用场景:当需要快速进行数组的组合和堆叠,尤其是在探索性数据分析或快速原型制作时。当需要在一个表达式内完成复杂的数组拼接操作。
我个人实测了快捷方式法,总体感觉缺点明显,那就是代码可读性差,对结果的预期不好把握,而且其针对不同维度的数组,默认行为也不尽相同!简单看几个示例:
在使用原生Python进行数组的堆叠之后,咱们需要先学习一下Python内置的zip函数,zip函数可用于将多个可迭代对象(如列表、元组、字符串等)打包成一个元组的列表。每个元组包含来自所有可迭代对象中相同位置的元素。zip函数可以接受任意数量的可迭代对象,长度不一时按最短的可迭代对象结束。这个功能非常有用于并行迭代多个可迭代对象,或者将数据组合在一起。
使用zip函数的优点:
- 简洁性:zip使代码更简洁、更易读。
- 灵活性:可以处理任意数量的可迭代对象。
- 适用性:非常适用于需要同时迭代多个序列的情况。
使用zip函数的缺点:
- 结果长度:zip处理的结果长度等于最短输入序列的长度。如果输入的可迭代对象长度不同,可能会导致一些数据无法被处理。
- 一次性:zip返回的是一个迭代器,只能遍历一次。
应用场景:
- 并行迭代:同时遍历多个列表或其他可迭代对象。
- 数据组合:将多个数据序列配对组合。
- 转置操作:将矩阵(二维列表)的行列互换。
注意,上面的图片中的*在Python中的作用是负责参数解包,所谓解包(unpacking)是指从列表、元组、字典等可迭代对象中提取元素的过程。特别是在函数调用时,解包操作允许你将列表或元组的元素分别作为独立的参数传递给函数,而不是作为单个列表或元组参数。
解包的类型:
- 序列(列表或元组)解包:将列表或元组中的元素分配给一组变量。
- 字典解包:将字典的键值对分配给一组变量。
- 参数列表解包:在函数调用时,将列表或元组的元素作为独立的参数传递给函数。
我们通过一个具体的例子就能明白参数解包到底是什么意思:
原生Python堆叠数组:
虽然在原生Python中没有直接相当于NumPy堆叠功能的函数,我们可以通过列表推导式和zip函数来模拟这些操作:
使用列表推导式:
- 优点:无需额外的库,代码简洁。
- 缺点:不如NumPy高效,适用于较小的数据集。
- 应用场景:当没有NumPy库或处理小规模数据时。
使用zip结合列表推导式:
- 优点:在不使用NumPy的情况下实现数组的并行迭代。
- 缺点:对于非常大的数据集可能不够高效。
- 应用场景:适用于需要对两组数据进行对应合并的简单场景。
不过由Python的原生堆叠方式与效果来看,语法略复杂且可读性不高,所以如果涉及到数组的堆叠,我们默认使用Numpy即可,毕竟它可以称之为AI的基石!
,好了,本期内容到此结束,如果你也想继续在代码圈摸爬滚打,就抓紧练起来吧!