フォルダ内のCSVフ​ァイルをすべて読み込​み、演算を実施するプ​ログラム実行時に発生​するメモリー不足エラ​ーの対処法について

フォルダ内のCSVファイルをすべて読み込み、演算を実施する為に、下記プログラムを作成しました。
実行したところ、27行目以降のForループのところ(CSV読み込み、演算)でメモリ不足エラーが発生します(JxBrowser Chromium Native Process(32bit)が停止して、matlabの画面が落ちてしまう)
実行可能なプログラムをしりたいです。
※フォルダ内には、328個のCSVファイルがあり、一つのCSVファイルには50050行×7列のデータがあります。
以下、実行したプログラム
%%% フォルダ内のcsvファイルをすべて読み込み
%% 読み込んだデータは変数dataにcell配列として格納される。ファイル名はfilenameにcell配列として格納される
% csvファイルが入っているフォルダを入力
rootname='C:\Users\10001169344\Desktop\CSV\'
% 検索パスにフォルダを追加
addpath(rootname) ;
%フォルダの情報を取得します
dirinfo = dir(fullfile(rootname))
%フォルダの中のファイル名を取得します
filename = {dirinfo.name};
%filenameの中に '.'と'..'が入っているので削除
filename = filename(:,3:end);
%読み込みファイル数を指定
numfiles = length(filename);
%csv読み込む際に読み込みをスキップする行、列を指定する。
skiprow=10
skipcol=1
%フォルダ内にあるcsvをすべて読み込み
%読み込んだcsvファイルデータの1列目の演算値をpressure、2列名の演算値をAxcel_sensor_x、3列名の演算値をAxcel_sensor_y
%4列名の演算値をAxcel_sensor_z、2~4列名の演算値をAxcel_sensor
%5列名の演算値をAxcel_engine_x、6列名の演算値をAxcel_engine_y
%7列名の演算値をAxcel_engine_z、5~7列名の演算値をAxcel_engineに代入する。
for k = 1:numfiles
read_data = csvread(filename{k},skiprow,skipcol)
pressure(:,k)=(read_data(:,1)-mean(read_data(:,1)))/214.5*100
Axcel_sensor_x(:,k)=(read_data(:,2))*1000
Axcel_sensor_y(:,k)=(read_data(:,3))*1000
Axcel_sensor_z(:,k)=(read_data(:,4))*1000
Axcel_sensor(:,k)=sqrt(power(read_data(:,2),2)+power(read_data(:,3),2)+power(read_data(:,4),2))*1000
Axcel_engine_x(:,k)=(read_data(:,5))*1000
Axcel_engine_y(:,k)=(read_data(:,6))*1000
Axcel_engine_z(:,k)=(read_data(:,7))*1000
Axcel_engine(:,k)=sqrt(power(read_data(:,5),2)+power(read_data(:,6),2)+power(read_data(:,7),2))*1000
end

Answers (2)

Musashi Ito
Musashi Ito on 5 May 2020

0 votes

50050行×7列 が 328 個あるとのことですので、大きなファイルを扱う場合のデータストアなどの機能を検討してみてはいかがでしょうか。
michio
michio on 5 May 2020

0 votes

50050x7 の double 型の行列を 328 ファイル分 = 900 MB 程度ですが、、これくらいは読み込めそうな環境でしょうか?
もし記載して頂いたコードがすべてであれば、pressure, Axcel_sensor_x などの変数に作成しておくことで解決しそうな気がします。参考:「メモリの事前割り当て」https://jp.mathworks.com/help/matlab/matlab_prog/preallocating-arrays.html
以下のように変えてみてください。
N1 = 50050;
pressure = zeros(N1,numfiles);
Axcel_sensor_x = zeros(N1,numfiles);
Axcel_sensor_y = zeros(N1,numfiles);
Axcel_sensor_z = zeros(N1,numfiles);
Axcel_sensor = zeros(N1,numfiles);
Axcel_engine_x = zeros(N1,numfiles);
Axcel_engine_y = zeros(N1,numfiles);
Axcel_engine_z = zeros(N1,numfiles);
Axcel_engine = zeros(N1,numfiles);
for k = 1:numfiles
read_data = csvread(filename{k},skiprow,skipcol)
pressure(:,k)=(read_data(:,1)-mean(read_data(:,1)))/214.5*100
Axcel_sensor_x(:,k)=(read_data(:,2))*1000
Axcel_sensor_y(:,k)=(read_data(:,3))*1000
Axcel_sensor_z(:,k)=(read_data(:,4))*1000
Axcel_sensor(:,k)=sqrt(power(read_data(:,2),2)+power(read_data(:,3),2)+power(read_data(:,4),2))*1000
Axcel_engine_x(:,k)=(read_data(:,5))*1000
Axcel_engine_y(:,k)=(read_data(:,6))*1000
Axcel_engine_z(:,k)=(read_data(:,7))*1000
Axcel_engine(:,k)=sqrt(power(read_data(:,5),2)+power(read_data(:,6),2)+power(read_data(:,7),2))*1000
end

5 Comments

SATORU SHIMIZU
SATORU SHIMIZU on 6 May 2020
回答ありがとうございます。
上記で試してみましたが、メモリの使用量としては変わらず、添付の画像の通り、処理中はMatlabで12G使用し、
計算が完了するまでにMatlabが落ちてしまいました。
データストアで実施するしかないのでしょうか?
SATORU SHIMIZU
SATORU SHIMIZU on 6 May 2020
メモリ環境は下記とおりです。
利用可能な最大配列: 16134 MB (1.692e+10 bytes) *
すべての配列に利用可能なメモリ: 16134 MB (1.692e+10 bytes) *
MATLAB で使用されるメモリ: 1700 MB (1.782e+09 bytes)
物理メモリ (RAM): 16275 MB (1.707e+10 bytes)
michio
michio on 6 May 2020
変わりませんでしたか・・。失礼しました。
念のための確認ですが、最初記載いただいたコード部分(csv ファイルからデータを読み込んで、各変数(pressure, Axcel_sensor など)を作る部分だけでメモリを 12 GB 使用してしまっているという状況でしょうか?
whos pressure
での出力も念のため確認して頂けますか?
SATORU SHIMIZU
SATORU SHIMIZU on 10 May 2020
最初記載したコードがすべてです。その部分で、12GB使用しているようです。
whosで確認した結果です。
Name Size Bytes Class Attributes
pressure 50050x328 131331200 double
いろいろ試行しましたが、うまくいかないので、結局pythonで実行し、うまくいきました。
ご回答、ありがとうございました。
michio
michio on 11 May 2020
タイムリーに解決できず申し訳ございません。

Sign in to comment.

Categories

Products

Release

R2019a

Asked:

on 5 May 2020

Commented:

on 11 May 2020

Community Treasure Hunt

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

Start Hunting!