MATLABの得意な行列の操作 文字列編|脱Excel プログラミング

脱Excel プログラミング 脱Excel
MATLABでは、表の扱い、表同士の操作が非常に簡単です。MATLABはもともと数値計算を目的としたプログラミング言語なので数値操作を解説した記事や本は多いですが、文字列操作に関する解説をした記事はほとんどありません。文字列操作にも役立つ、MATLABの仕組みについて解説します。
スポンサーリンク

3つ以上の条件で不要な行を削除する

「3つ以上の条件で不要な行を削除したいとき」に、MATLABでは以下のように実質4行のプログラムで実行できることがわかりました。
このプログラムでは 8行目の以下の一文が重要です。
ListA = ListA(~contains(ListA.Email, exclusion_conditions{i}), :);
この行には 文字列を含む表を簡単に操作するために役立つ、MATLABの非常に重要な機能がいくつも含まれているので、分解してわかりやすく説明します。

MATLABで扱うデータ構造〜テーブル配列とセル配列

このプログラムで何をしているのかを理解するために、まずはじめにMATLABで扱うデータの構造を理解しなければなりません。
MATLABでも、他のプログラミング言語でも、表データを保存する入れ物を「配列」と呼びます。
「配列」のうち、このプログラムで使われているのは、以下の3つです。
テーブル(Table)配列 表形式のデータを、列のラベルを保持して保管します。
セル(Cell)配列 表の要素(データ)を順序を保持して保管します。
論理型(Logical)配列 真偽値 (true または false) を格納するために使用されます。
テーブル配列とセル配列の違いがプログラミング初心者にはわかりにくいものです。
例えが適切かどうかわかりませんが、以下のように考えると理解しやすいかもしれません。
配列の種類
テーブル配列は、表のデータを列のラベルをつけながら保管します。このテーブルでは「くだもの」を入れる箱をつくり、くだものとそれ以外のデータを保管しています。
セル配列は、列のラベルがついておらず、ただデータの値が順番に並んでいるだけです。
以下のようなExcelの表(ファイル名:food.xlsx) があるとき、MATLABで取り込むにはどうしたらよいでしょうか?テーブル配列で取り込むのと、セル配列で取り込むのでは結果が異なります。
セル配列として取り込むとき
A = readcell (‘food.xslx’);
テーブル配列として取り込むとき

B = readtable (‘food.xslx’);

セル配列 テーブル配列
もとの表をセル配列として読み込むと、列名として定義していた1行目の”Fruit”や”Vegetable”という文字も、データの一部として扱われています。
一方、テーブル配列として読み込むと列名として定義していた1行目の”Fruit”や”Vegetable”は、テーブルの列名として扱われ、実質的なデータは 1行目の”りんご”や”トマト”から始まっています。
セル配列とテーブル配列の間で変換する関数もあります。
セル配列”Food”を 以下のようなテーブル配列”Food_T”に変換するには cell2table関数を使います。
Food_T = cell2table(Food, “VariableNames”, [“Fruit”, “Vegetable”] );
 セル配列は、列名を持たないため、テーブル配列に直すときに改めて ”Fruit”と”Vegetable”という列名をつけてあげます。
Cell2table関数の使用例
逆に、テーブル配列”Food_T”から セル配列”Food_C”を取り出したいときには, table2cell 関数を使い、
 Food_C = table2cell(Food_T);
とすれば列名が削除されたデータが格納されます。
このあとの説明でも利用するTipsですが、テーブル配列から表の一部の列を取り出す方法は2通りあります。以下のようなテーブル配列 “Food_T”があったときに、
テーブル配列 Food_T
“テーブル配列名”と”列名”を”.” (ピリオド)でつなぐと、その列のデータがセル配列で取り出せます。
テーブル配列名(:, (列番号))とすると、列番号の一列がテーブル配列として取り出せます。
列”Fruit”の値をセル配列として取り出す

Fruit_C = Food_T.Fruit;

列”Fruit”の値をテーブル配列として取り出す

Fruit_T = Food_T(:, 1);

テーブル配列

表の一部を取り出すときに便利な論理値配列

MATLABで表を操作するときに便利な機能は、論理値配列をつかった操作です。
論理値配列は、それぞれのデータが、ある条件に対して Yesか(=1), Noか(=0)の値だけを保持した配列です。
論理値配列を使うと、表の一部を簡単に取り出せます。

たとえば以下のような”くだもの”というテーブル配列があるとします。この中のデータには、”くだもの”でないデータ”ゴリラ”や”パンダ”が混じっています。これらを除外して、”くだもの”だけのテーブルを作成したいとします。なんらかのコマンドで各データが”くだもの”か”くだものでないか”を判定し、1か0かの論理型配列をつくります。この論理型配列をもとのテーブル配列にかけあわせると、”くだもの”だけのテーブル配列が簡単に作成できるのです。

論理型配列の活用イメージ

文字列操作に便利な”contains”関数

MATLABで文字列が入った表を取り扱うときに欠かせないのが contains関数です。

contains関数は、セル配列の中のすべてのデータについて、指定した文字列が含まれているか、いないかを 0と1の論理値の表で表した論理値配列で返します。

例えば、以下のようなEmailアドレスが入ったテーブル”ListA”があったとき、”@pmail.com”という文字列が入った行を判別したいとします。その場合、

L = contains(ListA.Email, ‘@pmail.com’);

とすれば、’@pmail.com’という文字列が入った位置には’1′ (Yes)が、それ以外には’0′ (No)の値が入った論理値配列が結果で返ってきます。判別ができるのは、テーブル配列ではなくセル配列であることに注意してください。

contains関数の使用例

 

コマンドの解説

さて、以上の知識を得た上で、改めて最初のプログラムの8行目をみてみます。
不要な行を削除する実質的な作業をしているのは以下の1文でした。
ListA = ListA(~contains(ListA.Email, exclusion_conditions{i}), :);

部分ごとに分けて何をしているかみてみましょう。

ListA.Email テーブル配列”ListA”から、列”Email”に含まれる値をセル配列で取り出しています
exclusion_conditions{i} i = 1のときは、除外したいEmailアドレスのうち、最初の要素 ’@pmail.com’を示しています
contains(ListA.Email, exclusion_conditions{i}) i = 1のとき、’@pmail.com’が入った行には ‘1’, そうでない行には ‘0’の論理値が入った論理値配列を返します
~contains(ListA.Email, exclusion_conditions{i}) ‘~’マークは、論理値を否定する記号です。論理値が’1’だったら’0’に、’0’だったら’1’を返します。

したがって’@pmail.com’が入った行には ‘0’, ‘@pmail.com’が入っていない行には ‘1’の論理値が入った論理値配列を返します

ListA(~contains(ListA.Email, exclusion_conditions{i}),:) ListAのうち、’@pmail.com’が入った行を取り除き、’@pmail.com’が入っていない行のみを残したテーブルを作成します

このプログラムでは、For文で 除外するEmailドメインの数だけこの作業を繰り返しています。

したがって、

‘@pmail.com’が除外されたテーブル配列が作成され、
さらに ‘@smail.com’ が除外されたテーブル配列が作成され、
最後に ‘@tmail.com’ が除外されたテーブル配列が作成されます。

除外する条件(この場合はEmailドメイン)は、セル配列 ‘exclusion_conditions’の中に、足していけばいくらでも増やせます。

これによって、3つ以上の条件でも不要な行を削除するプログラムがつくれるのです。
脱Excel
スポンサーリンク