|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 uqHZau 于 2020-11-30 13:25 编辑 - e$ z Q( ?+ F# a' I" Y
% X2 p9 r) u6 `
目录:3 K, M' `8 j+ M3 x! M
- table简介
- 为什么需要table数据结构
- 通过导入数据构造table对象
- 调用table构造函数来构造table对象
- 通过转换函数构造table对象
- 访问table中的数据( ^7 `& X2 W8 h2 k4 m
$ k( e/ y3 f) nMATLAB常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。除了这些基本数据类型,MATLAB还有很多其它的数据类型不为人熟悉,这些数据类型在编程中也非常有用。MATLAB高级数据类型系列旨在向大家介绍它们:比如containers.Map, tables,enumeration和time series等等,它们为什么有用,用来解决什么问题,并且怎样在科学工程计算中怎么使用。上篇我们提到了映射表结构(containers.Map )。本篇将介绍另一中新的MATLAB数据类型--table。5 s0 q+ _ O7 u8 B
8 g$ ~5 I; Y5 _$ Rtable简介2 u! A& b8 P; i7 N- Z
为什么需要table数据结构& _; |& ~9 ~6 G! |5 Y7 u; A
MathWorks在MATLAB R2013b中引入了一种新的数据结构叫做table 。table类似统计 工具箱中的dataset ,其引入的目的就是用来取代dataset的数据类型。因为表状的数据在工程计算中越来越长久,有了table 类型,MATLAB用户就可以不用购买统计工具箱,也能使用表状的数据结构了。 table本质上来说是一种可以存放各种数据类型的容器,比如下面表Table.1中的数据,其中既有字符型,又有数值类型,其中第一行作为表头:Symbol,Name,Market,Cap,IPO, Year是各列的名字。
* j' u% E/ R7 c9 I2 _4 U! t9 A
1 K# P6 J+ ~2 q, w; a! `$ NTable.1 NASDAQ股票名称表Symbol Name Market Cap IPO Year
3 k8 W. H2 h6 O( wAAPLApple Inc$742.63B1980
- T# J# |5 G9 n5 a1 {AMZNAmazon.com, Inc$173.33B1997
# q6 @; @0 j9 QMSFTMicrosoft Corporation$346.9B1986
3 ?' ]2 _6 z6 h在conatiners.Map的章节中,我们介绍了MATLAB的基本数据类型(比如数组,原胞数组和结构体)在表达某些复杂数据类型时的局限性。这里不再一一赘述,读者只需要认识到:数组的局限性在于不能用来存放数值以外的数据,而使用元胞读取和索引内容时有种种不方便,比如无法区分该数据中的表头和其余的行数据。事实上,如果数据存放在如下的CSV文件中,并且用importdata 直接读取表Table.2中的CSV文件。( ?$ l* y9 Q J$ Z
7 R- l* A Y0 WTable.2 Nasdaq 的 csv 原始数据
" n5 D- a4 @9 H. I& h"Symbol","Name","Market Cap","IPO Year". J3 S# A# ?8 c
"AAPL","Apple Inc","$742.63B",1980& `9 n+ Y& h+ ]
"AMZN","Amazon.com Inc","$173.33B",1997
/ C8 b# s+ [) ~3 n' {* }"MSFT","Microsoft Corporation","$346.9B",1986
$ `* V: i) O* V7 ~/ T7 |" Z, [3 k; U
读入之后数据将会被分成数值和非数值部分:# q$ A" \' y& z; k9 m
% 用importdata直接读入CSV文件$ Y z' i2 K2 L3 l+ {: I
>> nasdaq = importdata('nasdaq.csv')
3 y0 R: e* z: {9 h1 `nasdaq = % 结果存在struct中$ u) Q0 \5 ]' P4 q, l4 s2 X) ?
data: [3x1 double]
( q6 i0 n! Z% F1 y textdata: {4x4 cell}+ a' f2 l+ y5 z1 u
>> nasdaq.data % csv中的数值部分
# ?; `) q% m, A4 e0 Sans =; `0 F% r' C3 [, N& P: B% h) I
1980% x7 `" `% T6 m) d( ?: I
1997; X1 C2 m: l) [# U# u" |, C+ `
1986 * I1 C- N# M2 m0 [3 {% O" n8 F
>> nasdaq.textdata % csv中的字符部分9 p( v# V) I. |0 T6 [) J9 E4 \
ans = . \9 J) ~3 T4 s3 [
'"Symbol"' '"Name"' '"Market Cap"' '"IPO Year"'
( b# I' }4 \: Z 'AAPL' 'Apple Inc' '$742.63B' ''
$ `: p7 f9 t2 q w3 e% K" o 'AMZN' 'Amazon.com Inc' '$173.33B' ''
) U. R0 F% Z! Z* z/ e* j7 _ 'MSFT' 'Microsoft Corporation' '$346.9B' '' 6 j$ O+ q7 F& Q2 [
* E1 l3 L; x8 u5 B显然这不是我们所期待的要导入格式。
& J9 [2 R& l7 ]3 v/ ~9 h) D! b o# U: x4 O- v. z6 j% a# J
通过导入数据构造table对象% N g) s$ s7 K1 u% ^$ |
沿用表Table.2中nasdaq.csv文件,我们可以使用readtable 函数,构造一个新的table对象,把csv文件中的数据导入到该对象中。readtable函数接受文件名称作为输入,返回一个table对象。) R( M/ V/ C9 P2 S& u1 d0 o4 K; s
7 P* D) }, F$ w& ?4 H7 Q
% 通过readtable函数来构造table对象' i* f8 R+ |# C, G* A7 C( y) {
>> nasdaq = readtable('nasdaq.csv')
* i' ?# R6 R4 [; a. n: f# [Warning: Variable names were modified to make them valid MATLAB identifiers. * ]1 k0 O( q8 |' ^! D8 U7 Y( X
nasdaq =
8 r* U) R, {, m& c( Z g3 O5 x Symbol Name MarketCap IPOYear
' v H4 x& V0 K- e ______ _______________________ __________ _______4 L5 c6 i% [7 r) n, i
'AAPL' 'Apple Inc' '$742.63B' 1980
8 `: _; `# [6 J; k; j 'AMZN' 'Amazon.com Inc' '$173.33B' 1997 $ x: m4 l+ e5 D: V2 @1 f0 y
'MSFT' 'Microsoft Corporation' '$346.9B' 1986 , P9 a3 w& J. l5 `
) p8 j& C* O1 q/ U" Y) `
注意第2行的warning,因为readtable 函数把nasdaq.csv中的第一行自动变成了这个table的表头,在创建table对象的时候,MATLAB会对做表头的文字做处理,这里把Market Cap和IPO Year两个词中的空格去掉,缩成一个词,这样做是为了方便将来使用dot语法来访问表中的数据。因为MATLAB修改了原来的表头,所以这里给出了warning。9 V6 w( D& A2 d
1 b; y, y: M& ~8 v调用table构造函数来构造table对象) v8 u6 Q6 {) \' w
我们还可以通过直接调用table类的构造函数来创建table对象 (什么是类的构造函数见参加<>第2.5节,构造函数和类的名称相同)。在containers.Map 的介绍中,我们举了电话号码簿的例子,如表Table.3所示,它是我们这节要构造的table对象的原始数据
+ G# ?1 |7 o" t5 F/ J6 _( J% K, J: d7 ~- V! K6 P/ S" q1 ?
Table.3 电话号码簿
9 l% t1 B5 @9 l9 f2 ]7 N7 V6 T1 r" W* |0 x1 i
姓名 电话号码
2 o3 V- {) J: M1 \! X4 @1 IAbby5086470001
, Y8 i, P- Y$ l, `; N0 r: eBob5086470002
0 I8 ^. i2 z p4 y) {9 [Charlie5086470003# H2 _6 o( \; _. h: J
下面程序中第1,2行用元胞数组来表示表中每一列的数据,第3行规定了表头的名称,第4行调用table的构造函数创建table对象,先输入数据,再输入表头的名称。表头通过table对象的VariableNames属性来设置。
5 L5 l/ S& F. u) f$ j2 b/ g6 U/ x
name={'Abby';'Bob';'Charlie'}; % 3x1列向量
; c `, f$ d1 Inumber={'5086470001';'5086470002';'5086470003'}; % 3x1列向量4 W _$ h& G2 Z9 b
colName={'Name','Number'};9 M+ y7 j- E4 O/ h" n9 g
phonetable=table(name,number,'VariableNames',colName) - f- Z- ]* I- t! \
( K* z2 ?7 y4 K5 M% X) d
命令行显示如下0 c* Q& o2 D1 ^2 t) @1 r& k1 r, U
( \+ t4 r7 B) U) D9 ^
% phonetable在命令行中disp的结果
- A# |% d* W; K' n: O& |) t+ P Qphonetable = 8 y/ A3 B' B" C) k1 i4 p, z
Name Number
/ ] B8 W! M+ v _________ ____________/ S: i: |1 i! N2 j( ?/ f2 @
7 W) H% O4 { G" ]2 ?& z
'Abby' '5086470001'& |4 ]5 _) w# C1 V3 l1 s* }- w
'Bob' '5086470002'
2 @9 C1 w. v _4 ` c 'Charlie' '5086470003'/ P* x. q9 h8 ^# ^. J
2 m) F# C: _/ f; ]6 \5 ]第4行把Name和Number做为table对象的VariableNames,可以这样理解VariableNames,我们可以把table看成由一个个列数据组成的数据结构,每列都是矢量,其中存放相同类型的数据。如果一个table有两列,它就有两个列矢量,每个列矢量都是table的一个变量(Variable),给变量名字就是Variable Name。* S2 s0 E6 [" C7 k. e2 |
& w K. A( z8 l
通过转换函数构造table对象
; }9 E, n7 k$ b, X ?3 c7 T- k0 y除了使用table的构造函数来创建table对象,还可以使用转换函数把其它数据类型转成table,下列通过数组数据类型类构造table。下面的程序的1-2行,我们利用financial工具箱中的fetch函数,从Yahoo财经处得到雅虎从3月1日到3月10日的股票价格,fetch函数将返回一个数组,第3行我们利用array2table转换函数把得到数组转成table。( Z* N* {/ }" r) {; E) B
* n! \$ G2 m$ z: b$ o, e w% 通过array2table创建table对象 2 p W9 \+ C: T; ~! [
conn = yahoo;
" d$ H0 ^6 e2 `1 `+ X, Y$ S- b, barray = fetch(conn,'YHOO','3/1/2015','3/10/2015');
. h" T$ g* _ Iyhoo = array2table(array,...
8 ~/ I( x: I7 @$ K: N4 `6 ^ 'VariableNames', {'date','open','high','low','closing','volumn','adjusted'})4 i% @9 U* n$ d$ H" x
. T' y* P, ^& ~8 F1 E% @* N3 a1 p第4行中,我们通过VariableName来指定表头的内容,结果显示如下" P" l6 f* U. J* w6 ^3 ]) v
6 j, v" i/ U$ b0 @ D0 A+ }
% yhoo的table在命令行的显示- c% q! |2 j" X4 E* w0 l
yhoo =
4 E. ^. g9 _. ^+ W date open high low closing volumn adjusted& W3 G6 i/ V$ K, o6 p* x
__________ _____ _____ _____ _______ __________ ________ c4 l7 e* [: w% }$ V
7.3603e+05 42.57 42.92 42.18 42.68 1.0601e+07 42.68 . V: s& A4 I! ^; B, `
7.3603e+05 43.6 43.93 42.67 42.98 1.1802e+07 42.98 # F+ D) o( m0 s! ^' q j/ |* t
7.3603e+05 43.98 44.24 43.4 43.44 1.1888e+07 43.44
: p0 l/ ~% {. y" N& k" K T! N6 X: S 7.3603e+05 44.18 44.31 43.5 44.16 1.1868e+07 44.16
K4 g0 R$ t- Y6 n% }( Q 7.3603e+05 42.08 44.38 41.97 43.99 3.0099e+07 43.99
' e3 l% n" f. U ]5 A( H 7.3603e+05 43.7 43.95 42.42 42.62 2.2392e+07 42.62 , l* O. ]. s, @. c# c. h6 |. p# r
7.3603e+05 44.06 44.43 43.7 44.11 1.1027e+07 44.11
5 U, U) i8 g" D& F% F$ o9 f1 G2 K) o$ t$ k9 n' w
访问table中的数据
# E1 A4 O0 m/ j, D6 R% G
- ]( B+ ]$ Q$ [* S8 U通过表Table.1所建立的table对象,在命令行中显示如下:
# P" A/ N- x, u3 @! T% M( C
. D/ k& O, C9 t% nasdaq table在命令行中的显示3 d4 | C/ V0 B! g' F
nasdaq = 2 {/ o( L2 _0 Y
Symbol Name MarketCap IPOYear
0 @1 i+ f+ h& o' X ______ _______________________ __________ _______9 R1 u% U* n8 p6 p$ ]
4 f# |) t6 {: h) C4 J+ X
'AAPL' 'Apple Inc' '$742.63B' 1980
' I% w& b5 P+ K# y4 C8 j. n 'AMZN' 'Amazon.com Inc' '$173.33B' 1997
* o+ r3 ^* c7 | g( \. m, a+ E/ P* O! } 'MSFT' 'Microsoft Corporation' '$346.9B' 1986
3 T) G( m, I, g# N+ ?9 L$ H1 ]6 ] `' \
我们可以通过使用dot+Variablename的语法直接访问table中的列,返回的结果是cell格式的数据:( @2 @% u1 [0 w3 F+ N4 d# K
4 k9 t. o+ B% K6 W3 ~
% 使用dot语法访问table中的数据
9 z) j1 _- ]! ?. p$ C* L( a* r# r>> nasdaq.Symbol % dot格式+变量名的访问方式" g/ p1 Y$ a( b9 l
ans =
/ @; d# c3 v3 M$ l1 \7 u4 P5 V 'AAPL'
/ s/ d0 {: |4 u8 J1 ?0 D3 N2 r 'AMZN'
6 y: Q$ C; G6 j4 Y; i5 F- s 'MSFT'
* v8 z4 ?/ ?5 ]: ]' H- Z) S* |>> class(nasdaq) % 返回cell格式的数据
0 a% j* E( z) Z& \; dans =
2 H( M* \0 M+ acell
6 c: A7 w. F' K( R# K9 |/ \7 Y: g. h5 {
table类重载了subsref函数(什么是运算符的重载,参加《MATLAB面向对象编程-从入门到设计模式》12.1节),于是支持MATLAB传统的圆括号下标访问,如果要访问第一行,则:) _9 {2 I: a9 W9 W" |* x. m
: h+ y: p$ _6 ]. C E% 使用下标语法访问table中的数据
% N" l. h# G* _( t# |>> nasdaq(1,:)2 `4 p8 }* Q2 A9 n
ans = ! E+ N3 U$ ^9 N) p2 Y1 F' |) g
Symbol Name MarketCap IPOYear
% M: V$ C8 _( p3 U" _0 q9 ~ ______ ___________ __________ _______6 O4 ^% i6 K+ `4 E& `% |8 T
% q2 j7 x4 A3 Z- k 'AAPL' 'Apple Inc' '$742.63B' 1980
5 ?5 H6 z4 f- L e
7 ]/ ]+ `* Q3 Q( |使用圆括号,返回的结果仍然是table,如果要访问第2到3行,则:
. E9 q9 I% @, O% b' m
_. K2 q" `! Q. n. x, s% 使用下标语法访问table中的数据
2 E: z: G1 k% R) ^>> nasdaq(2:3,:)
! Z x, F2 i$ x3 C5 |) Qans =
, Z3 z7 z, B$ [( Q. v# k' ? Symbol Name MarketCap IPOYear" c# M& z0 K) ?' ~ `# ~) m3 w7 ?
______ _______________________ __________ _______
4 G3 @" _, W% { H- E' K1 L+ N, ~! P* J
'AMZN' 'Amazon.com Inc' '$173.33B' 1997
# R3 t( D3 L6 H7 ~: w 'MSFT' 'Microsoft Corporation' '$346.9B' 1986
" {/ v# Z4 v& o: v/ g4 q0 X. c; F$ j# c% L: C1 d8 A
返回的结果仍然是table。 table数据结构支持MATLAB传统的花括号下标访问,返回的结果是cell格式的数据
0 {6 X/ ~/ t& T% ^1 A! N ( T1 C# Y4 {9 E! B. l( |
% 花括号下标访问, ]6 u% K; h, l
>> nasdaq{:,1} % 花括号下标访问,返回第一列中的数据
# n f: F; d0 c3 c* zans =
, _0 K( N# o: _/ R& N Q* r 'AAPL'' G; g) d2 J7 L# p( i
'AMZN'+ _- @7 B% O1 z8 Q$ H1 L
'MSFT' M9 [1 C5 v: H" I8 X F) i
4 v: G( H0 Q5 q/ r5 S2 ]2 \还可以把Dot语法和下标语法结合起来获取数据,下例代码访问table第一列的第三行,返回的结果是元胞。
+ ~; Q& B4 w$ K- N+ r; x. G4 Y6 U1 I0 m5 R% C
% Dot语法和圆括号下标访问结合' F. o8 f9 O) d
>> nasdaq.Symbol(3), p9 e V( z$ `1 r+ ~. T( j
ans = ) B9 `; W" R" e1 o( L$ v" k5 C% d) z
'MSFT'
! }, j, [" }, h+ t>> class(ans) % 圆括号下标访问,返回结果是元胞
: {0 e) T7 @8 v3 [0 R: S S# _ans =
4 d7 S, T/ n6 N1 Xcell - {- F/ {/ o: J6 R3 H
|
|