|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 uqHZau 于 2020-11-30 13:25 编辑 ' ~# ]9 A1 _; U6 O+ A! k6 P
, {, O6 F9 U* l% C$ N! K目录:
: {' K, J ?: Q6 X) [& j- table简介
- 为什么需要table数据结构
- 通过导入数据构造table对象
- 调用table构造函数来构造table对象
- 通过转换函数构造table对象
- 访问table中的数据
l# k7 Q' h3 R* q9 e7 S
# E; S# Y; [5 \9 }. {3 i4 N6 mMATLAB常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。除了这些基本数据类型,MATLAB还有很多其它的数据类型不为人熟悉,这些数据类型在编程中也非常有用。MATLAB高级数据类型系列旨在向大家介绍它们:比如containers.Map, tables,enumeration和time series等等,它们为什么有用,用来解决什么问题,并且怎样在科学工程计算中怎么使用。上篇我们提到了映射表结构(containers.Map )。本篇将介绍另一中新的MATLAB数据类型--table。
2 x" F% ~; M% D3 i0 Q* N! h4 I
4 h; s$ a6 R8 _1 Gtable简介! x' h0 ^" m% w6 p5 N5 x+ ]7 ?2 S
为什么需要table数据结构
/ Q! {% s( \: B @. k. sMathWorks在MATLAB R2013b中引入了一种新的数据结构叫做table 。table类似统计 工具箱中的dataset ,其引入的目的就是用来取代dataset的数据类型。因为表状的数据在工程计算中越来越长久,有了table 类型,MATLAB用户就可以不用购买统计工具箱,也能使用表状的数据结构了。 table本质上来说是一种可以存放各种数据类型的容器,比如下面表Table.1中的数据,其中既有字符型,又有数值类型,其中第一行作为表头:Symbol,Name,Market,Cap,IPO, Year是各列的名字。; S- S* K2 y: Q0 W: @: N
, b: Z0 H. ]9 j3 ^+ s. u
Table.1 NASDAQ股票名称表Symbol Name Market Cap IPO Year ) A$ A; G' d; Z' [
AAPLApple Inc$742.63B1980
+ s% F' \4 H; U' DAMZNAmazon.com, Inc$173.33B1997; H; a5 W* a0 `" y6 w( d) ?
MSFTMicrosoft Corporation$346.9B1986
+ D8 W! q* Y# t: y% F( @在conatiners.Map的章节中,我们介绍了MATLAB的基本数据类型(比如数组,原胞数组和结构体)在表达某些复杂数据类型时的局限性。这里不再一一赘述,读者只需要认识到:数组的局限性在于不能用来存放数值以外的数据,而使用元胞读取和索引内容时有种种不方便,比如无法区分该数据中的表头和其余的行数据。事实上,如果数据存放在如下的CSV文件中,并且用importdata 直接读取表Table.2中的CSV文件。1 X# E' g' g3 l. R
) ]2 c9 F Q. g/ V# D6 g4 ^5 n! eTable.2 Nasdaq 的 csv 原始数据
1 M0 y% c7 J( q" _"Symbol","Name","Market Cap","IPO Year"! F2 v3 Y% P: t: A+ j& G6 s. m
"AAPL","Apple Inc","$742.63B",1980
0 N! x9 {# {. r"AMZN","Amazon.com Inc","$173.33B",1997
* ]" d2 J1 A7 _/ E"MSFT","Microsoft Corporation","$346.9B",1986
6 U6 @) I+ z6 x0 u! _4 I
8 ~) D8 Y) y1 B" h: Z# G. `读入之后数据将会被分成数值和非数值部分:4 F' x6 k$ x* q* Z
% 用importdata直接读入CSV文件
& O( p T7 a' b: A4 ]8 \>> nasdaq = importdata('nasdaq.csv')
* @3 Z7 L& D" W, L% x: F4 |nasdaq = % 结果存在struct中
7 @1 g+ F* S) l5 J1 ? data: [3x1 double]
9 N" r: \0 r R textdata: {4x4 cell}# h; q/ f- Q: U# n9 U
>> nasdaq.data % csv中的数值部分6 U) x k+ E# n8 t
ans =
* h5 P9 [' t) l" B* u+ { 1980
: z& O% ~# W* h- |' z 1997
]$ P& k; [4 s3 u 1986
2 k5 o4 P# J. ^5 K8 _>> nasdaq.textdata % csv中的字符部分
9 ?% b6 w, R& ]: n( _9 E' f Bans = * ]% A- `) `3 w8 T+ G9 `
'"Symbol"' '"Name"' '"Market Cap"' '"IPO Year"'+ |. } d' C0 d3 x4 b$ F& ^
'AAPL' 'Apple Inc' '$742.63B' ''
" N- x$ J5 R) H) U6 K' z1 f& b 'AMZN' 'Amazon.com Inc' '$173.33B' ''
- P& _# G7 E, a2 ~ 'MSFT' 'Microsoft Corporation' '$346.9B' '' * r6 ?# k, N2 v0 H% Q$ n4 |
: H) u! H% f. p0 v' \显然这不是我们所期待的要导入格式。 u5 H1 K3 I- u b, b1 {
) J2 f7 F) }* J, Y8 j" N+ R+ N
通过导入数据构造table对象7 R! [6 ]2 C! U: C
沿用表Table.2中nasdaq.csv文件,我们可以使用readtable 函数,构造一个新的table对象,把csv文件中的数据导入到该对象中。readtable函数接受文件名称作为输入,返回一个table对象。/ z! O0 k h2 t' o! E7 e/ j
& r: N: ?3 E: S" P9 q" y% 通过readtable函数来构造table对象; ~# ]9 d6 A/ ?, A& O) e
>> nasdaq = readtable('nasdaq.csv')
) z; G" e$ |0 `! e/ `5 ?: AWarning: Variable names were modified to make them valid MATLAB identifiers. ! M7 P; j& g1 M# `: `/ |0 v; s# s
nasdaq =
3 `) _3 O" } J7 l Symbol Name MarketCap IPOYear( A" M* e& ?: C5 C9 {& t
______ _______________________ __________ _______
' z( |+ s- K+ ]: ^& w 'AAPL' 'Apple Inc' '$742.63B' 1980 - k; c' {( @5 i+ @, w( |
'AMZN' 'Amazon.com Inc' '$173.33B' 1997
7 L5 b. R' L/ q. T6 X. T0 V$ h 'MSFT' 'Microsoft Corporation' '$346.9B' 1986 c7 V4 p0 t) D
+ R" Y8 j N' P! O% O; k- P
注意第2行的warning,因为readtable 函数把nasdaq.csv中的第一行自动变成了这个table的表头,在创建table对象的时候,MATLAB会对做表头的文字做处理,这里把Market Cap和IPO Year两个词中的空格去掉,缩成一个词,这样做是为了方便将来使用dot语法来访问表中的数据。因为MATLAB修改了原来的表头,所以这里给出了warning。7 ]/ X+ c6 R2 w& y; b3 j
- P3 b+ h) O! I L5 e" ` V: G' `调用table构造函数来构造table对象2 V! q2 d7 b# u1 D/ f5 D# v5 b# g
我们还可以通过直接调用table类的构造函数来创建table对象 (什么是类的构造函数见参加<>第2.5节,构造函数和类的名称相同)。在containers.Map 的介绍中,我们举了电话号码簿的例子,如表Table.3所示,它是我们这节要构造的table对象的原始数据6 Q8 f# o9 q$ ^9 |0 K0 ]0 M2 s* r
3 Q4 ]1 h( R7 o0 k- v
Table.3 电话号码簿
5 f* U9 [' ~( C5 R) Q( c* P0 Z1 t0 K& O( I
姓名 电话号码
6 Q- {8 y3 R6 N4 Y- [* jAbby50864700017 G: F% i" E- \1 h9 V r: Q" [9 G% n
Bob5086470002% h0 \, B3 k: I
Charlie50864700032 o. C' D6 x! A' V1 T
下面程序中第1,2行用元胞数组来表示表中每一列的数据,第3行规定了表头的名称,第4行调用table的构造函数创建table对象,先输入数据,再输入表头的名称。表头通过table对象的VariableNames属性来设置。/ t( k& o% A! R8 @7 T
; |. {+ E. ~" i: e" r! oname={'Abby';'Bob';'Charlie'}; % 3x1列向量$ E D3 z5 i, H* h. h7 p1 u
number={'5086470001';'5086470002';'5086470003'}; % 3x1列向量
4 S: D" t- v% P3 GcolName={'Name','Number'};9 u5 i+ h) S: R' I1 G# i
phonetable=table(name,number,'VariableNames',colName) 2 D- R1 J* w1 ?, P0 L
8 z" e; A0 {; O' x8 ^
命令行显示如下; A& ^% q1 |3 h* t) J# ~$ V
# P/ Q' A4 H" [, l) Z& g7 l0 j8 A
% phonetable在命令行中disp的结果
( |% g: Y( V" ?3 h) |# _phonetable = 5 }8 O* X- m$ a6 n
Name Number + k1 o/ |7 ?# U: L" \0 I
_________ ____________) H- @' e3 ?' {$ ], r
X. B3 n0 E' O/ R) D" {
'Abby' '5086470001'
2 ~4 A2 o5 J5 [6 W% A1 M0 _ 'Bob' '5086470002'
7 e8 g* F+ v) |! f4 p) B 'Charlie' '5086470003'2 ~- P7 v8 \* _$ g" [' y$ V5 f
1 o7 Z/ g. l5 w0 B. _
第4行把Name和Number做为table对象的VariableNames,可以这样理解VariableNames,我们可以把table看成由一个个列数据组成的数据结构,每列都是矢量,其中存放相同类型的数据。如果一个table有两列,它就有两个列矢量,每个列矢量都是table的一个变量(Variable),给变量名字就是Variable Name。5 q" c e$ O6 u: R
! C( [) ]: P D
通过转换函数构造table对象; c( n$ n* P$ u5 b# h
除了使用table的构造函数来创建table对象,还可以使用转换函数把其它数据类型转成table,下列通过数组数据类型类构造table。下面的程序的1-2行,我们利用financial工具箱中的fetch函数,从Yahoo财经处得到雅虎从3月1日到3月10日的股票价格,fetch函数将返回一个数组,第3行我们利用array2table转换函数把得到数组转成table。
w8 Q" Z% |& a+ J* l2 H
/ R: `3 f) x& u1 Z% 通过array2table创建table对象 ! X7 a6 M3 d4 ?6 l7 K5 r: l
conn = yahoo;
, C$ k; i; @* o5 T. Harray = fetch(conn,'YHOO','3/1/2015','3/10/2015');
7 z, Q, }$ w- Ryhoo = array2table(array,...5 q1 v, b) G# v! R# `
'VariableNames', {'date','open','high','low','closing','volumn','adjusted'})
+ H* e. i4 r3 q8 r; |
+ }( M2 ^! d6 ^/ U& l1 n第4行中,我们通过VariableName来指定表头的内容,结果显示如下
6 E% h- q7 |4 `! E3 U1 Q& G/ `1 }( i4 [6 N; c3 R$ b& h; T5 R
% yhoo的table在命令行的显示7 v6 p& t2 J4 ?7 G
yhoo = & h" E' h5 b/ G* H) g4 G/ ~3 k9 Y
date open high low closing volumn adjusted
! p4 H2 `$ _$ c1 W! _ __________ _____ _____ _____ _______ __________ ________! C' P# [% o& W9 e
7.3603e+05 42.57 42.92 42.18 42.68 1.0601e+07 42.68
( p* q. |4 O! Q+ T; n3 A+ t! V, b 7.3603e+05 43.6 43.93 42.67 42.98 1.1802e+07 42.98 3 Y/ O/ e- P" \: T
7.3603e+05 43.98 44.24 43.4 43.44 1.1888e+07 43.44
2 s! L- S- Q! k5 M 7.3603e+05 44.18 44.31 43.5 44.16 1.1868e+07 44.16
/ A2 C& W0 \6 J5 V( Q- h 7.3603e+05 42.08 44.38 41.97 43.99 3.0099e+07 43.99 & C% m# P# j0 W/ h% d6 y3 x
7.3603e+05 43.7 43.95 42.42 42.62 2.2392e+07 42.62 n1 p, ~- ^( O1 i
7.3603e+05 44.06 44.43 43.7 44.11 1.1027e+07 44.11
0 U( q* P/ ^ j! d2 C/ P' J3 w9 S1 W7 F$ Z. w7 x0 M
访问table中的数据. }& O# N( r3 m% Z2 H+ `( o) {
3 O# H. [- A8 z, F) ?. j7 `! ^
通过表Table.1所建立的table对象,在命令行中显示如下:
5 Z. y$ B: M y0 C0 _, ~- D
/ }& ?4 e& v5 B5 C& G% nasdaq table在命令行中的显示, Q3 }% |; r' q
nasdaq =
8 |8 y$ _; Q8 O; [9 K Symbol Name MarketCap IPOYear
8 ]- V' I! X5 M% y. T ______ _______________________ __________ _______9 J6 ~5 O J- F: S8 m5 H+ |
( o9 D9 |7 C$ p" s: F
'AAPL' 'Apple Inc' '$742.63B' 1980
* G+ q* c% o4 e8 \7 Q5 ^% c 'AMZN' 'Amazon.com Inc' '$173.33B' 1997
5 P$ F& @6 P1 {: e7 A1 y* B 'MSFT' 'Microsoft Corporation' '$346.9B' 1986 4 |+ Q$ {1 Z8 a* L
( ~) {4 I' E3 T2 {. J( z2 Y
我们可以通过使用dot+Variablename的语法直接访问table中的列,返回的结果是cell格式的数据:
5 A0 J: P4 l9 E8 u% i4 V8 f3 R$ J% x
% 使用dot语法访问table中的数据* a+ G b5 [5 O' l }7 r
>> nasdaq.Symbol % dot格式+变量名的访问方式7 [/ e& _: s, Y
ans = ; G" {; i. B! C( s# L$ J' h' B: O
'AAPL'4 T* { I9 i D! ~8 V- ?
'AMZN'
; {% v/ q3 w1 |* R+ { 'MSFT'
% J5 i0 l, U5 O' R; h>> class(nasdaq) % 返回cell格式的数据
8 m% X& N/ E2 j5 g4 E0 uans =4 G2 b' f; f; P: u, I; S
cell % _: V( T% @( @
; _- \ E6 N) _' L; f8 |# n' s* t
table类重载了subsref函数(什么是运算符的重载,参加《MATLAB面向对象编程-从入门到设计模式》12.1节),于是支持MATLAB传统的圆括号下标访问,如果要访问第一行,则:
: v! o6 [* j! T$ ~
( }9 A. }, y+ z. a4 t0 \- y% 使用下标语法访问table中的数据
5 g" M% F! O1 H0 a; Y; T3 W>> nasdaq(1,:)
. x/ O7 C6 t8 y: aans =
; Y! l A4 s/ E Y6 Q; a! K Symbol Name MarketCap IPOYear
8 d% H) j0 z( u" [$ u; D ______ ___________ __________ _______6 G' D. t* c5 v8 O) m
: N# A) d V+ i- w1 |8 i0 _! A+ e
'AAPL' 'Apple Inc' '$742.63B' 1980
+ F0 D+ k; D* z% _+ Q; D* y) I" s6 i/ C9 R; A5 J* O
使用圆括号,返回的结果仍然是table,如果要访问第2到3行,则:( [ P% @! `5 D1 s& r9 P
% ~8 t H( l/ T9 R# t: ~3 b% 使用下标语法访问table中的数据
7 v8 W7 [# b0 U>> nasdaq(2:3,:)
; O, ?+ u9 v: Rans = # H- |' d" K; u7 E
Symbol Name MarketCap IPOYear
5 m l' L! G' }. d8 J' t) o) d/ q9 a ______ _______________________ __________ _______
. K8 J6 L: n! h/ F% L9 E# `3 `
" j5 A4 e+ k Q8 y. | 'AMZN' 'Amazon.com Inc' '$173.33B' 1997
: h, H. b7 _ M a" Z 'MSFT' 'Microsoft Corporation' '$346.9B' 1986
: I$ P. v2 Q4 t- y. K/ @/ Y4 d6 `% w, Z; ^ N' c4 [
返回的结果仍然是table。 table数据结构支持MATLAB传统的花括号下标访问,返回的结果是cell格式的数据
" {- T& \( @: M0 B4 M4 b
7 f; R" Y. ^2 w+ e% 花括号下标访问
$ C+ c3 ]! s# C% U* S>> nasdaq{:,1} % 花括号下标访问,返回第一列中的数据
; l1 T+ p0 {2 v8 V7 Wans =
# e, x& u# u6 C! i: G. n$ ` 'AAPL'
$ ]% {9 j4 C( D2 R 'AMZN'
9 n- [4 V/ _# f! g: u 'MSFT'
# O+ {! j/ v; n; |6 I
# {# z; _2 {* T; C! U6 J还可以把Dot语法和下标语法结合起来获取数据,下例代码访问table第一列的第三行,返回的结果是元胞。
! ~7 }+ |5 {5 g8 `! w4 p1 U7 H9 |/ X% Z
% Dot语法和圆括号下标访问结合
; W, I6 v* ^) @' m>> nasdaq.Symbol(3)* O) \' m: z" a2 X! Y
ans = ! s9 V& A/ k7 @3 h
'MSFT'9 r- j( H. f8 s6 b
>> class(ans) % 圆括号下标访问,返回结果是元胞 / F1 L, \0 R+ N( E w8 S
ans =5 A+ J! @1 B9 K: q4 d q; ~; x: B9 s
cell 2 [# g/ Y" S3 U5 S, |
|
|