使用for循环删除表中的行

时间:2015-04-24 09:07:02

标签: matlab if-statement for-loop

我的数据被格式化为Matlab中的表:T =

  J K L M N O
  121 1 1 a1 3b 1.72
  121 2 1 2c 4d 1.43
  0 3 1 e3 5f nan
  299 4 1 g4 h5 1.64
  299 1 2 4i 4j 1.48
  0 2 2 6k nan 2.33
  0 3 2 m7 8n nan
  455 4 1 i4 j5 3.24
  4 2 o8 p0 1.92

我想删除列J中有零或299的每一行

我试过

number_of_rows = size(T,1);
for i=1:number_of_rows
    if T{i,1} == 299
        T(i,:) = [];
    end

     if T{i,1} == 0.0
         T(i,:) = [];
     end
end

但我总是犯错:

  

行索引超出表格尺寸。

我尝试索引要删除的行:

number_of_rows = size(T,1);
todelete = zeros(size(T,1),1);

for ii=1:number_of_rows

    if (T{ii,1} == 8.4) || (T{ii,1} == 1.5)
       todelete(ii) = 1;
    end

end

T(todelete,:) = [];

但是后来我发现了一个我不明白的错误

  

下标索引必须是实数正整数或逻辑。

为什么T(todelete,:) = [];不起作用?

我刚刚找到了解决问题的方法。我使用函数

  

查找()

然后,我所要做的就是:

to_delete = find(T.K==0 | T.K==8.4);
T(to_delete,:) = [];

2 个答案:

答案 0 :(得分:2)

你去删除行!

删除行后,>>> var_p1 = 'test' >>> var_p2 = 'test2' >>> print(("(x {})(x {})".format(var_p1, var_p2))) (x test)(x test2) 不再有T

2个解决方案:

1.创建numberrows1,然后将Tdeleted=T;替换为T(i,:) = [];

2. - 不要删除,而是保存要删除的行的索引。做Tdeleted(i,:) = [];。然后在for循环后执行todelete(end+1)=i,所有行将立即删除。

PD:不要使用T(todelete,:)=[];变量名是Matlab,它是imaginary unit!使用ii。

答案 1 :(得分:0)

在循环结束T之前删除行。因此,如果删除了任何行,您的循环将尝试访问向上移动的行,并且您将获得索引越界错误。

numberrows1 = size(T,1);
for i=1:numberrows1
    if T{i,1} == 8.4
        T(i,:) = [];
    end

     if T{i,1} == 0.0
         T(i,:) = [];  % Here you remove a row. From now on size(T) is (numberrows-1,...)
     end
end

在matlab中,你通常不想以这种方式操纵变量。通常,一种好的方法是循环遍历T 而不操作并存储要删除的行的索引。最简单的方法是分配一个新的T_clean,它将保留T而没有删除的行。这样的事情应该有效:

numberrows1 = size(T,1);
deletion_indices = zeros(size(T,1),1);

for i=1:numberrows1
    if T{i,1} == 8.4
        T(i,:) = [];
    end

     if T{i,1} == 0.0
%          T(i,:) = cell(4,1);
        deletion_indices(i) = 1; % Flag for deletion
     end
end

% Allocate new T
new_numberrows1 = numberrows1 - sum(deletion_indices);
T_clean = cell( new_numberrows1, size(T,2) );

row_index = 1;
for iRow=1:new_numberrows1
    % Add row if it's not marked for deletion
    if ( ~deletion_indices(iRow) )
        T_clean(iRow,:) = T(row_index,:);
    end

    % Increase row_index
    row_index = row_index +1;
end