2016-04-12 7 views
0

日付文字列を数値行列に変換する必要があり、非常に高速に処理する必要があります。私の入力:複数の文字列を使ってsscanfを呼び出す

dateStrings = [ 
    '2015 07 09 12 28 18.17641'; 
    '2015 07 09 12 28 19.17641'; 
    '2015 07 09 12 28 20.17641'] 

私は現在sscanfを使って数値に変換したいと思っています。 (理由は非常に速いからです)。これは、dateStringsに1文字列しか含まれていない場合はうまく動作しますが、この場合は3文字列があります。 (現実的に50 000+)。

sscanf(dateStrings, '%d %d %d %d %d %f') 

所望の出力のように見える行列である:

2015   7   9   12   28  18.176 
2015   7   9   12   28  19.176 
2015   7   9   12   28  20.176 

は、複数の文字列でSSCANFの呼び出しで作成する方法はありますか、私はループを作ることがありますか?

問題を解決する方法については、速い限り、歓迎します。


EDIT:Sueverのソリューションは、私に1トンのスピードを与えました!しかし、上記の入力は実際には真実ではありません。実際の入力は以下のようになります。あなたが実際に細胞を使って作業することがより速いと述べたので、この入力を使ってどのようにしますか?現時点では、私はcell2matを使って入力を変換し、特定のインデックスを空白に置き換えて、'2015 07 09 12 28 18.17641'のような文字列で終わります。

Input is 4x1 cell: 

    '2015-11-18T23:31:49.37486 +01:00' 
    '2015-11-18T23:31:49.37583 +01:00' 
    '2015-11-18T23:31:49.37658 +01:00' 
    '2015-11-18T23:31:49.37735 +01:00' 

答えて

3

2次元文字配列は特に操作が難しいです。最初にcellstrを使用してセルに変換すると、作業がはるかに簡単になります。

C = cellstr(dateStrings); 
output = sscanf(sprintf('%s ', C{:}), '%f'); 
output = reshape(output, [], numel(C)).';  %' 

%// 2015   7   9   12   28  18.176 
%// 2015   7   9   12   28  19.176 
%// 2015   7   9   12   28  20.176 

それとも、あなたはまた、str2numstrjoinの組み合わせを使用することができcellfun

output = cellfun(@(x)sscanf(x, '%f'), C, 'uni', 0); 
output = cat(2, output{:}).'; 

を使用することができます。

output = reshape(str2num(strjoin(C)), [], numel(C)).'; 

正直なところ、あなたの初期データをループするのが最も速いオプションかもしれません。

さまざまな行数の入力を使用してこれらの方法をベンチマークし、次の結果が得られました。第1および第3の見た目が最も魅力的です。

enter image description here

更新

あなたの最初の質問は、すべてのデータの正確な表現ではなかったので、あなたは今sscanfにあなたの書式指定を変更する必要があります。また、cellstrではなく、入力セル配列(Cを直接に渡すこともできます。

sscanf(x, '%d-%d-%dT%d:%d:%f +%*d:%*d') 

だから我々は、上記の答えのいくつかにそれを適用することができます。

%// Option #1 
fmt = '%d-%d-%dT%d:%d:%f +%*d:%*d'; 
output = reshape(sscanf(sprintf('%s ', C{:}), fmt), [], numel(C)).'; %' 

%// Option #2 
output = cellfun(@(x)sscanf(x, fmt), C, 'uni', 0); 
output = cat(2, output{:}).'; %' 

%// Option #4 
output = NaN(numel(C), 6); 
for k = 1:numel(C) 
    output(k,:) = sscanf(C{k}, fmt); 
end 
+0

非常に素晴らしいです!最初の解決策を使用して私にかなり多くのスピードを上げました。私は自分の質問を編集しました。 – Goatcat

+1

@Goatcat解決策を更新しました。次回は、実際のデータを投稿することが有益です。特にそれが解析される必要があるときです。 – Suever

+0

うわー!ありがとう、叙事詩の作品!最初のテストでは、ソリューションは10倍高速です(オプション#1を使用)。私はこれまでに感謝しています! – Goatcat

関連する問題