目录:
表之间的操作
熟悉SQL语言的读者对连接的概念应该不会陌生,连接就是把两个或者多个表按照一定的逻辑组合起来。MATLAB的table对象也支持表之间的连接运算,包括内连接,左右连接,全连接。为了节省篇幅,这节略去table对象的构造过程,直接介绍各种连接函数和连接的结果。(本节Employee和Department的例子参考了维基SQL条目)下例表
Table.1 和
Table.2 是要使用的原始数据:
Table.1 Employee表A
Employee
DepartmentID
Rafferty
31
Jones
33
Steinberg
33
Robinson
34
Smith
34
Jasper
35
Table.2 Employee表B
DepartmentID
DepartmentName
31
Sales
32
Foundation
33
Engineering
34
HR
35
Marketing
Table.1 中有员工的LastName和所在部门的号码,而表
Table.2 中有部门号码对应的名字,如果我们想知道每个员工所在部门的名字,要查两次表:首先从表
Table.1 得到某员工所在部门的号码,再通过这个号码去到表
Table.2 中去找到对应的名字,这样做不是很方便。
如果能把表
Table.2 和表
Table.2 中的DepartmentID“对上”,从而构造出一个有三列数据的新表,并且其中三列分别是LastName,DepartmentID,DepartmentName,那么就只用查一次表了,这个操作其实就是table的join操作。
% join
>> t1 = join(A,B) % join的第一个参数叫做左表,第二个参数叫做右表
t1 =
LastName DepartmentID DepartmentName
___________ ____________ ______________
'Rafferty' 31 'Sales'
'Jones' 33 'Engineering'
'Steinberg' 33 'Engineering'
'Robinson' 34 'HR'
'Smith' 34 'HR'
'Jasper' 35 'Marketing'
其中join函数的第一个参数叫做左表,第二个参数叫做右表。
t1用表格形式表示如
Table.3 所示,请读者自行核对。为了说明左连接,右连接和全连接,我们把表
Table.1 稍作修改,把最后一行Jasper的DepartmentID改成36,如表
Table.4
Table.3 join(A,B)
Employee
DepartmentID
DepartmentName
Rafferty
31
Sales
Jones
33
Engineering
Steinberg
33
Engineering
Robinson
34
HR
Smith
34
HR
Jasper
35
Marketing
Table.4 Employee表C
Employee
DepartmentID
Rafferty
31
Jones
33
Steinberg
33
Robinson
34
Smith
34
Jasper
36
所谓左连接,即连接结果表中将包含"左表"的所有记录, 即使那些记录在"右表" 没有符合连接条件的匹配。
% 左连接
>> t3 = outerjoin(C,B,'Type','left','MergeKeys',true)
t3 =
LastName DepartmentID DepartmentName
___________ ____________ ______________
'Rafferty' 31 'Sales'
'Jones' 33 'Engineering'
'Steinberg' 33 'Engineering'
'Robinson' 34 'HR'
'Smith' 34 'HR'
'Jasper' 36 '' %<-----
观察t3的结果,其中左表
Table.4 中Jasper的DepartmentID是36,在表
Table.2 中没有任何对应的行,但是左连接的结果t3中仍然保存了Japser项,并且其对应的DepartmentName为默认空字串。
所谓右外连接, 与左外连接完全类似, 只不过是作连接的表的顺序相反而已. 如果“左表”右连接“右表”, 那么"右表" 中的每一行在连接表中至少会出现一次.
如果 “右表”的记录在"左表"中未找到匹配行, 连接表中来源于“左表”的列的值设为默认空值。右表
Table.2 中的DepartmentID 35和36在表
Table.4 都没有任何员工与之对应,但是右连接的结果t4保留了这些没有员工对应的Department。
% 右连接
>> t4 = outerjoin(C,B,'Type','right','MergeKeys',true)
t4 =
LastName DepartmentID DepartmentName
___________ ____________ ______________
'Rafferty' 31 'Sales'
'' 32 'Foundation' %<-----
'Jones' 33 'Engineering'
'Steinberg' 33 'Engineering'
'Robinson' 34 'HR'
'Smith' 34 'HR'
'' 35 'Marketing' %<-----
全连接是左右外连接的并集. 连接表包含被连接的表的所有记录, 如果缺少匹配的记录, 即以默认值填充。这允许我们查看每一个在部门里的员工和每一个拥有雇员的部门, 同时, 还能看到不在任何部门的员工以及没有任何员工的部门
% 全连接
t5 = outerjoin(C,B,'MergeKeys',true)
t5 =
LastName DepartmentID DepartmentName
___________ ____________ ______________
'Rafferty' 31 'Sales'
'' 32 'Foundation' %<-----
'Jones' 33 'Engineering'
'Steinberg' 33 'Engineering'
'Robinson' 34 'HR'
'Smith' 34 'HR'
'' 35 'Marketing' %<-----
'Jasper' 36 '' %<-----
内连接(inner join)是应用程序中用的普遍的"连接"操作,它一般都是默认连接类型。内连接基于连接谓词,即DepartmentID,将两张表的列组合在一起,产生新的结果表。查询会将 A 表的每一行和 B 表的每一行进行比较,并找出满足连接谓词的组合
% 内连接
>> t5 = innerjoin(C,B)
t5 =
LastName DepartmentID DepartmentName
___________ ____________ ______________
'Rafferty' 31 'Sales'
'Jones' 33 'Engineering'
'Steinberg' 33 'Engineering'
'Robinson' 34 'HR'
'Smith' 34 'HR'
t1和t5的结果类似,join和innerjoin的区别在于join对两个表的契合度要求更高,表1中的Key一定要在表2中也出现,如果尝试连接表3和表2,因为表C的Jasper的DepartmentID变成了36,而36在表2中不存在,MATLAB报错如下:
% join报错
>> join(C,B)
Error using table/join (line 130)
The key variable for B must contain all values in the key variable for A.
>> [a b] = lasterr
a =
Error using table/join (line 130)
The key variable for B must contain all values in the key variable for A.
b =
MATLAB:table:join:LeftKeyValueNotFound
最后做个总结,table是MATLAB从R2013b开始新引入的一个类(数据类型)。用UML(Unified Modeling Language)中的类图,可以表示如图
Figure.1
Figure.1 table的Class Diagram
图
Figure.1 中的属性除Properties外都是私有属性,即不可以用dot语法直接访问
% 通过Properties这个中间属性来访问table的其它属性
>> t1.VariableNames
You can not access the 'VariableNames' property directly. Access it using dot subscripting via .Properties.VariableNames.
按照错误信息的提示,我们可以通过Properties这个metadata来访问这些属性,表\ref{map_phone_book_table}对应的table中的Properties将返回如下的内容
% Properties作为访问table其它属性的中间层
>> t1.Properties
ans =
Description: ''
VariableDescriptions: {}
VariableUnits: {}
DimensionNames: {'Row' 'Variable'}
UserData: []
RowNames: {}
VariableNames: {'Name' 'Number'}
>> t1.Properties.VariableNames
ans =
'Name' 'Number'
图
Figure.1 中的中Import and export,Size and Shape, set, Data Organization操作代表一些列可以施加在table上的方法的集合。我们可以通过help命令来得到该类的帮助信息:
>> help table
其中有这些方法的介绍,这里大致罗列如下,方便读者查阅。
Import and export类的操作
eadtable 读入一个文件,创建table对象
writetable 普通函数,把table写入一个文件,内部调用write
write 类方法,把table写入一个文件
Size and shape类的操作
istable 判断一个变量是否是table类型
size 返回table的高和宽,表头不计
width 返回table的宽
height 返回table的高
ndims 返回table的维度
numel 返回table高和宽的乘积
horcat 横向串接table
vercat 纵向串接table
Set membership类的操作
intersect 返回两表中的相同的行
ismember 查询表中的行是否在另一表中也出现
setdiff 查询两表之间的差异
unique 返回的表中没有相同的行
sextor 两个集合交集的非
union 两个集合的并
join 自然连接
innterjoin 内连接
outerjoin 外连接
Data organization的操作
summary 返回table的基本信息
sortrows 给table按照制定的row排序
stack 把table的各列摞成一列
unstack 把table的某一列展开成为若干列
ismissing 找到table中那些没有赋值的项,返回logical index
standizeMissing 给未赋值项赋默认值
varfun 把函数作用在table中选定的变量上
rowfun 把函数作用在table的每列上
关于作者
oopmatlab ,计算物理博士,计算机硕士,
《MATLAB面向对象编程-从入门到设计模式》 作者,现就职一家科学工程计算公司的任架构组C++软件工程师。业余兴趣包括如何把软件工程中的现代手段,应用到科学和工程计算当中去,来更好的解决复杂的问题。包括如何从整体上设计科学计算程序的结构;如何让程序便于扩展和修改;在改进和开发算法的时候,如何保证程序已有的功能没有收到影响;如何让算法开发和测试系统的建立齐头并进。
声明:
本文内容所有内容仅代表个人观点,如有任何问题,请联系作者。
本版块所有文章版权归作者个人所有,未经允许,不得作为出版物出版。如需转载,请联系论坛管理员 。