6

私は MATLAB を初めて使用し、配列単位の操作と要素単位の操作の間の微妙な点を理解するのに苦労しています。私は大規模なデータセットを扱っていますが、最も単純な方法が常に最速であるとは限りません。この単純化された例のように、文字列の非常に大きなセル配列があります。

% A vertical array of same-length strings
CellArrayOfStrings = {'aaa123'; 'bbb123'; 'ccc123'; 'ddd123'};

たとえば、部分文字列の配列を抽出しようとしています。

'a1'
'b1'
'c1'
'd1'

次のような要素ごとの参照で十分満足しています。

% Simple element-wise substring operation
MySubString = CellArrayOfStrings{2}(3:4);  % Expected result is 'b1'

しかし、次のように、それらすべてを一度に参照するための表記法を理解することはできません。

% Desired result is 'a1','b1','c1','d1'
MyArrayOfSubStrings = CellArrayOfStrings{:}(3:4); % Incorrect notation!

私は、Matlab が strcat などの非常に高速な配列単位の操作を実行できることを知っているので、同様の速度で機能する手法を期待していました。

% An array-wise operation which works quickly
tic
speedTest = strcat(CellArrayOfStrings,'hello');
toc   % About 2 seconds on my machine with >500K array elements

私が試みた舞台裏の反復を使用するすべての for ループと関数は、私のデータセットで実行するのが遅すぎます。これを行う配列単位の表記法はありますか? 誰かが要素ごとの操作と配列ごとの操作についての私の理解を修正できますか?! どうもありがとう!

4

4 に答える 4

5

次のように、それらすべてを一度に参照するための表記法を理解することはできません。

MyArrayOfSubStrings = CellArrayOfStrings{:}(3:4); % Incorrect notation!

これは、中括弧 ( ) がカンマ区切りのリスト{}を返すためです。これは、これらのセルの内容を次のように記述することと同じです。

c{1}, c{2}, and so on....

添字インデックスが1 つの要素のみを参照する場合、MATLAB の構文では()、中括弧の後に括弧 ( ) を使用して、サブ配列 (この場合はサブストリング) をさらに抽出できます。ただし、カンマ区切りのリストに複数の項目が含まれている場合、この構文は禁止されています。

では、代替手段は何ですか?

  1. forループを使用します:

    MyArrayOfSubStrings = char(zeros(numel(CellArrayOfStrings), 2));
    for k = 1:size(MyArrayOfSubStrings, 1)
        MyArrayOfSubStrings(k, :) = CellArrayOfStrings{k}(3:4);
    end
    
  2. 使用cellfunDang Khoaの答えのわずかな変形):

    MyArrayOfSubStrings = cellfun(@(x){x(3:4)}, CellArrayOfStrings);
    MyArrayOfSubStrings = vertcat(MyArrayOfSubStrings{:});
    
  3. 元のセル配列に固定長の文字列が含まれている場合は、Danの提案に従い、セル配列を文字列の配列 (文字の行列) に変換し、形状を変更して目的の列を抽出できます。

    MyArrayOfSubStrings =vertcat(CellArrayOfStrings{:});
    MyArrayOfSubStrings = MyArrayOfSubStrings(:, 3:4);
    
  4. 正規表現など、より複雑な方法を使用します。

    MyArrayOfSubStrings = regexprep(CellArrayOfStrings, '^..(..).*', '$1');
    MyArrayOfSubStrings = vertcat(MyArrayOfSubStrings{:});
    

選択できるソリューションはたくさんありますが、最も適したものを選択してください :) MATLAB の JIT アクセラレーションを使用すると、ほとんどの場合、単純なループで十分だと思います。

また、私のすべての提案では、取得された部分文字列 cell のセル配列が文字列の配列 (行列) に変換されることに注意してください。これは例のためだけです。明らかに、部分文字列をセル配列に格納しておくことができます。

于 2013-10-10T15:37:46.590 に答える
4

cellfunセル配列のすべての要素で動作するため、次のようなことができます。

>> CellArrayOfStrings = {'aaa123'; 'bbb123'; 'ccc123'; 'ddd123'};
>> MyArrayofSubstrings = cellfun(@(str) str(3:4), CellArrayOfStrings, 'UniformOutput', false)
MyArrayofSubstrings = 
    'a1'
    'b1'
    'c1'
    'd1'

要素が文字列であるセル配列ではなく、文字列の行列が必要な場合は、 on を使用charMyArrayOfSubstringsます。これは、各文字列が同じ長さの場合にのみ許可されることに注意してください。

于 2013-10-10T15:25:05.407 に答える
1

あなたはこれを行うことができます:

C = {'aaa123'; 'bbb123'; 'ccc123'; 'ddd123'}
t = reshape([C{:}], 6, [])'
t(:, 3:4)

しかし、あなたの弦がすべて同じ長さである場合に限ります。

于 2013-10-10T15:18:24.353 に答える