【问题标题】:Delete rows in a table using a for-loop使用 for 循环删除表中的行
【发布时间】:2015-04-24 09:07:02
【问题描述】:

我的数据在 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,:) = [];

【问题讨论】:

  • 我想我知道发生了什么。你听从了 Ander 的好建议,将 'i' 替换为 'ii'。看起来您忘记在某处替换它,现在您正在访问“变量(i)”,其中“i”代表虚构。所以这个错误告诉你你正在请求一个虚构的索引(这就是为什么它说它必须是真实的)。
  • 也可能是您请求访问索引 0,这将来自您的 todelete = zeros(...)
  • 我找到了一个非常好的解决方案:

标签: matlab if-statement for-loop


【解决方案1】:

你去删除行!

一旦你删除了一行,T 就不再是numberrows1了!

2 个解决方案:

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

2.-不要删除,而是保存要删除的行的索引。做todelete(end+1)=i。然后在for循环之后执行T(todelete,:)=[];,所有行都会被一次性删除。

PD:不要使用i s 变量名是Matlab,它是imaginary unit! 使用ii。

【讨论】:

  • 我尝试使用您的第二个解决方案。但是如何保存行的索引?
  • @Samuel 它写在那里! todelete(end+1)=ii;
【解决方案2】:

在循环结束 T 之前删除行。因此,如果删除了任何行,您的循环将尝试访问已向上移动的行,并且您会收到 index-out-of-bounds 错误。

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

【讨论】:

  • @Samuel 好的,我在您的问题中添加了一条评论,应该会有所帮助。
猜你喜欢
  • 2023-04-10
  • 2016-04-25
  • 2011-01-04
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2022-10-20
  • 2018-02-16
相关资源
最近更新 更多