Excelの数値変換について

図に添付したようにB列に0,1,10の数値があります。この数値を1を見つけたら10を見つけるまでの間の数値を5に変換したいです。現在説明のためC列に変換後を示しています。出力は同じB列に変換したもの上書きしたいです。どなたか助言をお願いいたします。

 Accepted Answer

Hernia Baby
Hernia Baby on 27 May 2021
Edited: Hernia Baby on 28 May 2021

3 votes

find関数で1と10の座標を見つけ、その間を5で埋めます
※存在しないx1を設定していましたのでxに修正しました
clear,clc;
x=xlsread('test2.xlsx');
[idx(:,1), ~] = find(x==1);
[idx(:,2), ~] = find(x==10);
for i = 1:length(idx(:,1))
x(idx(i,1):idx(i,2),1)=5;
end
x

7 Comments

健気 大川
健気 大川 on 28 May 2021
お忙しい中、ありがとうございます。1と10の数が異なるとき、割り当ての次元が一致しないのですが、どうしたらよいのでしょうか。
Hernia Baby
Hernia Baby on 28 May 2021
返信ありがとうございます。 恐らく1と10が順序よく並んでいない状態と思います。
以下のうちどのような状態でしょうか? ①1の後に10がない状態 ②1と10の間に1or10がある  1 000 10 000 10 0000 1 000
コメントいただければ 仕事が終わり次第、こちら解決に取り掛かりたく思います。 よろしくお願いします。
健気 大川
健気 大川 on 28 May 2021
こちらこそありがとうございます。
①の状態です。1の後に10がない、又は10の後に1がない状態です。
イメージを画像で添付させていただきました。
お忙しいところ恐れ入りますが、ご検討の程よろしくお願い致します。
はみ出たほうの行番号を消してしまえば変換せずに行けます
たとえば(a)の場合で計算します。
clear,clc;
% x=xlsread('test2.xlsx');
% test
x = zeros(10,1);
b = 1, a = 10; %(a)
% a = 1, b = 10; %(b)
x([3 9],1) = a;
x(6,1) =b;
% ここから計算
[idx1(:), ~] = find(x==1);
[idx2(:), ~] = find(x==10);
% ここで余った分をそのままにする
if length(idx1) > length(idx2)
% 1で終わるとき⇒最後の1以降はそのまま
idx1 = idx1(1:end-1);
elseif length(idx1) < length(idx2)
% 10で始まるとき⇒最初の10以前はそのまま
idx2 = idx2(2:end);
end
for i = 1:length(idx1(:,1))
x(idx1(i):idx2(i),1)=5;
end
x
x =
0
0
10  <-ここは変えてません
0
0
5
5
5
5
0
健気 大川
健気 大川 on 28 May 2021
お忙し中ありかとうございます。こちらの問題は解決いたしました。
お手数おかけしますが、②のような時はどうしたらよいでしょうか。また①、②が混在した場合はどうしたらよいでしょうか。お忙しいところ恐れ入りますが、ご検討の程よろしくお願い致します。
イメージを添付いたします。
網羅した物を用意しました。
PointはStep2 ~ 4になります。
Step2 端点補正
Step3 1~10のペアを作る
Step4では 以下のようなケースを想定しています(パターン2)
  ... 10 0 1 0 0 0 0 1 0 0 0 10 0 0 ...
⇒ ... 10 0 1 0 0 0 0 5 5 5 5 5 0 0 ...
clear,clc;
% x=xlsread('test2.xlsx');
%% Step0 初期値設定
x = zeros(17,1);
b = 1; a = 10; %パターン1
% a = 1; b = 10; %パターン2
x([2 6 9 11 15],1) = a;
x([4 13 17],1) =b;
%% Step1 1と10の行番号抽出
[idx1(:), ~] = find(x==1); % 1の行番号
[idx2(:), ~] = find(x==10); % 10の行番号
%% Step2 端点補正(1から始まり10で終わる)
idx2 = idx2(idx1(1)<idx2); % 最初の1以前の10を除外
idx1 = idx1(idx1<idx2(end)); % 最後の10以降の1を除外
%% Step3 [1 0 … 0 10]のペアを作る
% 各1の行番号以上かつ最近傍の10の行番号をペアで格納
cnt = 0;
while cnt < length(idx1)
cnt = cnt + 1;
idx(cnt,1) = idx1(cnt);
idx(cnt,2) = min(idx2(idx2>idx1(cnt)));
end
%% Step4 [1 0 … 1 … 0 10]の場合
% 1と10の間で最も近いものを採用
% 詳細は以下url
% https://jp.mathworks.com/matlabcentral/answers/812535-#answer_684355
[~,num] = unique(idx(:,2),'last');
idx = idx(num,:);
%% Step5 変換開始
x1 = x; % 比較用
for i = 1:length(idx(:,1))
x1(idx(i,1):idx(i,2),1)=5;
end
%% Step6 出力結果比較
[x, x1] % [変換前, 変換後]
ans =
0 0
10 10
0 0
1 5
0 5
10 5
0 0
0 0
10 10
0 0
10 10
0 0
1 5
0 5
10 5
0 0
1 1
健気 大川
健気 大川 on 29 May 2021
解決いたしました!何度も質問してしまいお手数おかけいたしました。
本当にありがとうございました!

Sign in to comment.

More Answers (1)

Atsushi Ueno
Atsushi Ueno on 27 May 2021
Edited: Atsushi Ueno on 27 May 2021

2 votes

上記Q&Aを真似てExcelの入出力を追記しました。
% 数値だけ読み込む(Aはテストデータと正解の両方)
[A,~,~] = xlsread('test4matlab.xls');
% テストデータだけをBにおく
B = A(:,1)'
% 結果をおくCを一旦ゼロクリアする
C = zeros(1,size(B,2));
% Cの「B=1の所からB=10の所まで」を5に設定する
C(cell2mat(arrayfun(@colon, find(B==1), find(B==10), 'un', false))) = 5
% 同じB列に変換したもの上書きする
xlswrite('test4matlab.xls', C', 'B2:B24');

Categories

Find more on 環境と設定 in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!