Main Content

cell 配列のデータへのアクセス

基本インデックス付け

"cell 配列" は cell と呼ばれるインデックス付きのデータ コンテナーをもつデータ型です。各セルには任意のデータ型を含めることができます。cell 配列は、数値データとテキスト データの両方を含む列など、一貫性のない形式をもつファイルのデータを保持する場合によく使用されます。

たとえば、異なる種類のデータが混在している 2 行 3 列の cell 配列について考えます。

C = {'one','two','three'; 
     100,200,rand(3,3)}
C=2×3 cell array
    {'one'}    {'two'}    {'three'   }
    {[100]}    {[200]}    {3x3 double}

各要素は cell 内にあります。標準の小かっこを使用してこの配列にインデックスを付けると、結果として、cell を含む cell 配列のサブセットになります。

C2 = C(1:2,1:2)
C2=2×2 cell array
    {'one'}    {'two'}
    {[100]}    {[200]}

特定の cell 内の内容を読み書きするには、インデックスを中かっこで囲みます。

R = C{2,3}
R = 3×3

    0.8147    0.9134    0.2785
    0.9058    0.6324    0.5469
    0.1270    0.0975    0.9575

C{1,3} = 'longer text in a third location'
C=2×3 cell array
    {'one'}    {'two'}    {'longer text in a third location'}
    {[100]}    {[200]}    {3x3 double                       }

複数の cell の内容を同時に置換するには、小かっこを使用して cell を参照し、中かっこを使用して同等のサイズの cell 配列を定義します。

C(1,1:2) = {'first','second'}
C=2×3 cell array
    {'first'}    {'second'}    {'longer text in a third location'}
    {[  100]}    {[   200]}    {3x3 double                       }

複数の cell からのデータの読み取り

MATLAB® のデータ処理関数のほとんどは、均一なデータ型を持つ方形配列に対して処理を行います。cell 配列には異なる型とサイズを混在させて含めることができるため、データを処理する前に cell からデータを抽出して結合する必要がある場合があります。このセクションでは、いくつかの一般的なシナリオについて説明します。

特定の cell 内のテキスト

cell 配列全体または cell の既知のサブセットにテキストが含まれている場合、cell にインデックスを付けて、MATLAB のテキスト処理関数のいずれかに直接渡すことができます。たとえば、C の最初の行の各要素内で文字 "t" が出現する場所を検索します。

ts = strfind(C(1,:),'t')
ts=1×3 cell array
    {[5]}    {0x0 double}    {[8 11 18 28]}

特定の cell の数値

cell 配列内の数値データを処理する主な方法は次の 2 つです。

  • 該当する cell の内容を単一の数値配列に結合してから、その配列を処理する。

  • 個別の cell を別個に処理する。

数値 cell を結合するには、関数 cell2mat を使用します。連結するには、各 cell 内の配列のサイズに互換性がなければなりません。たとえば、C の 2 行目の最初の 2 つの要素はスカラー値です。1 行 2 列の数値ベクトルに結合します。

v = cell2mat(C(2,1:2))
v = 1×2

   100   200

個別の cell を処理するには、関数 cellfun を使用できます。cellfun を呼び出す際に、各 cell に適用する関数を指定します。@ 記号を使用して、それが関数であることを示し、関数ハンドルを作成します。たとえば、C の 2 行目の各 cell の長さを求めます。

len = cellfun(@length,C(2,:))
len = 1×3

     1     1     3

インデックスが不明な cell のデータ

いくつかの cell に処理対象のデータが含まれているが、正確なインデックスがわからない場合は、次のいずれかのオプションを使用できます。

  • 論理インデックス付けを使用して特定の条件を満たす要素をすべて検索してから、該当する要素を処理します。

  • for ループまたは while ループを使用して、cell を一度に 1 つずつ調べて処理します。

たとえば、文字ベクトルを含む cell のみを処理するとします。論理インデックス付けを利用するには、まず ischar を指定して関数 cellfun を使用して該当する cell を検索します。

idx = cellfun(@ischar,C)
idx = 2x3 logical array

   1   1   1
   0   0   0

次に、logical 配列を使用して cell 配列 C(idx) にインデックスを付けます。インデックス付け操作の結果は列ベクトルであり、strlength などのテキスト処理関数に渡すことができます。

len = strlength(C(idx))
len = 3×1

     5
     6
    31

もう 1 つの方法として、ループを使用して各 cell の内容を調べて処理できます。たとえば、文字 "t" を含む cell を検索し、該当する cell をループして string 配列に結合します。ループで string 配列に追加された要素の数を変数 n で追跡します。

n = 0;
for k = 1:numel(C)
    if ischar(C{k}) && contains(C{k},"t")
        n = n + 1;
        txt(n) = string(C{k});
    end
end
txt
txt = 1x2 string
    "first"    "longer text in a third location"

複数の cell へのインデックス付け

中かっこのインデックス付けを使用して複数の cell を参照した場合、MATLAB は cell の内容を "コンマ区切りリスト" として返します。以下に例を示します。

C{1:2,1:2}

上記は、以下と同じ結果を得ます。

C{1,1}, C{2,1}, C{1,2}, C{2,2}.

各セルが異なるデータの型を含むことができるので、このリストを 1 つの変数に代入することはできません。しかし、リストをセルと同数の変数に代入することはできます。

[v1,v2,v3,v4] = C{1:2,1:2}
v1 = 
'first'
v2 = 100
v3 = 
'second'
v4 = 200

各 cell が互換性のあるサイズをもつ同じ型のデータを含んでいる場合は、配列連結演算子 [] をコンマ区切りリストに適用することにより 1 つの変数を作成できます。

v = [C{2,1:2}]
v = 1×2

   100   200

cell の内容を連結できない場合は、結果を新しい cell 配列、table、またはその他の異種コンテナーに保存します。たとえば、C の 2 行目の数値データを table に変換します。変数名には C の 1 行目のテキスト データを使用します。

t = cell2table(C(2,:),VariableNames=C(1,:))
t=1×3 table
    first    second    longer text in a third location
    _____    ______    _______________________________

     100      200               {3x3 double}          

cell 内の配列へのインデックス付け

cell に配列が含まれている場合は、2 つのレベルのインデックスを使用してその配列内の特定の要素にアクセスできます。まず、中かっこを使用して cell の内容にアクセスします。次に、その cell 内の配列の型に応じた標準のインデックス付け構文を使用します。

たとえば、C{2,3} は乱数の 3 行 3 列の行列を返します。小かっこでインデックスを付けて、該当する行列の 2 行目を抽出します。

C{2,3}(2,:)
ans = 1×3

    0.9058    0.6324    0.5469

cell に cell 配列が含まれている場合は、インデックス付けに中かっこを使用します。構造体配列が含まれている場合は、ドット表記を使用して特定のフィールドを参照します。たとえば、2 行 1 列の cell 配列と、フィールド f1 および f2 をもつスカラー構造体を含む cell 配列について考えます。

c = {'A'; ones(3,4)};
s = struct("f1",'B',"f2",ones(5,6)); 
C = {c,s}
C=1×2 cell array
    {2x1 cell}    {1x1 struct}

入れ子にされた cell 配列と構造体から、1 から成る配列を抽出します。

A1 = C{1}{2}
A1 = 3×4

     1     1     1     1
     1     1     1     1
     1     1     1     1

A2 = C{2}.f2
A2 = 5×6

     1     1     1     1     1     1
     1     1     1     1     1     1
     1     1     1     1     1     1
     1     1     1     1     1     1
     1     1     1     1     1     1

セルと構造体配列の任意の数値を入れ子にすることができます。同じインデックス付けルールを階層の下位レベルに適用します。たとえば、次の構文は、参照されている cell に予期される cell または構造体配列が含まれている場合に有効です。

C{1}{2}{3}

C{4}.f1.f2(1)

C{5}.f3.f4{1}

どのインデックス付けレベルでも、複数の cell を参照すると、MATLAB はコンマ区切りリストを返します。詳細については、複数の cell へのインデックス付けを参照してください。

参考

| |

関連するトピック