当前位置: 首页 > news >正文

Numpy数组中的运算与拼接,看这篇就够了

上一篇数据分析的文章我们介绍了Numpy的索引和切片,用于获取Numpy数组的元素。我们也提到Numpy中ndarray对象是类似列表的,但是也有区别比如:

  • 数组对象内的元素类型必须相同

  • 数组大小不可修改

列表可以使用的符号有:+ 、* 、in,那在ndarray中能使用的有哪些?

本篇文章主要介绍Numpy数组的一些运算和拼接内容。

广播机制

在Numpy中当数组进行运算时,如果两个数组的形状相同,那么两个数组相加就是两个数组的对应位相加,这是要求维数相加,并且各维度的长度相同。比如:

import numpy as np

data1 = np.arange(9,dtype=np.int32).reshape(3,3)  # 维数是(3,3)
data2 = np.ones((3,3),dtype=np.int32)  # 维数是(3,3)
# 两个相加
print(data1+data2)

原来两个数是:

[[0 1 2]
 [3 4 5]
 [6 7 8]]
[[1 1 1]
 [1 1 1]
 [1 1 1]]

相加之后的结果:

[[1, 2, 3],
 [4, 5, 6],
 [7, 8, 9]]

当运算中两个数组的形状不同使时,numpy将会自动触发广播机制,那什么是广播机制呢?

复习下数学知识😂,在线性代数中我们曾经学到过如下规则:

a1 =3 ,a2 = 4,a1,a2是0维张量,即标量;

 b1,b2是1维张量,即向量;

c1,c2是如下所示的2维张量,即矩阵:

a1与a2之间可以进行加减乘除,b1与b2可以进行逐元素的加减乘除运算,c1与c2之间可以进行逐元素的加减乘除以及矩阵相乘运算(矩阵相乘必须满足维度的对应关系),而a与b,或者b与c之间不能进行逐元素的加减乘除运算,原因是他们的维度不匹配。而这种在数学方面的不可能在NumPy中,就可以通过广播完成这项操作。 

再比如:

import numpy as np

data1 = np.arange(9,dtype=np.int32).reshape(3,3)  # 维数是(3,3)
print(data1+1)

此时data1是3行3列的矩阵,跟一个1进行运算,能否成功呢?在Numpy中这时ok的,data1中的每个元素都会跟1相加而得到一个新的矩阵,这就是广播机制。

所以结果就是:

[[1 2 3]
 [4 5 6]
 [7 8 9]]

如果是跟一个3行1列的进行加法呢?

import numpy as np

data1 = np.arange(9,dtype=np.int32).reshape(3,3)  # 维数是(3,3)
data2 = np.array([[1],[2],[3]])
print(data1+data2)

这个操作也是ok的,结果是:

[[ 1  2  3]
 [ 5  6  7]
 [ 9 10 11]]

如果是跟一个2行3列的数据进行加法运算呢?

import numpy as np

data1 = np.arange(9,dtype=np.int32).reshape(3,3)  # 维数是(3,3)
data2 = np.array([[1,2,3],[1,1,1]])
print(data1+data2)

此时会报错:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-f381f9bc5a62> in <module>
----> 1 print(data1+data2)

ValueError: operands could not be broadcast together with shapes (3,3) (2,3)

报错的原因是什么呢?我们一起来看一张图

所以广播的规则是:

  1. 形状相同的广播

 import numpy as np
 
 data1 = np.arange(9,dtype=np.int32).reshape(3,3)
 print(data1+data1)
  1. 相同维度,但其中某一个或多个维度长度为 1 的广播:

 import numpy as np
 
 data1 = np.arange(9,dtype=np.int32).reshape(3,3)  # 维数是(3,3)
 data2 = np.array([[1],[2],[3]])
 print(data1+data2)
 
 data2 = data2.T
 print(data1+data2)
  1. 如果是标量的话,会广播整个数组上

 import numpy as np
 
 data1 = np.arange(9,dtype=np.int32).reshape(3,3)  # 维数是(3,3)
 print(data1+5)

所以我们要首先了解numpy的广播机制,接下来才能更好的进行数组的运算。

numpy数组的运算

加法

其实上面我们已经使用了数组的加法运算,而在运算中是使用广播机制的。假设我们现在有这样的两组数据:

import numpy as np

data1 = np.arange(12,dtype=np.int32).reshape(3,4)  # 维数是(3,3)
data2 = np.ones((3,1))
print(data1+data2)

结果:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

减法

print(data1-data2)

结果:

[[-1  0  1  2]
 [ 3  4  5  6]
 [ 7  8  9 10]]

乘法

print(data1*data2)

结果:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

除法

print(data1/data2)

结果:

[[ 0.  1.  2.  3.]
 [ 4.  5.  6.  7.]
 [ 8.  9. 10. 11.]]

当然还有整除和幂运算

data2 = np.array([2,2,2,2])
print(data1//data2)

结果:

[[0 0 1 1]
 [2 2 3 3]
 [4 4 5 5]]

如果是幂运算呢?

print(data1**data2)

结果:

[[  0   1   4   9]
 [ 16  25  36  49]
 [ 64  81 100 121]]

当然数组也可以进行比较,也是会自动应用广播机制

import numpy as np
arr1=np.array([[1,2,3],[4,5,6]])
arr2=np.array([[1,1,1],[1,1,1]])
print(arr2>arr1)

结果:

[[False, False, False],
 [False, False, False]]

拼接

Numpy中提供了concatenate,append, stack类(包括hsatck、vstack、dstack、row_stack、column_stack),r_和c_等类和函数用于数组拼接的操作。

各种函数的特点和区别如下表:

在我们学习拼接之前我们先了解一些轴和维度。

上一篇我们提到numpy中的ndim和shape来分别查看维度,以及在对应维度上的长度的。而其中的axis表示的是轴

concatenate函数

concatenate(tuple, axis=0, out=None)
"""
参数说明:
tuple:对需要合并的数组用元组的形式给出
axis: 沿指定的轴进行拼接,默认0,即第一个轴
"""

比如我们有两个数组:

 

所以是对两个数组进行了axis=0轴的合并,如果将axis换成1则变成:

append函数

函数的说明如下:

append(arr, values, axis=None)
"""
参数说明:
arr:类似array的数据
values: 类似array的数据
axis:进行append操作的axis的方向,默认无
"""

代码示例:

 

大家发现,若axis为None,则先将arr和values进行ravel扁平化,再拼接;如果指定axis=0表示x轴的拼接,而如果axis=1表示y轴的拼接。

stack函数

函数的说明如下:

stack(arrays, axis=0, out=None)
"""
沿着指定的axis对arrays(每个array的shape必须一样)进行拼接,返回值的维度比原arrays的维度高1
axis:默认为0,即第一个轴,若为-1即为第二个轴
"""

代码演示:(仍然使用上面的data1和data2)

可以发现如果axis=1,就是x轴的依次进行组合,如果是axis=-1就是两个数组的列进行组合。当然如果想直接进行行或者列的拼接也可以使用:hstack、vstack分别表示只进行行的拼接,或者列的拼接,类似上面的axis=1或axis=-1的情况。

总结:

增加行(对行进行拼接)的方法有

np.concatenate((ar1, ar2),axis=0)
np.append(ar1, ar2, axis=0)
np.vstack((ar1,ar2))

增加列(对列进行拼接)的方法有:

np.concatenate((ar1, ar2),axis=1)
np.append(ar1, ar2, axis=1)
np.hstack((ar1,ar2))

内容比较多,大家要多多练习哦!

-END-

扫码添加请备注:python,进群与宋老师面对面交流:517745409

 

相关文章:

  • Docker网络模型
  • U9二次开发之补丁制作
  • 数字孪生与元宇宙相比有何区别?
  • java计算机毕业设计计算机散件报价系统源码+数据库+系统+lw文档+mybatis+运行部署
  • Qt Quick/QML入门到精通_专栏demo对应文章目录(目前27个demo/长期更新)
  • Java并发 | 17.[锁机制] 重量级锁(Monitor+自旋锁)
  • 【我拥有的书】
  • MSP432P 汇编,C语言点灯
  • Tomcat部署及优化
  • Kubernetes中Pod容器的使用
  • BERT模型解析
  • Springboot整合dubbozookeeper为注册中心
  • Spark的部署与使用
  • 目标检测——关键点检测学习记录(二):人体骨骼点检测——自顶向下
  • C++----类型转换
  • CSS3 变换
  • JSONP原理
  • Linux下的乱码问题
  • Map集合、散列表、红黑树介绍
  • Meteor的表单提交:Form
  • Nacos系列:Nacos的Java SDK使用
  • PAT A1017 优先队列
  • React-生命周期杂记
  • sessionStorage和localStorage
  • session共享问题解决方案
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • 成为一名优秀的Developer的书单
  • 飞驰在Mesos的涡轮引擎上
  • 复杂数据处理
  • 两列自适应布局方案整理
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 如何使用 JavaScript 解析 URL
  • 使用权重正则化较少模型过拟合
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (3)选择元素——(17)练习(Exercises)
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (六)激光线扫描-三维重建
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (转)Oracle 9i 数据库设计指引全集(1)
  • ... 是什么 ?... 有什么用处?
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET : 在VS2008中计算代码度量值
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET 表达式计算:Expression Evaluator
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .NET/C# 的字符串暂存池
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件