「位置 2 のインデックスが配列​範囲を超えています」​の解決法を教えてくだ​さい

16 views (last 30 days)
Bonanza
Bonanza on 7 Nov 2022
Commented: Bonanza on 8 Nov 2022
データ総数4478×4490のcsvデータに対して、(x,y) = (1,1)から始める場合、
  1. 2×2、つまり(1,1) ~ (3,3)のデータを切り抜く
  2. 抜き取ったデータ群の最大値と最小値をリストに格納
  3. 一つ隣の2×2、つまり(3,1) ~ (5,3)のデータを切り抜き、最大値と最小値をリストに格納
  4. これを(4475,1) ~ (4478,3)まで繰り返したら一段下にずれて、(1,3) ~ (3,5)の2×2データを切り抜き、最大値と最小値をリストに格納
  5. これを(4475,4488) ~ (4478,4490)まで繰り返す
という処理を想定して作ったものが以下のコードです。
% MATLAB Initialize
clc; clear; allProcessStart=tic;
% Main Directory Path
mainProjectDir = pwd;
% ---------------------------FDA Parameter--------------------------------
% CSV Data Name (without extension)
CSV_filePATH ...
= "C:/python_workspace/221030/No31_1.csv";
% Set Box Size
BoxSize = 2;
% Set Division Number
DivNum = 4096;
% ------------------------Data Import Section-----------------------------
DataFrame = readmatrix(CSV_filePATH);
% -------------------------Main Processing--------------------------------
row1 = 1;
row2 = BoxSize + 1;
col1 = 1;
col2 = BoxSize + 1;
%Max_h = zeros(DivNum^2,1);
%Min_h = zeros(DivNum^2,1);
Max_h = zeros((size(DataFrame,2)-2)*(size(DataFrame,1)-2),1);
Min_h = zeros((size(DataFrame,2)-2)*(size(DataFrame,1)-2),1);
ProcessStart_1 = tic;
for num=1:DivNum ^2
block = DataFrame(row1:row2,col1:col2);
Max_h(num) = max(block,[],'all');
Min_h(num) = min(block,[],'all');
%disp([num2str(row1),' ',num2str(col1)])
if col2 <= size(DataFrame,2)
col1 = col1 + BoxSize;
col2 = col2 + BoxSize;
else
row1 = row1 + BoxSize;
row2 = row2 + BoxSize;
col1 = 1;
col2 = BoxSize + 1;
end
%%{
if row2 >= size(DataFrame,1) + 1
break
end
%}
end
ProcessFinish_1 = toc(ProcessStart_1);
disp(['Division Processing Time: ',num2str(ProcessFinish_1),' [s]'])
N_h = sum((((Max_h - Min_h)/(0.00148267795488433*BoxSize)) + 1),1);
N_h_log = log2(N_h)
allProcessFinish = toc(allProcessStart);
disp(['All processing finish time: ',num2str(allProcessFinish),' [s]'])
% ------------------------------------------------------------------------
これを実行したところ、以下のようなエラーコードが返ってきました。
位置 2 のインデックスが配列範囲を超えています。インデックスは 4490 を超えてはなりません。
エラー: test (47)
block = DataFrame(row1:row2,col1:col2);
原因は "col2" が最終的に4491になってしまうからだとわかったのですが、if文の一節で4490を超えた値を取った時点で一段下にずれるようにした(つもり)にもかかわらず4491になってしまう理由がわかりません。
このような結果が返ってくる理由や改善案を教えていただきたいです。
また、区切るデータ範囲を4×4、8×8、16×16と倍々にしていく予定なので、そこでも流用できるようにもしたいです。
使用しているcsvファイルはzipにしても容量が大きすぎるようで載せられませんでした。申し訳ありません。

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 7 Nov 2022
> このような結果が返ってくる理由
col2が3,5,7,... と2ずつ増加していくと4490を跨いでしまい、その次の周期で範囲を超えたインデックスにアクセスしてしまいます。この条件式で閾値を跨がず上手くいくのは、増分 BoxSize = 1 の時だけです。
%block = DataFrame(row1:row2,col1:col2);
% (中略)
% if col2 <= size(DataFrame,2) % 4489 <= 4490 まだ通る!
% col1 = col1 + BoxSize; % col1 = 4487 + 2 = 4489
% col2 = col2 + BoxSize; % col2 = 4489 + 2 = 4491
% 次の周期で DataFrame(row1:row2,4489:4491) にアクセスしてしまう⇒エラー!
> 2×2、つまり(1,1) ~ (3,3)のデータを切り抜く ⇒ 3x3になってしまう
質問の要件とプログラムの動作が違います。今のプログラムでは BoxSize より1大きいデータ群が抜き取られてしまいます。しかも1~3、3~5、5~7、と部分的に重なって意図した最大/最小値が得られていません。
DataFrame = zeros(100,100); % 適当なサンプルデータ
DataFrame(1:3, 1:3) % 左記のサイズは2×2ではなく3×3になる
ans = 3×3
0 0 0 0 0 0 0 0 0
> 改善案を教えていただきたいです
% -------------------------Main Processing--------------------------------
row1 = 1;
row2 = BoxSize;% + 1; % 【変更点】1からBoxSizeまで
col1 = 1;
col2 = BoxSize;% + 1; % 【変更点】1からBoxSizeまで
%Max_h = zeros(DivNum^2,1);
%Min_h = zeros(DivNum^2,1);
Max_h = zeros((size(DataFrame,2)-2)*(size(DataFrame,1)-2),1);
Min_h = zeros((size(DataFrame,2)-2)*(size(DataFrame,1)-2),1);
ProcessStart_1 = tic;
for num=1:DivNum ^2
block = DataFrame(row1:row2,col1:col2);
Max_h(num) = max(block,[],'all');
Min_h(num) = min(block,[],'all');
%disp([num2str(row1),' ',num2str(col1)])
if col2 <= size(DataFrame,2) - BoxSize % 【変更点】BoxSizeを引いた閾値と比較する
col1 = col1 + BoxSize;
col2 = col2 + BoxSize;
else
row1 = row1 + BoxSize;
row2 = row2 + BoxSize;
col1 = 1;
col2 = BoxSize + 1;
end
%%{
if row2 >= size(DataFrame,1) + 1
break
end
%}
end
  1 Comment
Bonanza
Bonanza on 8 Nov 2022
早速のご返答ありがとうございました!
非常にわかりやすくご指摘していただいたお陰ですぐに理解できました!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!