Matlab Advanced Data Structure

by allenlu2007

Reference (oopmatlab)

http://blog.sina.com.cn/s/blog_4cf8aad30102wcu3.html

http://www.ilovematlab.cn/article-52-1.html

http://www.ilovematlab.cn/article-53-1.html

http://www.ilovematlab.cn/article-54-1.html

 

第一代的 matlab user (包含我)主要驚艷於 (numerics) array data type.  可以很方便做 matrix and vector operations. 特別是 element-wise operation (e.g. .* .^) 獨樹一幟,非常有用。但之後缺乏亮點,雖然也有 OOP matlab, 比起其他高階語言如 python (caffe, tensorflow) or ruby,  並沒有引起太大的注意 (at least for me).

隨著 machine learning and deep learning 變成主流應用。Matlab 終於找到新的舞台。除了提供相關的 toolbox, app, xxxLearner (e.g. ClassificationLearner),  visualization tools 之外。也更新了 data structure and load function.  本文討論 Matlab advanced data structure.  除了常用的 int, float, char, function or file handles, struct 外,比較 advanced data structure 有 cell, containers.Map, table, enumeration, and time series.

 

Cell  (類似 Ruby Array [] )

以下表為例。Matlab array data structure 只能處理數值,無法處理字串。需要新的 data structure.

NewImage

Cell 可以處理字串。可視為 array 概念延伸至字串!  

NewImage

也可以用 for loop access content

NewImage

 

以電話簿而言,重點是查詢電話號碼。理想而言 operation 如下:

NewImage

但 cell 無法如此。只能間接用 for loop + 比較的方法。

NewImage

或是用兩個 cells, 再用 index 把兩個 cells 關聯起來。

NewImage

1. 兩種方法無一例外,都需要 linear search 所有的 cell array, 非常沒效率。

BTW, 因為 matlab 沒有 foreach loop!!!!  比起 perl, python, ruby 實在是一大敗筆。從 cell element 的定義,到 for loop 的表述,都很冗長。Matlab 的 cell 是 indexed (類 Ruby) array.  

例如在 python or ruby 中:

NewImage

但在 matlab 中硬要塞 index i 在 cell 的定義和 access.  Very ugly 😦

NewImage

2. 無法方便的验证重复数据。电话号码簿要求每一个人的名字都是独一无二的,所以在数据录入的时候要防止姓名的重复,但是我们没有其它办法知道某名字是否已经被使用过了,除非在每次输入的时候都对整個 cell 里的内容做遍历比较。

3. 無法方便地添加内容。如果电话号码簿中的记录需要不断地增长,但是我们没有办法在一开始就估计出其大概的数量,于是无法有效的预先分配記憶體,所以添加数据时,一旦超过预先分配的量,MATLAB就要重新分配記憶體了。

4. 無法方便地删除内容。如果我们要从 cell 中去掉某一记录,可以找到该记录,并把该位置的 cell 内容置空,但这并不会自动减小 cell array 的长度,如果这样的删减操作多了,cell 中会留下很多没有利用的空余位置。

5. 不方便作为函数的参数,具体原因见struct的局限性.

 

Struct   (類似 C struct {})

雖然有點不倫不類,可以用 struct 來做以上的設定:

NewImage

NewImage

應該沒有人會直接用人名做 structure.  一般還是會用 addressBook.name and addressBook.phone 來做 structure 如下。如果如此就和 cell 沒什麼不同。

NewImage

Matlab Struct 常用來做為和 C 對接的用途。

 

Containers.Map  (類似 Ruby Hash {} )

其實就是 Perl: associative array %;  Ruby: hash {};  Python: dictionaries {}.   搭配 foreach, key/value pair functions 非常方便。但是 matlab 原先只有 cell, 而且佔用的 {}.  只好再創造出 Containers.Map data structure 😦  

之前提到 matlab 沒有 foreach,  對於 cell, struct, (table?) 的查詢都很麻煩。但在 Containers.Map 因為有 key/value pair 關係,可以用其他搜尋方式或 functions (e.g. remove, add …)

 NewImage

 NewImage

右邊的 Map 是什麼意思?key/value 就是左邊的映射表。Count,KeyType,ValueType 如下。

NewImage

Keys, values, isKey, remove 都是 functions.

NewImage

 

Table (Matlab 獨創 for machine learning and big data?)

Matlab 2013b 引入新的 data structure 叫做 table.  Table 類似 statistics toolbox 的 dataset.  Table 的目的就是取代 dataset.   Table 用於各類數據,比起 (numerics) array and cell 更廣泛。

Table 本质上来说是一种可以存放各种 data type 的容器,比如下面表中的 data,其中既有 char,又有 numerics,其中第一行作为表頭:Symbol,Name,Market,Cap,IPO, Year是各列的名字。

NewImage

Array 的局限性在于不能用来存放数值以外的数据,而使用 cell 读取和索引内容时有种种不方便,比如无法区分该 data 中的表頭和其余的 data.

一般 data 可能放在 csv file 如下。

NewImage

用 load or tblread (tabular data read) 顯然不行。因為其中有 char data type.  Matlab 最早只處理 numerics data type!  這是 matlab 的優點,但也是最大的缺點。如果用 importdata 也會有同樣的狀況如下。顯然不是我們所要的。

NewImage

 

如何建造 table

1. Use readtable function to read a tabular file, return a table object.

NewImage

注意第2行的warning,因为readtable 函数把nasdaq.csv中的第一行自动变成了这个table的表頭,在创建table object 的时候,MATLAB会对做表頭的文字做处理,这里把Market Cap和IPO Year两个词中的空格去掉,缩成一个词,这样做是为了方便将来使用dot语法来 access data。因为MATLAB修改了原来的表頭,所以这里给出了warning。


2. Use table() function to create a table object. 以上節電話簿為例。

Table 可由 row cell and column cell 組成。

下面程序中第1,2行用 column cells 来表示表中每一列的数据,第3行用 row cell 规定了表頭的名称,第4行调用table的构造函数创建table object,先输入 data,再输入表頭的名称。表頭通过table object 的VariableNames属性来设置。

NewImage

 

 如何 access table

Access table 需要使用 index.

NewImage

注意使用 () 時, return object 仍是 table.  但使用 {}, return object 時 column cell!!

NewImage 

下表顯示幾種 access table 方式。

NewImage

 

 

如何刪除 table row and column

Delete row:  只要對該行置空即可。

NewImage

Delete column: 同理,只要對該列置空即可。

NewImage


 

如何增加 table row and column

增加 column(列)比較麻煩:

NewImage

前節提到,把table中的 row data 取出来,该 row data type 仍然是table。同理,如果想要给table添加一行,该行也必须是一个 table,可以通过下面的方法给 table 添加行:

NewImage

其中第1行先构造一个包含数据的 cell,第二行把该 cell 转成一个table,但是尚未指定表頭,第三行指定表頭,第四行把nasdaq和新建的table进行串接构成新的table。

也就是 (1) 先把 cell 轉換成 table; (2) 確認 variableNames 要一致; (3) table 合併只要用 [ tb1; tb2]. 就像是字串合併。不過要注意用 “;” 而不是 “,” .

 

如何合併 tables

NewImage

 

NewImage 

NewImage

NewImage

 

輸出 table

 NewImage

NewImage

 

NewImage

Advertisements