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

조회 수: 17 (최근 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
George Ansari
George Ansari 2017년 8월 8일
dpb, thanks for your answer. First of all, I use cells because I find it easier to work with them in for loops. The example that I showed here is just simplified version of small chunk. Second, I'm not very well familiar with factorized functions, therefore using for loops is easier for me. The last section of your post didn' work, I guess because P must be a matrix, not cell. I'm not sure if I will be able to do it in matrix format because P is a vector that changes when L changes, B is also must be a cell, that changes whenever P=0. Thank you for your help.
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
George Ansari
George Ansari 2017년 8월 8일
Hi Cyclist, thanks for your answer. Removing an element from B whenever P=0 is what I want. For instance, assume there are 3 power generating units, each has its values of P_max, Pg and B. As it can be seen from the code 'P' is also individual to each unit. I calculate it for different 'L'(which is general to all units). When generator's P = 0, there is no power output from the generator, and therefore the corresponding B value must be deleted from the B vector (in other words B vector is reduced to 2 elements, or even to 1 if for k P = 0 twice). The problem is formulated in the way, so it is impossible to have all P's equal to zero. I had something similar to what you suggest, but I was not sure if having B in the form of matrix is a good idea, since I couldn't track if the length of B was reduced when it was needed or not. I was thinking to include in the for loop something like this:
if (P{k}(:) == 0)
B_cell{k}(:) = [];
end
But it didn't work, maybe now it is more clear what I'm trying to implement. Thanks for your help.
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.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Data Type Conversion에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by