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

62 views (last 30 days)
SATORU SHIMIZU
SATORU SHIMIZU on 5 May 2020
Commented: michio on 11 May 2020
フォルダ内の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
50050行×7列 が 328 個あるとのことですので、大きなファイルを扱う場合のデータストアなどの機能を検討してみてはいかがでしょうか。

michio
michio on 5 May 2020
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 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

Find more on データのインポートとエクスポート in Help Center and File Exchange

Products


Release

R2019a

Community Treasure Hunt

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

Start Hunting!