How to delete row in matrix or cell in a for loop?

44 ビュー (過去 30 日間)
George Ansari
George Ansari 2017 年 8 月 8 日
編集済み: dpb 2017 年 8 月 8 日
I have the following code:
L = [1 10 15];
L_cell = num2cell(L);
P_max = [100;150;200];
Pg = [90 150 150];
B = [1; 2; 3];
B_cell = num2cell(B);
for k = 1:length(L)
P_d{k} = P_max*L_cell{k};
P{k}=P_d{k} - Pg';
end
For each k, I need to delete a row in vector B corresponding to P = 0
I hope it is clear.
Thanks, George.

回答 (2 件)

dpb
dpb 2017 年 8 月 8 日
No, it is not clear, sorry.
Firstly, why are you converting perfectly good vectors to cell arrays?
Second, use the Matlab vectorized functions where possible rather than looping...
>> P_d=P_max.*L % use 'dot' operator for element-wise operations
P_d =
100
1500
3000
>> P=P_d-Pg
P =
10
1350
2850
>>
Lastly, there is no element of P==0.
But the general syntax would be
Pout=HitVal; % set the value targetted
B(P==Pout)=[]; % eliminate corresponding row in B
Example--
>> Pout=1350;
>> B(P==Pout)=[]
B =
1 3
>>
  2 件のコメント
dpb
dpb 2017 年 8 月 8 日
編集済み: dpb 2017 年 8 月 8 日
It's almost inconceivable that cell array is any "easier" in a loop than a a double array -- as you've shown it there's no difference at all excepting requiring the "curlies" to dereference the content of the cell instead of direct addressing with straight parens.
You in fact started out with double arrays and had to go to the effort to convert them to subsequently then have to dereference them to use them -- how can that be "simpler"?
Show enough context to get to the real problem if the above isn't enough -- it would appear that simply throwing away the num2cell calls and using the original variables as shown would be all you need to do; would have to see the actual application to see anything otherwise needed or where a cell array does more good than not.
Cell arrays DO have their place, certainly, but really only need for them is to hold disparate types of objects or objects that aren't of uniform size; neither of those cases is evident here (even if you do remove rows, since variables are simple column vectors, each is still the length it is after the operation and for keeping track you'll want/need to remove the same row from all or you'll have a mishmash of plants to deal with and not know "who's who in the zoo" if don't, otherwise.

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


the cyclist
the cyclist 2017 年 8 月 8 日
In your code, only P{1} has a zero entry. If you put
B(P{k}==0) = [];
as the last line inside your for loop, you will delete the entries in B that correspond to zeros in kth cell of P. In your case, it will remove the 2nd element of B, during the first iteration of the loop.
However, this won't work in a more general case where multiple cells of P contain zeros, because you will have changed the length of B. It's not clear to me how you want to handle that case. Do you want to track all the zeros in the loop (which may repeat in location), and then delete those elements in B?
In that case, this more general code should do what you want:
L = [1 10 15];
L_cell = num2cell(L);
P_max = [100;150;200];
Pg = [90 150 150];
B = [1; 2; 3];
B_cell = num2cell(B);
idxToRemove = false(size(B));
for k = 1:length(L)
P_d{k} = P_max*L_cell{k};
P{k}=P_d{k} - Pg';
idxToRemove = idxToRemove | P{k}==0;
end
B(idxToRemove) = [];
(This will also work in the simpler case, so is more robust. I'm just not sure this is what you want to do.)
  2 件のコメント
dpb
dpb 2017 年 8 月 8 日
編集済み: dpb 2017 年 8 月 8 日
Again, the cell arrays add complexity in processing them owing to dereferencing syntax and that (:) applied to a cell returns a comma-separate list instead of an array which also needs more specialized handling (at a minimum, generally, enclosing in [] to create an array).
The result of comparison operations such as find or == when applied to cell arrays ends up in a bunch of empty cells as well as the logical T in the cell(s) in which the comparison is valid -- processing those then also takes the additional step of isempty or the like.
All in all, it just gets more complicated than need be in all likelihood in going this route.
If the issue is removing rows that aren't significant as in your example; there are other ways to deal with it other than physically removing the rows -- one of the easiest is to simply use logical addressing to only operate on those elements that meet the criterion--in this case, as above where I wrote
B(P==Pout)=[];
instead similar to Star's form you can write
ix=(P==0); % indices of zero elements
and then compute using
P=P_max(~ix).*L(~ix)-Pg(~ix);
which operates only on the non-zero elements.
Alternatively, set the zero elements to NaN and use isfinite on the results to select those with actual values.

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

Community Treasure Hunt

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

Start Hunting!

Translated by