フィルターのクリア

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

5 ビュー (過去 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 Center および File ExchangeData Type Identification についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by