|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 uqHZau 于 2020-11-30 13:25 编辑
! o- j8 T' b% i, ?. O1 e
3 H. Z3 W/ [ c: T目录:0 ~/ Y m/ F" d3 D8 u; u. L
- table简介
- 为什么需要table数据结构
- 通过导入数据构造table对象
- 调用table构造函数来构造table对象
- 通过转换函数构造table对象
- 访问table中的数据
6 ~1 V; D+ ^- D5 M; ~' N5 S + f0 {5 } Z/ q& b1 C4 v# d2 z
MATLAB常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。除了这些基本数据类型,MATLAB还有很多其它的数据类型不为人熟悉,这些数据类型在编程中也非常有用。MATLAB高级数据类型系列旨在向大家介绍它们:比如containers.Map, tables,enumeration和time series等等,它们为什么有用,用来解决什么问题,并且怎样在科学工程计算中怎么使用。上篇我们提到了映射表结构(containers.Map )。本篇将介绍另一中新的MATLAB数据类型--table。. `4 L0 F7 x" R; L! f% x
4 D, J9 _' p) b3 B. q
table简介8 _6 t8 C! n+ B
为什么需要table数据结构
5 f5 O. H, q! j5 cMathWorks在MATLAB R2013b中引入了一种新的数据结构叫做table 。table类似统计 工具箱中的dataset ,其引入的目的就是用来取代dataset的数据类型。因为表状的数据在工程计算中越来越长久,有了table 类型,MATLAB用户就可以不用购买统计工具箱,也能使用表状的数据结构了。 table本质上来说是一种可以存放各种数据类型的容器,比如下面表Table.1中的数据,其中既有字符型,又有数值类型,其中第一行作为表头:Symbol,Name,Market,Cap,IPO, Year是各列的名字。, G1 `2 N6 K9 s; D
! _1 Y% v; `% J6 O qTable.1 NASDAQ股票名称表Symbol Name Market Cap IPO Year & q4 s* q: |; ~5 I) K
AAPLApple Inc$742.63B1980
1 m: L/ y, \; {" j( V. X5 ]* |2 SAMZNAmazon.com, Inc$173.33B1997& u0 G" ?- I$ ]) w5 K) U
MSFTMicrosoft Corporation$346.9B1986
% T7 X8 L% d) P" U$ j C在conatiners.Map的章节中,我们介绍了MATLAB的基本数据类型(比如数组,原胞数组和结构体)在表达某些复杂数据类型时的局限性。这里不再一一赘述,读者只需要认识到:数组的局限性在于不能用来存放数值以外的数据,而使用元胞读取和索引内容时有种种不方便,比如无法区分该数据中的表头和其余的行数据。事实上,如果数据存放在如下的CSV文件中,并且用importdata 直接读取表Table.2中的CSV文件。( k2 f2 I1 V5 A( H& K [& Y) i
. x1 V& V g* C& I: B% m4 LTable.2 Nasdaq 的 csv 原始数据
! B s0 h) p3 f"Symbol","Name","Market Cap","IPO Year", r! u+ L ]9 g) K q9 L3 s
"AAPL","Apple Inc","$742.63B",1980- I" } v6 I7 O' P* i" O; s$ p& i
"AMZN","Amazon.com Inc","$173.33B",1997
) Q2 m+ E' C7 L5 O" `5 J4 T"MSFT","Microsoft Corporation","$346.9B",1986
# P, l% Z8 [$ w9 M% k
' f2 C9 i$ G: c/ [6 `7 P& t读入之后数据将会被分成数值和非数值部分:: u# T+ O- ~/ p# M6 B& r- e( X
% 用importdata直接读入CSV文件7 N. [# U ` }. F+ y: A4 _
>> nasdaq = importdata('nasdaq.csv') [) X" f K/ v# x, k+ Y
nasdaq = % 结果存在struct中
3 i5 p$ t; D' Y0 Z/ h7 r) I' ? data: [3x1 double]
9 [4 r' O3 D8 k& M+ b textdata: {4x4 cell}
0 K- y( Q$ p$ a2 X) M>> nasdaq.data % csv中的数值部分
0 d3 {& p. D9 m+ V# c/ t4 Yans =8 k' e- @, K# `2 G& y
1980
. i7 s( U( N3 J. Z; j5 X 1997( b( _5 @; X8 ^! T
1986
6 S4 r0 p2 ]6 j8 t( B h>> nasdaq.textdata % csv中的字符部分/ ?2 B0 o4 d! x, ]7 @
ans = 2 Q- \+ h/ i2 \1 ]; r& P& L: ?
'"Symbol"' '"Name"' '"Market Cap"' '"IPO Year"'! F; i1 w& K# P4 i. j$ ~0 C8 {* B
'AAPL' 'Apple Inc' '$742.63B' '' $ Q" E7 o$ H& _/ O1 H9 E/ y5 p
'AMZN' 'Amazon.com Inc' '$173.33B' ''
1 f( e. Z7 S' l% ?* i0 Z% ? 'MSFT' 'Microsoft Corporation' '$346.9B' '' 3 c* V3 V* n; a) M9 ~
0 {" @: _0 ~1 F& d4 q2 Y) d* z显然这不是我们所期待的要导入格式。
S" b( n; q. y/ F. B2 h& h! }- P2 u6 C' g
通过导入数据构造table对象/ ~9 s& d, W+ q% m- j; R
沿用表Table.2中nasdaq.csv文件,我们可以使用readtable 函数,构造一个新的table对象,把csv文件中的数据导入到该对象中。readtable函数接受文件名称作为输入,返回一个table对象。0 o9 N8 X/ V' ~0 _2 F' j
+ l3 C2 ?8 M0 F H. p" U
% 通过readtable函数来构造table对象
2 v5 j2 o) n x>> nasdaq = readtable('nasdaq.csv')3 O% R% E! \0 _; d5 i
Warning: Variable names were modified to make them valid MATLAB identifiers.
) w- w% T! U9 d- jnasdaq =
n; m& h8 [* ^ Symbol Name MarketCap IPOYear( f+ X( H/ e2 f1 I- y$ L7 \( }( I$ A
______ _______________________ __________ _______( q" m% [6 o6 Q, D- b0 V
'AAPL' 'Apple Inc' '$742.63B' 1980 ) S, R& S6 F8 C; a$ A
'AMZN' 'Amazon.com Inc' '$173.33B' 1997 / z! X$ s) P* T& m' T# y8 r3 i2 h+ j
'MSFT' 'Microsoft Corporation' '$346.9B' 1986 / F4 C, B8 Z: H! l# k
( z2 H5 P3 W( g( M f注意第2行的warning,因为readtable 函数把nasdaq.csv中的第一行自动变成了这个table的表头,在创建table对象的时候,MATLAB会对做表头的文字做处理,这里把Market Cap和IPO Year两个词中的空格去掉,缩成一个词,这样做是为了方便将来使用dot语法来访问表中的数据。因为MATLAB修改了原来的表头,所以这里给出了warning。& H- L( q- i7 M6 z/ ~; }6 @
. n) G4 p1 W! L; b6 B调用table构造函数来构造table对象 q: n& }4 K5 @1 u
我们还可以通过直接调用table类的构造函数来创建table对象 (什么是类的构造函数见参加<>第2.5节,构造函数和类的名称相同)。在containers.Map 的介绍中,我们举了电话号码簿的例子,如表Table.3所示,它是我们这节要构造的table对象的原始数据8 |2 q' D' ?3 i- W
+ U) B$ l! U0 E! HTable.3 电话号码簿
* G% M8 F( x2 Q4 F
; t( U8 C5 {- h7 I( n+ x姓名 电话号码
; h( \) Z+ _1 W( ]5 i' `# qAbby50864700017 Z4 }6 O% @- A( n
Bob5086470002" I3 s$ J2 [2 ~% {
Charlie50864700034 l: z; T+ Z* R" {
下面程序中第1,2行用元胞数组来表示表中每一列的数据,第3行规定了表头的名称,第4行调用table的构造函数创建table对象,先输入数据,再输入表头的名称。表头通过table对象的VariableNames属性来设置。# X3 U9 [1 h/ g
1 V. e. D1 r" Y8 }1 [2 `. @name={'Abby';'Bob';'Charlie'}; % 3x1列向量
, F0 c( k. G+ r& _4 knumber={'5086470001';'5086470002';'5086470003'}; % 3x1列向量" W: H0 |- z/ c" @/ [+ ?9 {' y. [! K( F
colName={'Name','Number'};9 {' H/ r( g# m& B, _/ b
phonetable=table(name,number,'VariableNames',colName)
+ c( c' D/ v8 I% }9 p6 m: h+ l6 Z7 ^ V; h5 N$ n) ~
命令行显示如下
' e/ f( U1 e+ v
0 D9 t8 U& F* X& n/ h. _% phonetable在命令行中disp的结果
- z3 }" r; [$ \phonetable =
) B& h( q. N+ V7 i6 N% I Name Number
6 p& C4 H. N4 J% ] _________ ____________
Z; `. W1 y% O" @5 f& B0 `7 o- x, ]/ c2 p4 z) @# x$ Z
'Abby' '5086470001'5 p- R* q+ E5 A' a
'Bob' '5086470002'
* e2 [ o2 n1 s0 [ 'Charlie' '5086470003'
4 K+ q6 g6 z4 u+ } L
' d- s2 s7 P8 a, P9 R) A第4行把Name和Number做为table对象的VariableNames,可以这样理解VariableNames,我们可以把table看成由一个个列数据组成的数据结构,每列都是矢量,其中存放相同类型的数据。如果一个table有两列,它就有两个列矢量,每个列矢量都是table的一个变量(Variable),给变量名字就是Variable Name。5 h+ l0 W/ ^& V4 N% e
# @, Z7 b0 C* T9 w! `4 l7 F4 ^9 w/ \通过转换函数构造table对象( f% i; m9 A" N6 ^! z5 K; `
除了使用table的构造函数来创建table对象,还可以使用转换函数把其它数据类型转成table,下列通过数组数据类型类构造table。下面的程序的1-2行,我们利用financial工具箱中的fetch函数,从Yahoo财经处得到雅虎从3月1日到3月10日的股票价格,fetch函数将返回一个数组,第3行我们利用array2table转换函数把得到数组转成table。
; ~9 p6 n- K2 R, J* D; b; C: [2 R' Z7 v7 S8 z o$ ?
% 通过array2table创建table对象 / G! z8 F T6 H) Y& P9 ^+ L1 R
conn = yahoo;9 ]1 r) U; O: I, v# U6 {: J4 \
array = fetch(conn,'YHOO','3/1/2015','3/10/2015');$ W( l' \0 b* r" l4 p
yhoo = array2table(array,...
& t7 ]5 O* n$ a4 F* V 'VariableNames', {'date','open','high','low','closing','volumn','adjusted'})
2 ^2 R! v+ K' I! Q" r. V) d7 @9 f8 U, v0 E$ c
第4行中,我们通过VariableName来指定表头的内容,结果显示如下
, l" R% S1 p$ H8 O5 z- N$ F! c0 B/ T- _( E3 N
% yhoo的table在命令行的显示/ I: Q4 q J3 ?/ S
yhoo =
7 T9 [/ Z$ @2 l, r date open high low closing volumn adjusted
' @* X9 X6 \9 G( o# Z __________ _____ _____ _____ _______ __________ ________. @' {, Z, w' T
7.3603e+05 42.57 42.92 42.18 42.68 1.0601e+07 42.68
" P9 E) q* c |6 |$ B4 B 7.3603e+05 43.6 43.93 42.67 42.98 1.1802e+07 42.98
$ @* r R" F: H, p% J" W3 ? 7.3603e+05 43.98 44.24 43.4 43.44 1.1888e+07 43.44 ; u! G- i! J; f0 g* c; u6 ~7 K& x
7.3603e+05 44.18 44.31 43.5 44.16 1.1868e+07 44.16 6 _: K2 |* i. I0 R- y. ~4 q8 D
7.3603e+05 42.08 44.38 41.97 43.99 3.0099e+07 43.99 & v* ~3 b+ w r- V* }- B
7.3603e+05 43.7 43.95 42.42 42.62 2.2392e+07 42.62
: E# `' s7 h& Q$ |" Q! t: o8 ` 7.3603e+05 44.06 44.43 43.7 44.11 1.1027e+07 44.11 , j( E; O" m P/ ~$ k
7 s- O8 e8 @/ j m4 r5 X访问table中的数据7 V) m' Y. s; P+ R( Y: i
7 {" {/ t: L/ h7 M" q
通过表Table.1所建立的table对象,在命令行中显示如下:
" z; g1 u3 _- ]6 c8 ~% t3 Q/ o4 I' J( q/ a7 H( b
% nasdaq table在命令行中的显示
0 ~5 K2 s5 g E8 w' ?nasdaq =
+ M9 x9 q, R" E$ f, T' E Symbol Name MarketCap IPOYear* \9 A. g9 b. o% s& l8 D
______ _______________________ __________ _______
5 Y( X- u3 P8 _3 p# U/ i6 Y
1 a( w/ X2 ^! n 'AAPL' 'Apple Inc' '$742.63B' 1980
: f9 K7 d' A: N) B# a 'AMZN' 'Amazon.com Inc' '$173.33B' 1997
: u0 K. V* A' t5 o3 g 'MSFT' 'Microsoft Corporation' '$346.9B' 1986 % Q7 D# L, A& n( i
: W. R7 b; p( S$ t- Z b+ m6 C
我们可以通过使用dot+Variablename的语法直接访问table中的列,返回的结果是cell格式的数据:4 R0 h9 |; L. b6 K3 j
$ ~: u$ B7 s( f% 使用dot语法访问table中的数据
, a4 j, F) c* D9 a5 C' C0 {( Z>> nasdaq.Symbol % dot格式+变量名的访问方式* S# `' x; |& s. Z: ?7 l
ans =
1 g. g/ G0 q( p 'AAPL'
7 X s j8 [6 S- H1 w: P: Y/ ^ 'AMZN'5 D& P1 Y O- e6 \5 g
'MSFT'
/ y6 c* ] a0 T" W>> class(nasdaq) % 返回cell格式的数据
9 }) R: s# L0 `+ Z3 Pans =4 f6 k6 x' a; W4 s
cell
* r% {3 S) c% F5 F \' {+ m5 N# c. _& y5 q. i9 A
table类重载了subsref函数(什么是运算符的重载,参加《MATLAB面向对象编程-从入门到设计模式》12.1节),于是支持MATLAB传统的圆括号下标访问,如果要访问第一行,则:
5 N v% m# D& G
- [ H5 N8 C9 ~: w% 使用下标语法访问table中的数据
# W' ?% ~3 `" h" Q, F% G>> nasdaq(1,:)
" H' o. Q) c+ Y" X+ D% rans =
7 {6 e3 N5 c" r V. Q7 q) a Symbol Name MarketCap IPOYear+ _ ]' t4 i/ g+ x) U) l, B! \* k
______ ___________ __________ _______/ j/ E0 \/ O* U- i
+ U. s/ h0 l9 u- g
'AAPL' 'Apple Inc' '$742.63B' 1980
9 W) b4 Y) W# N" W1 @* I
! S8 e- Q, g! \3 S2 l使用圆括号,返回的结果仍然是table,如果要访问第2到3行,则:
7 \. L9 m! [1 J- N, `
- `, ?* I; z S0 {% 使用下标语法访问table中的数据$ F6 @. g. Q) D5 Y7 P
>> nasdaq(2:3,:)$ L2 l9 |& O: u# a5 B/ ?
ans =
3 G' q* V5 k7 W; J$ J0 E3 ` Symbol Name MarketCap IPOYear3 s" S8 M3 n! V/ s! k" s
______ _______________________ __________ _______
3 V O. a% r3 f: t
+ h i+ l; q" e+ p 'AMZN' 'Amazon.com Inc' '$173.33B' 1997 + F# s. Q5 w( I7 g) ^8 E2 K' o
'MSFT' 'Microsoft Corporation' '$346.9B' 1986 % O& E0 Z8 d) o
- E; e! j D' i& d3 `* L" k8 a: [9 J0 {0 B返回的结果仍然是table。 table数据结构支持MATLAB传统的花括号下标访问,返回的结果是cell格式的数据; F3 g% V- U B& U' H2 v/ t
/ u1 H% f: ?5 A/ E6 M
% 花括号下标访问& c$ ?! R" C/ N- `
>> nasdaq{:,1} % 花括号下标访问,返回第一列中的数据 \6 ]5 W$ V( x5 |# [- o' x
ans =
3 X) [% {0 e# ^5 C: _0 T 'AAPL'
" I1 p$ {/ c# j# x& F. L 'AMZN'
' {7 C. }' @# ?4 z* i/ U 'MSFT' 0 y% C1 w2 L* e$ P
- J4 k4 @; R3 h( ]( q$ ?还可以把Dot语法和下标语法结合起来获取数据,下例代码访问table第一列的第三行,返回的结果是元胞。
+ ~1 c( y O8 I3 v9 x- g: v; \# d5 J3 T: h3 q7 Z
% Dot语法和圆括号下标访问结合
8 L9 H: s2 ^/ h) @' h5 \. M) y>> nasdaq.Symbol(3)
* F# _! }3 A0 [+ u. J5 Oans = 6 v8 ?( h7 p; F" h+ y# [/ r
'MSFT'
# b0 Y% M8 Y) j! |: j Z>> class(ans) % 圆括号下标访问,返回结果是元胞 ) q1 Q4 w7 a8 _1 @/ Y' E
ans =8 ^! d$ G# U* Z7 F/ B# T
cell
1 k. p7 t0 P$ J& u8 E |
|