8? Categorical數(shù)組
類別(categorical)數(shù)組是一種存儲有限類別數(shù)據(jù)的數(shù)組類型。類別數(shù)組可以提供對非數(shù)值數(shù)據(jù)的高效存儲以及操作,另外類別數(shù)組還保持了原有類別的名字,這樣使用起來更加直觀方便。類別數(shù)組可以和表(table)數(shù)據(jù)類型一起使用。
默認情況下,類別數(shù)組中包含的類別是沒有順序的。例如,一組離散的寵物類別{'dog' 'cat' 'bird'}是沒有順序的。所以MATLAB采用字母表順序來對其進行排序,{'bird' 'cat' 'dog'}。順序類別數(shù)組包含的類別是有順序的,例如尺寸大小的類別{'small', 'medium', 'large'}是具有順序的。
【例3-55】?類別數(shù)組的創(chuàng)建。
本例為讀者演示如何創(chuàng)建一個類別數(shù)組。用戶可以使用categorical函數(shù)把數(shù)值數(shù)組、邏輯數(shù)組、字符串元胞數(shù)組或者已有的類別數(shù)組創(chuàng)建為類別數(shù)組。
首先創(chuàng)建一個新英格蘭地區(qū)州名的一個元胞數(shù)組。
>> state ={'MA','ME','CT','VT','ME','NH','VT','MA','NH','CT','RI'};
之后將此元胞數(shù)組轉(zhuǎn)換為類別數(shù)組。
>> state = categorical(state)
>> class(state)
state =
? Columns 1through 9
???? MA????? ME?????CT????? VT????? ME?????NH????? VT????? MA?????NH
? Columns 10through 11
???? CT????? RI
ans =
categorical
通過categories函數(shù)可以列出類別數(shù)組中包含了哪些類別。
>> categories(state)
ans =
??? 'CT'
??? 'MA'
??? 'ME'
??? 'NH'
??? 'RI'
??? 'VT'
從結果可以看到,所有的類別是按照字母順序來排序的。
【例3-56】?順序類別數(shù)組的創(chuàng)建。
創(chuàng)建一個記錄物體尺寸大小的元胞數(shù)組:
>> AllSizes ={'medium','large','small','small','medium',...
???????????'large','medium','small'};
這個元胞數(shù)組有三種尺寸,'large'、'medium'和'small'。如果使用元胞數(shù)組進行記錄的話,那么是沒有一種方便的形式來表示small < medium < large這種大小關系的。使用valueset變量用來指明順序的大小,在調(diào)用categorical函數(shù)時對順序參數(shù)進行設置就可以實現(xiàn)順序類別數(shù)組的創(chuàng)建。
>> valueset = {'small','medium','large'};
>> sizeOrd =categorical(AllSizes,valueset,'Ordinal',true)
sizeOrd =
? Columns 1through 6
????medium????? large????? small?????small????? medium????? large
? Columns 7through 8
????medium????? small
>> class(sizeOrd)??????????? %查看創(chuàng)建數(shù)組的類型
ans =
categorical
類別數(shù)組中的順序,sizeOrd,是保持不變的。同樣適用categories函數(shù)列出所有類別:
>> categories(sizeOrd)
ans =
??? 'small'
??? 'medium'
??? 'large'
這時,所有類別的列舉就不是再按照字母順序了,而是按照用戶定義的small<medium<large順序來列舉的。
創(chuàng)建100各1-44之間的整數(shù)向量:
>> x = gallery('integerdata',44,[100,1],1);
然后使用histc函數(shù)創(chuàng)建3個箱子,將x中的數(shù)值在1-15之間的放進第一個箱子,15-30之間的放在第二個箱子,30-45之間的數(shù)值放進第三個箱子。分界點15和30會歸入第而2和第三各箱子。
>> [~,bin] = histc(x,[1,15,30,45]);
Bin是一個100×1的向量,用來表示x中的每一個向量是屬于哪個箱子的。創(chuàng)建一個順序類別數(shù)組,sizeOrd2,其中三個箱子變成了三個類別,small、medium和large。
>> valueset = 1:3;
>> catnames = {'small','medium','large'};
>> sizeOrd2 =categorical(bin,valueset,catnames,'Ordinal',true);
sizeOrd2是一個100×1的順序類別數(shù)組,它有三個類別small<medium<large。
使用summary函數(shù)可以對類別進行求和
>> summary(sizeOrd2)
????small?????? 33
????medium????? 36
????large?????? 31
通過結果可以看出,有33個元素是屬于small這個類別的,36個是屬于medium這個類別的,31個是屬于large這個類別的。
【例3-57】?類別數(shù)組元素的比較。
首先由一個字符串元胞數(shù)組來創(chuàng)建類別數(shù)組。
>> C = {'blue' 'red' 'green' 'blue';...
'blue' 'green' 'green' 'blue'};???????????? %創(chuàng)建測試元胞數(shù)組
>> colors = categorical(C)???????????????????? %?轉(zhuǎn)換為類別數(shù)組
colors =
????blue????? red??????? green????? blue
????blue????? green????? green?????blue
這里我們創(chuàng)建了2×4的類別數(shù)組。然后可以通過categories函數(shù)查看數(shù)組中有哪些類別。
>> categories(colors)
ans =
??? 'blue'
??? 'green'
??? 'red'
然后我們可以使用“==”來比較數(shù)組第一行元素是否和第二行元素相等。
>> colors(1,:) == colors(2,:)
ans =
???? 1???? 0????1???? 1
從結果可以看出,只有第二列的兩個元素不相等。
我們還可以把整個類別數(shù)組colors和單一字符串’blue’來對比:
>> colors == 'blue'
ans =
???? 1???? 0????0???? 1
???? 1???? 0????0???? 1
結果顯示在colors數(shù)組中一共有4個blue。
通過指定顏色的順序,我們可以將colors轉(zhuǎn)換為順序類別數(shù)組。例如指定順序為red<green<blue。
>> colors = categorical(colors,{'red','green''blue'},'Ordinal',true)
colors =
????blue????? red??????? green????? blue
????blue????? green????? green?????blue
類別數(shù)組中的各元素和轉(zhuǎn)換之前是相同的,檢驗一下數(shù)組中有哪些類別:
>> categories(colors)
ans =
??? 'red'
??? 'green'
??? 'blue'
在設置了順序之后,就可以對各元素的順序進行比較。例如比較第一列的元素是否比第二列的元素大:
>> colors(:,1) > colors(:,2)
ans =
???? 1
???? 1
第二列中的元素是red和green,按照設定的順序都比第一列中的blue小,所以均返回了1(true)。
用戶還可以查找所有比blue小的元素:
>> colors < 'blue'
ans =
???? 0???? 1????1???? 0
???? 0???? 1????1???? 0
返回結果中為1的元素就是比blue小的元素。
【例3-58】?類別數(shù)組元素的組合。
首先創(chuàng)建測試數(shù)組,記錄的是一個班25名學生午餐飲料是什么。
>> A = gallery('integerdata',3,[25,1],1);
>> A = categorical(A,1:3,{'milk' 'water''juice'});
然后對類別數(shù)組A進行統(tǒng)計:
>> summary(A)
????milk?????? 8
????water????? 8
????juice????? 9
從結果可以看出有8名學生喜歡喝牛奶,8名學生喜歡水,還有9名學生喜歡果汁。
創(chuàng)建另一個類別數(shù)組,用以表示另一個班28人的午餐飲料情況。
>> B = gallery('integerdata',3,[28,1],3);
>> B = categorical(B,1:3,{'milk' 'water''juice'});
B是一個28×1的和A具有相同類別的數(shù)組。對數(shù)組B進行統(tǒng)計:
>> summary(B)
????milk?????? 12
????water????? 10
????juice?????? 6
從結果可以看出有12名學生喜歡喝牛奶,10名學生喜歡水,還有6名學生喜歡果汁。
有了兩個類別數(shù)組之后,我們可以將其組合成為一個新的數(shù)組。
>> Group1 = [A;B];?????????? %?組合的方法和普通數(shù)值矩陣相同
對總的類別數(shù)組Group1進行統(tǒng)計:
>> summary(Group1)
????milk?????? 20
????water????? 18
????juice????? 15
Group1是一個53×1的類別數(shù)組,包含3個類別:milk,water和juice。
現(xiàn)在我們創(chuàng)建一個新的包含50個學生的類別數(shù)組,可選的飲料增加了蘇打水。
>> Group2 =gallery('integerdata',4,[50,1],2);
>> Group2 = categorical(Group2,1:4,{'juice''milk' 'soda' 'water'});
對Group2進行統(tǒng)計:
>> summary(Group2)
????juice????? 18
????milk?????? 10
????soda?????? 13
????water?????? 9
Group2是一個50×1的數(shù)組,有4個類別:juice,milk,soda和water.
將Group1和Group2組合:
>> students = [Group1;Group2];
對新建的總數(shù)組進行統(tǒng)計:
>> summary(students)
????milk?????? 30
????water????? 27
????juice????? 33
????soda?????? 13
可見結果中的數(shù)組有4個類別。下面使用reordercats來更改數(shù)組中的類別排列順序:
>> students =reordercats(students,{'juice','milk','water','soda'});
>> categories(students)????? %?查看有哪些類別
ans =
??? 'juice'
? ??'milk'
??? 'water'
??? 'soda'