MATLAB高級數據結構連載5: table 2
本文所有內容僅代表本人觀點,和MathWorks無關
table的操作
刪除行列
刪除一個table中的某行只需要對該行置空即可:
% 刪除行n>> nasdaq(3,:) =[]nnasdaq = n Symbol Name MarketCap IPOYearn ______ ________________ __________ _______nn AAPL Apple Inc $742.63B 1980 n AMZN Amazon.com Inc $173.33B 1997 n
以上是nasdaq中的第三行MSFT被刪除後的結果。
同理,刪除一個table中的某列也只需要對該列置空,在上面刪除了第三行之後,下面的代碼繼續刪除第2列,於是nasdaq變成一個2行3列的table。
% 刪除列n>> nasdaq(:,2) =[]nnasdaq = n Symbol MarketCap IPOYearn ______ __________ _______nn AAPL $742.63B 1980 n AMZN $173.33B 1997 n
刪除列還可以通過Dot的語法,只需對錶的VariableName置空即可
% 刪除行n>> nasdaq.IPOYear=[]nnasdaq = n Symbol MarketCap n ______ __________nn AAPL $742.63Bn AMZN $173.33B n
添加行列
沿用上節中的Nasdaq的數據,假設我們要給表中添加一列,名字叫做Sector,該列關於公司的文字的描述,可以通過Dot語法來完成
% 添加列nnasdaq.Sector={Computer Manufacturing;...n Consumer Services;...n Computer Software} n
注意,這裡等式的右邊是一個列向量元胞,結果顯示如下:
% table新增了Sector列nSymbol Name MarketCap IPOYear Sector n______ _______________________ __________ _______ ________________________n AAPL Apple Inc $742.63B 1980 Computer Manufacturingn AMZN Amazon.com Inc $173.33B 1997 Consumer Services n MSFT Microsoft Corporation $346.9B 1986 Computer Softwaren
前節提到,把table中的行數據取出來,該行的數據類型仍然是table。同理,如果想要給table添加一行,該行也必須是一個table,可以通過下面的方法給table添加行:
% 給table添加行nnewCell={ FB,Facebook Inc.,$ 231.62B,2012,Computer Software} nnewTable = cell2table(newCell)nnewTable.Properties.VariableNames = {Symbol,Name,MarketCap,IPOYear,Sector};nnewNasdaq =[nasdaq;newTable] n
其中第1行先構造一個包含數據的元胞,第二行把該元胞轉成一個table,但是尚未指定表頭,第三行指定表頭,第四行把nasdaq和新建的table進行串接構成新的table。
合併table
合併table可以理解成給已有的table添加多個行或者列。如圖Figure.1,Figure.2 所示:
Figure.1 橫向合併tableFigure.2 縱向合併table圖Figure.1橫向合併示例如下,已有兩個電話號碼簿table, 分別是t1和t2:
t1 = n Name Number n _________ ____________nn Abby 5086470001n Bob 5086470002n Charlie 5086470003 n
t2 = n Name Number n _______ ____________nn Dave 5086470004n Eric 5086470005n Frank 5086470006n
橫向合併table可以使用MATLAB的數組串接的語法,如下左做所示;或者直接調用vertzcat函數(table類重載了vercat函數,左邊的代碼將觸發對vercat的調用),如下代碼框右所示:
% 直接串接tablen>> new_t =[t1 ; t2] nnew_t = n Name Number n _________ ____________nn Abby 5086470001n Bob 5086470002n Charlie 5086470003n Dave 5086470004n Eric 5086470005n Frank 5086470006n
% 使用vertcatn>> new_t = vertcat(t1,t2)nnew_t = n Name Number n _________ ____________nn Abby 5086470001n Bob 5086470002n Charlie 5086470003n Dave 5086470004n Eric 5086470005n Frank 5086470006n
圖Figure.2縱向合併示例如下,已有號碼簿t1,以及另一個關於辦公室和樓號的table
t1 = n Name Number n _________ ____________nn Abby 5086470001n Bob 5086470002n Charlie 5086470003n
t3 = n Office Buildingn ______ ________nn 331 A1 n 201 A2 n 328 A4 n
橫向合併table可以使用MATLAB的數組串接語法(這樣的直接連接似乎有些不和邏輯,Abby不一定正好對應了331 A1這一行,在Join Table 節中將完善這個例子),如下做所示
% 直接串接tablen>> new_t = [t1,t3]nnew_t = n Name Number Office Buildingn _________ ____________ ______ ________nn Abby 5086470001 331 A1 n Bob 5086470002 201 A2 n Charlie 5086470003 328 A4 n
或者直接調用horzcat函數,如下代碼框所示:
% 使用horzcatn>> new_t = horzcat(t1,t3)nnew_t = n Name Number Office Buildingn _________ ____________ ______ ________nn Abby 5086470001 331 A1 n Bob 5086470002 201 A2 n Charlie 5086470003 328 A4 n
操作列數據
沿用NASDAQ表所導入的table:
% nasdaq table原始數據nnasdaq = n Symbol Name MarketCap IPOYearn ______ _______________________ __________ _______nn AAPL Apple Inc $742.63B 1980 n AMZN Amazon.com Inc $173.33B 1997 n MSFT Microsoft Corporation $346.9B 1986 n
其中第三列市值一項中的內容是字元串,這節通過去掉MarketCap列數據中的$和B符號,把該列轉成Numerical的類型,來演示如何對整列的數據進行操作。
前節"訪問table中的數據"中提到使用nasdaq.MarketCap訪問table數據返回的將是一個元胞數組,所以最簡單的對該table的MarketCap列的操作方法是使用cellfun。我們定義如下helper函數幫助去掉字元串開始的$和結尾的B
% helper函數nfunction out_num = marketcap_helper(in_string)n out_num = str2num(in_string(2:end-1));nend n
然後直接調用cellfun,並且把得到的結果再賦給nasdaq.MarketCap,結果如下:
% 調用cellfun對table列數據進行操作n>> nasdaq.MarketCap = cellfun(@ marketcap_helper,nasdaq.MarketCap)nnasdaq = nn Symbol Name MarketCap IPOYearn ______ _______________________ _________ _______nn AAPL Apple Inc 742.63 1980 n AMZN Amazon.com Inc 173.33 1997 n MSFT Microsoft Corporation 346.9 1986 n
table類還提供了varfun方法來進行列操作,和使用cellfun的區別是,cellfun的處理對象是table中的一部分,即元胞。而varfun處理的對象直接是table對象。下例中對Yahoo股票table的第二列7天的開盤價求均值:
% yhoo的table在命令行的顯示nyhoo = n date open high low closing volumn adjustedn __________ _____ _____ _____ _______ __________ ________n 7.3603e+05 42.57 42.92 42.18 42.68 1.0601e+07 42.68 n 7.3603e+05 43.6 43.93 42.67 42.98 1.1802e+07 42.98 n 7.3603e+05 43.98 44.24 43.4 43.44 1.1888e+07 43.44 n 7.3603e+05 44.18 44.31 43.5 44.16 1.1868e+07 44.16 n 7.3603e+05 42.08 44.38 41.97 43.99 3.0099e+07 43.99 n 7.3603e+05 43.7 43.95 42.42 42.62 2.2392e+07 42.62 n 7.3603e+05 44.06 44.43 43.7 44.11 1.1027e+07 44.11 n
直接把table的第三列提供給varfun即可,注意varfun的第一個參數是函數句柄,該函數必須能夠處理向量的輸入
% varfun對表中的列數據進行操作n>> varfun(@mean,yhoo(:,3))nans = n mean_highn _________nn 44.023 n
再舉一個例子,觀察上表的第一列,其中日期使用整數形式的輸出,難以閱讀,我們可以通過datestr函數對其第一列做操作,轉化成易讀的字元形式
% 變換date列的數據格式n>> formatOut = dd-mm-yy;n>> yhoo.date = datestr(yhoo.date,formatOut) % datestr接受table輸入nyhoo = ndate open high low closing volumn adjustedn________ _____ _____ _____ _______ __________ ________nn10-03-15 42.57 42.92 42.18 42.68 1.0601e+07 42.68 n09-03-15 43.6 43.93 42.67 42.98 1.1802e+07 42.98 n06-03-15 43.98 44.24 43.4 43.44 1.1888e+07 43.44 n05-03-15 44.18 44.31 43.5 44.16 1.1868e+07 44.16 n04-03-15 42.08 44.38 41.97 43.99 3.0099e+07 43.99 n03-03-15 43.7 43.95 42.42 42.62 2.2392e+07 42.62 n02-03-15 44.06 44.43 43.7 44.11 1.1027e+07 44.11 n
有的時候,我們還需要計算一天的股價相對於收盤價的變換範圍,下面的程序用最高價減去最低價,並且除以收盤價,並且把得到的結果放到一個新建的列range中去
% range列的數據來自於high low和closing列數據n>>yhoo.range = (yhoo.high - yhoo.low)./yhoo.closingnyhoo = ndate open high low closing volumn adjusted range n________ _____ _____ _____ _______ __________ ________ ________n10-03-15 42.57 42.92 42.18 42.68 1.0601e+07 42.68 0.017338n09-03-15 43.6 43.93 42.67 42.98 1.1802e+07 42.98 0.029316n06-03-15 43.98 44.24 43.4 43.44 1.1888e+07 43.44 0.019337n05-03-15 44.18 44.31 43.5 44.16 1.1868e+07 44.16 0.018342n04-03-15 42.08 44.38 41.97 43.99 3.0099e+07 43.99 0.054785n03-03-15 43.7 43.95 42.42 42.62 2.2392e+07 42.62 0.035899n02-03-15 44.06 44.43 43.7 44.11 1.1027e+07 44.11 0.01655 n
排序
沿用上節"操作列數據"中處理過後的數據,現nasdaq表中第三列中的數據類型,通過調用cellfun函數變成了Numerical
% 調用cellfun對table列數據進行操作nnasdaq = n Symbol Name MarketCap IPOYearn ______ _______________________ _________ _______nn AAPL Apple Inc 742.63 1980 n AMZN Amazon.com Inc 173.33 1997 n MSFT Microsoft Corporation 346.9 1986 n
現在我們可以通過調用sortrows函數對三支股票的市值進行從大到小的排序,結果如下
% 根據MarketCap列數據進行排序n>> sorted = sortrows(nasdaq,MarketCap,descend)nsorted = n Symbol Name MarketCap IPOYearn ______ _______________________ _________ _______nn AAPL Apple Inc 742.63 1980 n MSFT Microsoft Corporation 346.9 1986 n AMZN Amazon.com Inc 173.33 1997 n
篩選和查找
table的下標也接受logical index, 下例選出所有股票中市值大於200B的股票
% 篩選n>> nasdaq(nasdaq.MarketCap>200,:)nans = n Symbol Name MarketCap IPOYearn ______ _______________________ _________ _______nn AAPL Apple Inc 742.63 1980 n MSFT Microsoft Corporation 346.9 1986 n
如下選出所有股票中市值大於200B的股票並且在1985年之後IPO的股票
% 篩選n>> nasdaq( (nasdaq.MarketCap>200) & (nasdaq.IPOYear > 1985),:)nans = n Symbol Name MarketCap IPOYearn ______ _______________________ _________ _______nn MSFT Microsoft Corporation 346.9 1986 n
logical index還可以提供查找功能,下例查找所有行中Symbol=AMZN 的數據
% 查找n>> nasdaq(strcmp(nasdaq.Symbol,AMZN),:)nans = n Symbol Name MarketCap IPOYearn ______ ________________ __________ _______n AMZN Amazon.com Inc $173.33B 1997 n
輸出到文件
和readtable對應,把一個工作空間中的table寫到文件中去可以使用writetable
% writetablen>> nasdaq = readtable(nasdaq.csv) n>> wrietable(nasdaq,mydata.csv) n
writetable默認的分割符是逗號,writetable還可以通過delimiter來設置分割符,下例空格代替逗號
% 指定分隔符nwritetable(T,mydata.txt,Delimiter, )n
結果如下
% mydata.txtnSymbol Name MarketCap IPOYearnAAPL Apple Inc $742.63B 1980nAMZN Amazon.com Inc $173.33B 1997nMSFT Microsoft Corporation $346.9B 1986 n
其它數據類型之間和table相互轉換
MATLAB支持table和struct,cell,array之間的相互轉換。如圖Figure.3所示,下面一一介紹:
Figure.3 table和其它數據的轉換本節使用數據如表Table.1所示,內容是美元和人民幣的貨幣轉換速查表:
Table.1 美元人民幣換算表USDtCNYn1 6.21n5t31.03n10t62.06n
先討論array和table之間的轉化,下例第1行用數組a表示表Table.1中的內容,第6行把a轉成table,表頭的信息需要通過VariableNames來設置
% array2tablen>> a = [1 6.21;5 31.03 ;10 62.06 ]na =n 1.0000 6.2100n 5.0000 31.0300n 10.0000 62.0600n>> t = array2table(a,VariableNames,{USD CNY}) % 通過VariableNames提供表頭信息nt = n USD CNY n ___ _____n 1 6.21n 5 31.03n 10 62.06 n
如果把table再轉成array,表頭的信息將會被剝去
% table2arrayn>> ap = table2array(t)nap =n 1.0000 6.2100n 5.0000 31.0300n 10.0000 62.0600 n
操作如圖Figure.4所示:
Figure.4 table和array的轉換
在討論struct和table之間的轉換,下例第1,2行給struct的field賦向量,來表示表Table.1中的內容,第3行並且把它轉成table。
% struct2tablen>> s.USD = [1 ; 5 ;10];n>> s.CNY = [6.21 ;31.03; 62.06];n>> t = struct2table(s) % 輸入s是標量nt = n USD CNY n ___ _____n 1 6.21n 5 31.03n 10 62.06 n
struct2table還接受struct是非標量的輸入
% struct2table 矢量ns(1).USD = 1;ns(1).CNY = 6.21;ns(2).USD = 5;ns(2).CNY = 31.03;ns(3).USD = 10 ;ns(3).CNY = 62.06nnn% 輸入s是矢量nt = struct2table(s)n
s = n1x3 struct array with fields:n USDn CNYnt = n USD CNY n ___ _____n 1 6.21n 5 31.03n 10 62.06n
把table轉成struct,table的表頭將自動變成struct的field的名稱,得到的是結果是結構體數組。
% table2structn>> sp = table2struct(t) % non-scalar struct nsp = n3x1 struct array with fields:n USDn CNY n
操作如圖Figure.5所示:
Figure.5 table和struct的轉換
最後討論cell和table之間的轉換,下例用cell表示表Table.3中的內容,並且把它轉成table。
Table.3 電話號碼簿
姓名t電話號碼nAbbyt5086470001nBobt5086470002nCharliet5086470003n
c = {Abby, 508647001;...n Bob,5086470002;...n Charlie,5086470003};nt = cell2table(c,...n VariableNames,{Name,Number})n
nt = n Name Number n _________ ____________n Abby 508647001 n Bob 5086470002n Charlie 5086470003n
把table轉成cell,table的表頭將自動被剝去
% table2celln>> c = table2cell(t)nc = n Abby 508647001 n Bob 5086470002n Charlie 5086470003 n
操作如圖Figure.6所示:
Figure.6 table和cell的轉換
推薦閱讀:
※MATLAB App Desinger教程連載2:詳解App Designer生成的代碼
※js以變數調用json未知keys的方法?
※教學用的代碼使用面向對象技術合適嗎?
※先有Class還是先有Object?