大規模容量のstri​ng配列をdoubl​e配列に高速化変換で​きないか

tabularTextDatastore()で取得したテキストデータ(約700万行)の文字列配列をdouble型配列に変換し、
ワークスペースに保持したいですが、処理時間が多くかかっていおります。
高速化の手法はございますでしょうか?
****************
<string配列>
’4.1111’
’4.2222’
’4.3333’
’4.4444’
‥‥(700万行)
↓str2double()にて変換
<double配列>
4.1111
4.2222
4.3333
4.4444
‥‥(700万行)
****************
double型に変換できますが、処理時間約200sかかってしまいます。
(20s以内としたいです。)

 Accepted Answer

michio
michio on 29 Oct 2019

2 votes

MATLAB Coder で mex 関数にするか、Parallel Computing Toolbox で並列処理するか、何れかは取りうる選択肢ですか?
念のため確認ですが、str2double 関数の実行自体(データの読み込みにかかる時間は除く)に約 200s 掛かるということでしょうか?

14 Comments

Takahisa Setoguchi
Takahisa Setoguchi on 29 Oct 2019
ご回答いただきましてありがとうございます。
>MATLAB Coder で mex 関数にするか、Parallel Computing Toolbox で並列処理するか、何れかは取りうる選択肢ですか?
→いいえ、現在のところ、取りうる選択肢ではありません。
(Parallel Computing Toolbox は費用の関係から除外してます。
「MATLAB Coder で mex 関数」は初心者の為、存在を知りませんでした。
どのようなものか検討してみます。ありがとうございます。)
>念のため確認ですが、str2double 関数の実行自体(データの読み込みにかかる時間は除く)に約 200s 掛かるということでしょうか?
→はい、そうです。
(700万行×1列)
Takahisa Setoguchi さま、ちなみに、700万行の文字配列とは、700万×1のCell配列ですか?
for文を用いて、変換されていますか?cellfunで書き換えると少しだけ速くなりそうです。
もし、同様のことをすでにやっていれば申し訳ありません。ただ、AやBを得るのに
ノートPCで、それぞれ約2分かかりますが...
clear;clc
num=randi(100,[7000000 1]);
str=num2cell(num);
tic
A = cellfun(@num2str,str,'UniformOutput',false);
toc
tic
B = cellfun(@str2num,A,'UniformOutput',true);
toc
実際に試してみましたが 700万行は確かに時間がかかりますね・・。
70万行で試してみましたが、mex 関数化で 1/4 程度の処理時間にはなりましたが・・700万行で 20s (1/10) は達成が難しそうです。
参考まで mex 関数化した関数はこちら。(参考:MATLAB アルゴリズムの高速化
function a = mystr2double(b)
N = length(b);
a = zeros(N,1);
for ii=1:N
a(ii) = real(str2double(b{ii}));
end
str2double をコード生成する場合は、
  • Input text must be a string scalar or a character vector.
  • Generated code always returns a complex result.
という制約があるための措置です。
strdata = string(rand(7e5,1));
tic
doubledata1 = str2double(strdata);
toc
celldata = cellstr(strdata);
tic
doubledata2 = mystr2double(celldata);
toc
tic
doubledata3 = mystr2double_mex(celldata);
toc
と実行すると、私の環境では
Elapsed time is 9.835653 seconds.
Elapsed time is 5.812573 seconds.
Elapsed time is 2.177502 seconds.
という具合でした。
Kazuya
Kazuya on 29 Oct 2019
残る可能性としては tabularTextDatastore() での読み込み時に double として読み込む設定ができるかでしょうか。。
Takahisa Setoguchi
Takahisa Setoguchi on 30 Oct 2019
To:Kenta Itakura  様
ご回答ありがとうございます。
>700万行の文字配列とは、700万×1のCell配列ですか?
はい、そうです。
(元の列数は複数ありますが1列を切り出します)
>for文を用いて、変換されていますか?
いいえ、forは使用しない考えでいます。
>cellfunで書き換えると少しだけ速くなりそうです。
こちらは検討済でした。ご提案ありがとうございます。
To:michio
ご回答ありがとうございます。
 >参考まで mex 関数化した関数はこちら。
→ 記述していただいた mystr2double を使用すると3割り程度削減できました。
mex化すると大きく時間を削減できそうですね。
ただCoderのライセンス費用が発生するため厳しそうです。
現在無償版インストール申請し、勉強並びに上記を試そうとしている段階です。
(MEX ファイル化すればライセンス停止後もいつでも使用できる?)
To:Kazuya
ご提案ありがとうございます。
 >読み込み時に double として読み込む設定ができるかでしょうか。。
→ざっと調べた限り見つけることができず、上記別アプローチを試しております。
引き続き時間が許す限り調査したいと思います。
Kazuya
Kazuya on 30 Oct 2019
もし読み込まれているファイルの一部だけ(もしくは偽データ)と読み込みに使用しているコードを見せて頂ければ、私も double 型で読み込む方法を試してみます。
Takahisa Setoguchi
Takahisa Setoguchi on 30 Oct 2019
申し訳ございません。簡易的に記載いたします。
スタンドアロン環境で対応している点と、データ機密の観点
から詳細を記載する事は厳しいです。
<入力データ(string配列)>
’4.1111’
’4.2222’
’4.3333’
’4.4444’
‥‥(700万行)
<現状ソフト>
ds=tabularTextDatastore(filepath,'FileExtensions','.txt')
data=tall(ds);
strt=data{:,1};
tmp=father(strt);
%以下のdouble変換を検討中
target = mystr2double(tmp);
例えば添付のようなものですと
ds=tabularTextDatastore('sampleData.txt','FileExtensions','.txt');
data = readall(ds);
最初から double 型で読み込まれます。。txt ファイルにどうデータが入っているかによって変わるので、実際に読み込まれているデータ形式(を模したもの)が分からないと難しいですね。
Takahisa Setoguchi
Takahisa Setoguchi on 30 Oct 2019
上記詳細記載しなく申し訳なかったのですが、
実際に読み込まれているデータ形式は
2行のヘッダ(文字)があり、
3行目からデータ(数値)があるイメージです。
(複数列あり、ヘッダとデータ列は等しいです。1列目のデータを参照したい)
これを読み込むと文字列になるかと思います。
数値だけですとdoubleで取得できる認識です。
'NumHeaderLines' を使うといけそうです。
ds=tabularTextDatastore('sampleData2.txt','FileExtensions','.txt','NumHeaderLines',2);
data = readall(ds);
Takahisa Setoguchi
Takahisa Setoguchi on 30 Oct 2019
できました!
ありがとうございます^^
Kazuya
Kazuya on 30 Oct 2019
よかったです。
これで処理時間 約200s を稼げたということですね!?
Takahisa Setoguchi
Takahisa Setoguchi on 30 Oct 2019
そうです^^
誠にありがとうございました。
Kazuya
Kazuya on 30 Oct 2019
╭( ・ㅂ・)و ̑̑ グッ !

Sign in to comment.

More Answers (0)

Categories

Asked:

on 29 Oct 2019

Commented:

on 30 Oct 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!