How to remove/add elements to an array?

Hi All,
I have a 115x1 vector, say A which is attached, that I'd like to remove the elements that satisfy some conditions and add some that satisfy others. To be specific,
B = diff(A) = [768 12 757 767 12 756 ...1524.....768 13 754 271]
if B(n)<100, I would like to remove A(n) from A.
if 100 < B(n) < 300, I would like to remove A(n+1) from A.
if B(n) > 1500, I'd like to add an element to A between two elements of A that their diff value satisfies this constraint. for example B(91)=1523, and I like to add a point between A(91) and A(92), i.e., A(91)+A(92)/2.
I know how to do that when there is one constraint, but I struggle when there are more. Any help would be greatly appreciated.
pointToDelet = B<100;
A(pointToDelet) = []

 採用された回答

Voss
Voss 2022 年 12 月 13 日
編集済み: Voss 2022 年 12 月 13 日

0 投票

load locs
A = locs;
B = diff(A);
idx = B < 100;
A(idx) = []; % remove from both A and B because
B(idx) = []; % you need both A and B for the next step
idx = [false; B > 100 & B < 300];
A(idx) = [];
B(idx(2:end)) = [];
inds = find(B > 1500);
for ii = inds(end:-1:1).'
A = [A(1:ii); (A(ii)+A(ii+1))/2; A(ii+1:end)];
end
@Susan: By the way, what should happen if an element of B is exactly 100? According to the rules, if it were slightly less than 100 then the corresponding element of A would be removed; if it were slightly more than 100 then the element of A after it would be removed; but if it's exactly 100, A is unchanged...
Regardless of that, notice that after this process, you can still end up with elements of diff(A) = B > 1500, because the insertion of the new element in A effectively halves the two corresponding elements in B (i.e., the difference is now split half and half among two adjacent elements), but if the original difference was sufficiently large (> 3000), half of it will still be > 1500. An example of this (I don't know if it's a problem for what you're trying to do, but it's something to be aware of):
A = [0; 5000; 11000];
B = diff(A);
inds = find(B > 1500);
for ii = inds(end:-1:1).'
A = [A(1:ii); (A(ii)+A(ii+1))/2; A(ii+1:end)];
end
A
A = 5×1
0 2500 5000 8000 11000
B = diff(A)
B = 4×1
2500 2500 3000 3000

4 件のコメント

Susan
Susan 2022 年 12 月 16 日
@Voss Thank you so much for your response. It works the way I wanted it to work; I appreciate your help. Could you please tell me why, for satisfying the second condition, i.e., idx = [false; B > 100 & B < 300], you considered B(idx(2:end)) = []? Why did you remove B's idx(2:end) elements?
Moreover, if I have a vector named "pks" associated with the "locs", how can I add values to the "pks" when I add value to the "locs"? Assuming for the added locs value that satisfies the 3rd condition, for example locs(10), the corresponding value that should be added to the "pks" equals the mean value of pks(8) and pks(12). the pks vector is attached here. Many thanks for your help.
Voss
Voss 2022 年 12 月 18 日
"Why did you remove B's idx(2:end) elements?"
To keep A and B consistent with each other for the next step.
"how can I add values to the "pks" when I add value to the "locs"? Assuming for the added locs value that satisfies the 3rd condition"
load locs
load pks
whos
Name Size Bytes Class Attributes ans 1x32 64 char cmdout 1x33 66 char locs 114x1 912 double pks 115x1 920 double
% pks has one more element than locs, so I'll assume the first element of
% pks should be removed:
pks(1) = [];
plot(locs,pks)
hold on
Everything that is done to locs must be done to pks:
B = diff(locs);
idx = B < 100;
locs(idx) = [];
pks(idx) = [];
B(idx) = [];
idx = [false; B > 100 & B < 300];
locs(idx) = [];
pks(idx) = [];
B(idx(2:end)) = [];
inds = find(B > 1500);
for ii = inds(end:-1:1).'
locs = [locs(1:ii); (locs(ii)+locs(ii+1))/2; locs(ii+1:end)];
% e.g., pks(10) is avg of pks(8) and pks(12)
pks = [pks(1:ii); (pks(ii-1)+pks(ii+2))/2; pks(ii+1:end)];
end
plot(locs,pks)
Susan
Susan 2023 年 1 月 3 日
@Voss thank you so much for your help!
Voss
Voss 2023 年 1 月 3 日
You're welcome!

サインインしてコメントする。

その他の回答 (1 件)

millercommamatt
millercommamatt 2022 年 12 月 13 日
編集済み: millercommamatt 2022 年 12 月 13 日

0 投票

% B = diff(A) = [768 12 757 767 12 756 ...1524.....768 13 754 271]
% note that B will be one less in length than A
% if B(n)<100, I would like to remove A(n) from A.
A_FilteredOnB = A(1:end-1);
A_FilteredOnB = A_FilteredOnB(B>=100);
% if 100 < B(n) < 300, I would like to remove A(n+1) from A.
A_FilteredOnB_again = A(2:end); % note the difference from before
A_FilteredOnB_again = A_FilteredOnB_again(B >= 100 & B <= 300);
% if B(n) > 1500, I'd like to add an element to A between two elements
% of A that their diff value satisfies this constraint. for example B(91)=1523,
% and I like to add a point between A(91) and A(92), i.e., A(91)+A(92)/2.
% This one is tricky.
inds = find(B>1500);
for ii = inds
A = [A(1:ii), (A(ii)+A(ii+1))/2, A(ii+1:end)];
end

2 件のコメント

Voss
Voss 2022 年 12 月 13 日
@millercommamatt: What happens when B has two elements in a row > 1500?
A = [0 1600 3400];
B = diff(A);
inds = find(B>1500);
for ii = inds
A = [A(1:ii), (A(ii)+A(ii+1))/2, A(ii+1:end)];
end
A
A = 1×5
0 800 1200 1600 3400
Doesn't seem right. That's because when you insert the new element, all the higher indices (i.e., the rest of the elements of inds) are now one lower than they need to be, to account for the new element just inserted.
If you start at the end and go backwards instead, it works:
A = [0 1600 3400];
B = diff(A);
inds = find(B>1500);
for ii = inds(end:-1:1)
A = [A(1:ii), (A(ii)+A(ii+1))/2, A(ii+1:end)];
end
A
A = 1×5
0 800 1600 2500 3400
millercommamatt
millercommamatt 2022 年 12 月 13 日
this is why you test code

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeLoops and Conditional Statements についてさらに検索

質問済み:

2022 年 12 月 13 日

コメント済み:

2023 年 1 月 3 日

Community Treasure Hunt

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

Start Hunting!

Translated by