MATLAB table数据结构 再篇

2016-3-10 01:33| 发布者: ilovematlab| 查看: 38123| 评论: 0|原作者: oopmatlab

摘要: MATLAB table是R2013b中引入的一个新的数据结构,虽然不像常用的基本数据类型为人熟悉,但是在编程中非常有用。它用来存放表状类型的数据结构,并且支持常见的表和表之间的运算。 ... ... ... ... ... ...

文章PDF浏览下载链接

目录:

table的操作

删除行列

删除一个table中的某行只需要对该行置空即可:
% 删除行
>> nasdaq(3,:) =[]
nasdaq = 
    Symbol          Name          MarketCap     IPOYear
    ______    ________________    __________    _______

    'AAPL'    'Apple Inc'         '$742.63B'    1980   
    'AMZN'    'Amazon.com Inc'    '$173.33B'    1997     
以上是nasdaq中的第三行MSFT被删除后的结果。 同理,删除一个table中的某列也只需要对该列置空,在上面删除了第三行之后,下面的代码继续删除第2列,于是nasdaq变成一个2行3列的table。
% 删除列
>> nasdaq(:,2) =[]
nasdaq = 
    Symbol    MarketCap     IPOYear
    ______    __________    _______

    'AAPL'    '$742.63B'    1980   
    'AMZN'    '$173.33B'    1997     
删除列还可以通过Dot的语法,只需对表的VariableName置空即可
% 删除行
>> nasdaq.IPOYear=[]
nasdaq = 
    Symbol    MarketCap 
    ______    __________

    'AAPL'    '$742.63B'
    'AMZN'    '$173.33B'  

添加行列

沿用上节中的Nasdaq的数据,假设我们要给表中添加一列,名字叫做Sector,该列关于公司的文字的描述,可以通过Dot语法来完成
% 添加列
nasdaq.Sector={'Computer Manufacturing';...
                'Consumer Services';...
                'Computer Software'}  
注意,这里等式的右边是一个列向量元胞,结果显示如下:
%  table新增了Sector列
Symbol            Name             MarketCap     IPOYear             Sector         
______   _______________________   __________    _______    ________________________
 'AAPL'   'Apple Inc'               '$742.63B'    1980       'Computer Manufacturing'
 'AMZN'   'Amazon.com Inc'          '$173.33B'    1997       'Consumer Services'     
 'MSFT'   'Microsoft Corporation'   '$346.9B'     1986       'Computer Software'
  
前节提到,把table中的行数据取出来,该行的数据类型仍然是table。同理,如果想要给table添加一行,该行也必须是一个table,可以通过下面的方法给table添加行:
% 给table添加行
newCell={ 'FB','Facebook Inc.','$ 231.62B',2012,'Computer Software'}    
newTable = cell2table(newCell)
newTable.Properties.VariableNames = {'Symbol','Name','MarketCap','IPOYear','Sector'};
newNasdaq =[nasdaq;newTable]  
其中第1行先构造一个包含数据的元胞,第二行把该元胞转成一个table,但是尚未指定表头,第三行指定表头,第四行把nasdaq和新建的table进行串接构成新的table。

合并table

合并table可以理解成给已有的table添加多个行或者列。如图Figure.1,Figure.2 所示:
Figure.1 横向合并table
Figure.2 纵向合并table
Figure.1横向合并示例如下,已有两个电话号码簿table, 分别是t1和t2:
t1 = 
      Name          Number   
    _________    ____________

    'Abby'       '5086470001'
    'Bob'        '5086470002'
    'Charlie'    '5086470003'  
t2 = 
     Name         Number   
    _______    ____________

    'Dave'     '5086470004'
    'Eric'     '5086470005'
    'Frank'    '5086470006'
横向合并table可以使用MATLAB的数组串接的语法,如下左做所示;或者直接调用vertzcat函数(table类重载了vercat函数,左边的代码将触发对vercat的调用),如下代码框右所示:
% 直接串接table
>> new_t =[t1  ; t2] 
new_t = 
      Name          Number   
    _________    ____________

    'Abby'       '5086470001'
    'Bob'        '5086470002'
    'Charlie'    '5086470003'
    'Dave'       '5086470004'
    'Eric'       '5086470005'
    'Frank'      '5086470006'
% 使用vertcat
>> new_t = vertcat(t1,t2)
new_t = 
      Name          Number   
    _________    ____________

    'Abby'       '5086470001'
    'Bob'        '5086470002'
    'Charlie'    '5086470003'
    'Dave'       '5086470004'
    'Eric'       '5086470005'
    'Frank'      '5086470006'
Figure.2纵向合并示例如下,已有号码簿t1,以及另一个关于办公室和楼号的table
t1 = 
      Name          Number   
    _________    ____________

    'Abby'       '5086470001'
    'Bob'        '5086470002'
    'Charlie'    '5086470003'
t3 = 
    Office    Building
    ______    ________

    '331'     'A1'    
    '201'     'A2'    
    '328'     'A4' 
横向合并table可以使用MATLAB的数组串接语法(这样的直接连接似乎有些不和逻辑,Abby不一定正好对应了331 A1这一行,在Join Table 节中将完善这个例子),如下做所示
% 直接串接table
>> new_t = [t1,t3]
new_t = 
      Name          Number       Office    Building
    _________    ____________    ______    ________

    'Abby'       '5086470001'    '331'     'A1'    
    'Bob'        '5086470002'    '201'     'A2'    
    'Charlie'    '5086470003'    '328'     'A4'      
或者直接调用horzcat函数,如下代码框所示:
% 使用horzcat
>> new_t = horzcat(t1,t3)
new_t = 
      Name          Number       Office    Building
    _________    ____________    ______    ________

    'Abby'       '5086470001'    '331'     'A1'    
    'Bob'        '5086470002'    '201'     'A2'    
    'Charlie'    '5086470003'    '328'     'A4'      

操作列数据

沿用NASDAQ表所导入的table:
% nasdaq table原始数据
nasdaq = 
    Symbol             Name              MarketCap     IPOYear
    ______    _______________________    __________    _______

    'AAPL'    'Apple Inc'                '$742.63B'    1980   
    'AMZN'    'Amazon.com Inc'           '$173.33B'    1997   
    'MSFT'    'Microsoft Corporation'    '$346.9B'     1986     
其中第三列市值一项中的内容是字符串,这节通过去掉MarketCap列数据中的$和B符号,把该列转成Numerical的类型,来演示如何对整列的数据进行操作。 前节"访问table中的数据"中提到使用nasdaq.MarketCap访问table数据返回的将是一个元胞数组,所以最简单的对该table的MarketCap列的操作方法是使用cellfun。我们定义如下helper函数帮助去掉字符串开始的$和结尾的B
% helper函数
function out_num = marketcap_helper(in_string)
  out_num = str2num(in_string(2:end-1));
end  
然后直接调用cellfun,并且把得到的结果再赋给nasdaq.MarketCap,结果如下:
% 调用cellfun对table列数据进行操作
>> nasdaq.MarketCap = cellfun(@ marketcap_helper,nasdaq.MarketCap)
nasdaq = 

    Symbol             Name              MarketCap    IPOYear
    ______    _______________________    _________    _______

    'AAPL'    'Apple Inc'                742.63       1980   
    'AMZN'    'Amazon.com Inc'           173.33       1997   
    'MSFT'    'Microsoft Corporation'     346.9       1986     
table类还提供了varfun方法来进行列操作,和使用cellfun的区别是,cellfun的处理对象是table中的一部分,即元胞。而varfun处理的对象直接是table对象。下例中对Yahoo股票table的第二列7天的开盘价求均值:
% yhoo的table在命令行的显示
yhoo = 
     date       open     high      low     closing      volumn      adjusted
  __________    _____    _____    _____    _______    __________    ________
   7.3603e+05    42.57    42.92    42.18    42.68      1.0601e+07    42.68   
   7.3603e+05     43.6    43.93    42.67    42.98      1.1802e+07    42.98   
   7.3603e+05    43.98    44.24     43.4    43.44      1.1888e+07    43.44   
   7.3603e+05    44.18    44.31     43.5    44.16      1.1868e+07    44.16   
   7.3603e+05    42.08    44.38    41.97    43.99      3.0099e+07    43.99   
   7.3603e+05     43.7    43.95    42.42    42.62      2.2392e+07    42.62   
   7.3603e+05    44.06    44.43     43.7    44.11      1.1027e+07    44.11     
直接把table的第三列提供给varfun即可,注意varfun的第一个参数是函数句柄,该函数必须能够处理向量的输入
% varfun对表中的列数据进行操作
>> varfun(@mean,yhoo(:,3))
ans = 
    mean_high
    _________

    44.023     
再举一个例子,观察上表的第一列,其中日期使用整数形式的输出,难以阅读,我们可以通过datestr函数对其第一列做操作,转化成易读的字符形式
% 变换date列的数据格式
>> formatOut = 'dd-mm-yy';
>> yhoo.date = datestr(yhoo.date,formatOut)  % datestr接受table输入
yhoo = 
date      open     high      low     closing      volumn      adjusted
________    _____    _____    _____    _______    __________    ________

10-03-15    42.57    42.92    42.18    42.68      1.0601e+07    42.68   
09-03-15     43.6    43.93    42.67    42.98      1.1802e+07    42.98   
06-03-15    43.98    44.24     43.4    43.44      1.1888e+07    43.44   
05-03-15    44.18    44.31     43.5    44.16      1.1868e+07    44.16   
04-03-15    42.08    44.38    41.97    43.99      3.0099e+07    43.99   
03-03-15     43.7    43.95    42.42    42.62      2.2392e+07    42.62   
02-03-15    44.06    44.43     43.7    44.11      1.1027e+07    44.11     
有的时候,我们还需要计算一天的股价相对于收盘价的变换范围,下面的程序用最高价减去最低价,并且除以收盘价,并且把得到的结果放到一个新建的列range中去
% range列的数据来自于high low和closing列数据
>>yhoo.range = (yhoo.high - yhoo.low)./yhoo.closing
yhoo = 
date      open     high      low     closing      volumn      adjusted   range  
________    _____    _____    _____    _______    __________    ________  ________
10-03-15    42.57    42.92    42.18    42.68      1.0601e+07    42.68     0.017338
09-03-15     43.6    43.93    42.67    42.98      1.1802e+07    42.98     0.029316
06-03-15    43.98    44.24     43.4    43.44      1.1888e+07    43.44     0.019337
05-03-15    44.18    44.31     43.5    44.16      1.1868e+07    44.16     0.018342
04-03-15    42.08    44.38    41.97    43.99      3.0099e+07    43.99     0.054785
03-03-15     43.7    43.95    42.42    42.62      2.2392e+07    42.62     0.035899
02-03-15    44.06    44.43     43.7    44.11      1.1027e+07    44.11      0.01655  

排序

沿用上节"操作列数据"中处理过后的数据,现nasdaq表中第三列中的数据类型,通过调用cellfun函数变成了Numerical
% 调用cellfun对table列数据进行操作
nasdaq = 
    Symbol             Name              MarketCap    IPOYear
    ______    _______________________    _________    _______

    'AAPL'    'Apple Inc'                742.63       1980   
    'AMZN'    'Amazon.com Inc'           173.33       1997   
    'MSFT'    'Microsoft Corporation'     346.9       1986     
现在我们可以通过调用sortrows函数对三支股票的市值进行从大到小的排序,结果如下
% 根据MarketCap列数据进行排序
>> sorted = sortrows(nasdaq,'MarketCap','descend')
sorted  = 
    Symbol             Name              MarketCap    IPOYear
    ______    _______________________    _________    _______

    'AAPL'    'Apple Inc'                742.63       1980   
    'MSFT'    'Microsoft Corporation'     346.9       1986   
    'AMZN'    'Amazon.com Inc'           173.33       1997     

筛选和查找

table的下标也接受logical index, 下例选出所有股票中市值大于200B的股票
% 筛选
>> nasdaq(nasdaq.MarketCap>200,:)
ans = 
    Symbol             Name              MarketCap    IPOYear
    ______    _______________________    _________    _______

    'AAPL'    'Apple Inc'                742.63       1980   
    'MSFT'    'Microsoft Corporation'     346.9       1986     
如下选出所有股票中市值大于200B的股票并且在1985年之后IPO的股票
% 筛选
>> nasdaq( (nasdaq.MarketCap>200) & (nasdaq.IPOYear > 1985),:)
ans = 
    Symbol             Name              MarketCap    IPOYear
    ______    _______________________    _________    _______

    'MSFT'    'Microsoft Corporation'    346.9        1986     
logical index还可以提供查找功能,下例查找所有行中Symbol='AMZN' 的数据
% 查找
>> nasdaq(strcmp(nasdaq.Symbol,'AMZN'),:)
ans = 
    Symbol          Name          MarketCap     IPOYear
    ______    ________________    __________    _______
    'AMZN'    'Amazon.com Inc'    '$173.33B'    1997     

输出到文件

和readtable对应,把一个工作空间中的table写到文件中去可以使用writetable
% writetable
>> nasdaq = readtable('nasdaq.csv') 
>> wrietable(nasdaq,'mydata.csv')   
writetable默认的分割符是逗号,writetable还可以通过delimiter来设置分割符,下例空格代替逗号
% 指定分隔符
writetable(T,'mydata.txt','Delimiter',' ')
结果如下
% mydata.txt
Symbol Name MarketCap IPOYear
AAPL Apple Inc $742.63B 1980
AMZN Amazon.com Inc $173.33B 1997
MSFT Microsoft Corporation $346.9B 1986  

其它数据类型之间和table相互转换

MATLAB支持table和struct,cell,array之间的相互转换。如图Figure.3所示,下面一一介绍:
Figure.3 table和其它数据的转换
本节使用数据如表Table.1所示,内容是美元和人民币的货币转换速查表:
Table.1 美元人民币换算表
USD CNY
1 6.21
5 31.03
10 62.06
先讨论array和table之间的转化,下例第1行用数组a表示表Table.1中的内容,第6行把a转成table,表头的信息需要通过VariableNames来设置
% array2table
>> a = [1  6.21;5 31.03 ;10 62.06 ]
a =
    1.0000    6.2100
    5.0000   31.0300
   10.0000   62.0600
>> t = array2table(a,'VariableNames',{'USD' 'CNY'})   % 通过VariableNames提供表头信息
t = 
    USD     CNY 
    ___    _____
     1      6.21
     5     31.03
    10     62.06    
  
如果把table再转成array,表头的信息将会被剥去
% table2array
>> ap = table2array(t)
ap =
    1.0000    6.2100
    5.0000   31.0300
   10.0000   62.0600  
操作如图Figure.4所示:
Figure.4 table和array的转换
在讨论struct和table之间的转换,下例第1,2行给struct的field赋向量,来表示表Table.1中的内容,第3行并且把它转成table。
% struct2table
>> s.USD = [1 ; 5 ;10];
>> s.CNY = [6.21 ;31.03; 62.06];
>> t = struct2table(s)      % 输入s是标量
t = 
    USD     CNY 
    ___    _____
     1      6.21
     5     31.03
    10     62.06      
    
struct2table还接受struct是非标量的输入
% struct2table 矢量
s(1).USD = 1;
s(1).CNY = 6.21;
s(2).USD = 5;
s(2).CNY = 31.03;
s(3).USD = 10 ;
s(3).CNY = 62.06


% 输入s是矢量
t = struct2table(s)





  





s = 
1x3 struct array with fields:
    USD
    CNY
t = 
    USD     CNY 
    ___    _____
     1      6.21
     5     31.03
    10     62.06
把table转成struct,table的表头将自动变成struct的field的名称,得到的是结果是结构体数组。
% table2struct
>> sp = table2struct(t)  % non-scalar struct 
sp = 
3x1 struct array with fields:
    USD
    CNY  
操作如图Figure.5所示:
Figure.5 table和struct的转换
最后讨论cell和table之间的转换,下例用cell表示表Table.3中的内容,并且把它转成table。
Table.3 电话号码簿
姓名 电话号码
Abby 5086470001
Bob 5086470002
Charlie 5086470003
c = {'Abby', '508647001';...
     'Bob','5086470002';...
     'Charlie','5086470003'};
t = cell2table(c,...
 'VariableNames',{'Name','Number'})





  



t = 
      Name          Number   
    _________    ____________
    'Abby'       '508647001' 
    'Bob'        '5086470002'
    'Charlie'    '5086470003'
把table转成cell,table的表头将自动被剥去
% table2cell
>> c = table2cell(t)
c = 
    'Abby'       '508647001' 
    'Bob'        '5086470002'
    'Charlie'    '5086470003'  
操作如图Figure.6所示:
Figure.6 table和cell的转换


关于作者

oopmatlab,计算物理博士,计算机硕士,《MATLAB面向对象编程-从入门到设计模式》作者,现就职一家科学工程计算公司的任架构组C++软件工程师。业余兴趣包括如何把软件工程中的现代手段,应用到科学和工程计算当中去,来更好的解决复杂的问题。包括如何从整体上设计科学计算程序的结构;如何让程序便于扩展和修改;在改进和开发算法的时候,如何保证程序已有的功能没有收到影响;如何让算法开发和测试系统的建立齐头并进。

声明:
本文内容所有内容仅代表个人观点,如有任何问题,请联系作者。
本版块所有文章版权归作者个人所有,未经允许,不得作为出版物出版。如需转载,请联系论坛管理员

17

鲜花

握手

雷人

路过

鸡蛋

刚表态过的朋友 (17 人)

相关阅读

最新评论

MATLAB table数据结构 首篇

MATLAB table是R2013b中引入的一个新的数据结构,虽然不像常用的基本数据类型为人熟悉,但是在编程中非常有用。它用来存放表状类型的数据结构,并且支持常见的表和表之间的运算。 ... ... ... ... ... ...

MATLAB映射表数据结构

除了常用的基本数据类型,MATLAB还有很多其它实用的数据类型不为人熟悉,例如映射表containers.Map,常用的MATLAB高级数据类型。它最大的特点使用方便的索引方式进行快速的查找。本篇介绍为什么需要这种数据结构,以 ...

MATLAB table数据结构 再篇

MATLAB table是R2013b中引入的一个新的数据结构,虽然不像常用的基本数据类型为人熟悉,但是在编程中非常有用。它用来存放表状类型的数据结构,并且支持常见的表和表之间的运算。 ... ... ... ... ... ...

对函数的输入进行检查和解析

在工程计算中,如果函数的输入有错误,我们总是希望能尽早捕捉到这些错误,并及时终止程序。在MATLAB 中,可以使用validateattributes,validatestring和inputParser 类来对输入进行检查。它们提供全面的检查功能和清 ...

MATLAB单元测试

本篇是把现代软件工程思想应用到MATLAB工程开发中的精髓,希望高级MATLAB用户仔细研读。作者用实际的例子解释在开发和逐渐改进算法的时候,如何保证程序已有的功能没有收到影响,步步为营,让算法开发和测试系统的建 ...

MATLAB App Designer教程1-6

Mathworks在R2016a中正式推出了GUIDE的替代产品:AppDesigner, 这是在MATLAB图形系统转向使用面向对象系统之后(2014b),一个重要的后续产品,它旨在顺应Web的潮流,帮助用户利用新的图形系统方便的设计更加美观的GUI. ...

MATLAB性能测试框架

MATLAB Performance Test 框架是Mathworks 在MATLAB R2016a 中推出的⼀个新的框架,该框架⽤来获得代码性能在统计意义上的数据,还可以⽤来⽐较算法的性能,并且给出详细完整的报告。 ... ... ... ... ... ... ...

MATLAB单元测试

本篇是把现代软件工程思想应用到MATLAB工程开发中的精髓,希望高级MATLAB用户仔细研读。作者用实际的例子解释在开发和逐渐改进算法的时候,如何保证程序已有的功能没有收到影响,步步为营,让算法开发和测试系统的建 ...
关闭

站长推荐上一条 /2 下一条

返回顶部