MATLAB For Loop根据另一列中的条目对一列中的#s进行计数

问题描述

我有50个电子表格,其中包含多个计分栏: 一列(AG)的数字编码为1:13,另一列(SEC)的数字编码为1:6。

例如:

AG   SEC
 1    1
 2    1
 4    1
 13   1
 3    2
 12   2

我想编写一个for循环,计算.SEC中与.AG中的#s 1:5对应的所有1。 (输出将为3-不会计算与13对应的1)。我需要在.SEC(1:6)中的所有#事件中都发生这种情况。最终输出将在第一列中包含电子表格名称,并在每个后续列中将.SEC = 1,2,3,4,5,6计数。

我当前的代码为.SEC中的.AG总数创建了一个变量,但没有区别(计算.AG中任何数字的次数,而不是计算特定值)

scoringfiles是一个50个项目的路径列表(当我执行readtable(scoringfiles)时,它将遍历该列表并读取excel文件。filelist是一个仅包含文件名的50个项目列表。

for i=1:length(scoringfiles)

  if contains(filelist(i,:),"sheet")
        disp(i)
        sheetnum=[sheetnum extractBetween(filelist{i},1,4)]
        
        s1=[s1 length(find(readtable(scoringfiles(i,:)).SEC==1))]
        s2=[s2 length(find(readtable(scoringfiles(i,:)).SEC==2))]    
        s3=[s3 length(find(readtable(scoringfiles(i,:)).SEC==3))]
        s4=[s4 length(find(readtable(scoringfiles(i,:)).SEC==4))]
        s5=[s5 length(find(readtable(scoringfiles(i,:)).SEC==5))]
        s6=[s6 length(find(readtable(scoringfiles(i,:)).SEC==6))]

  elseif contains(filelist(i,"graph")
       disp("not sheet")

  end
end

解决方法

在MATLAB中,ij是虚数单位。为了避免重新定义它,您应该养成习惯使用iijj作为循环变量,而不是ij

现在回到主要问题:

假设您已将文件内容读入data变量中。这将是一个Nx2数组。

仅当AG处于1:5范围内时,您才关心它。让我们用filter创建一个true数组,其中AG在范围内,false在其他位置。

filter = data(:,1) >= 1 & data(:,1) <= 5;

为了清晰起见,我们首先将这些列分为两个变量。使用过滤器仅选择符合我们条件的行。

ag = data(filter,1);
sec = data(filter,2);

现在,您要遍历sec中的每个 unique 值,并计算ag条目的数量。

unique_sec = unique(sec);
counts = zeros(size(unique_sec)); % Preallocate a zeros array to save our answer in
for ii = 1:length(unique_sec)
    sec_value = unique_sec(ii); % Get the value of SEC
    matches = sec == sec_value; % Make a filter for rows that have this value
    % matches is a logical array. true = 1,false = 0. sum gives number of trues.
    counts(ii) = sum(matches); 
end

或者,如果您不想在之前进行过滤,则可以在循环内对1 <= AG <= 5进行过滤:

ag = data(:,1);
sec = data(:,2);
unique_sec = unique(sec);
counts = zeros(size(unique_sec)); 
for ii = 1:length(unique_sec)
    sec_value = unique_sec(ii);
    matches = sec == sec_value & ag >= 1 & ag <= 5; % Add more conditions to the filter
    counts(ii) = sum(matches); 
end

如果要对多个文件执行此操作,请遍历它们并将文件读取到data变量中。

,

借助Pranav的帮助,我弄清楚了如何应用过滤器。就像在遍历我的电子表格中进行迭代一样,只需将过滤器添加到for循环的每一行即可。见下文:

此示例仅在S1和S2上可见。实际上,我有6个不同的#s来创建6个表,每个电子表格都有计数。

for i=1:length(scoringfiles)
    filter1 = readtable(scoringfiles(i,:)).AG >= 1;
    filter2 = readtable(scoringfiles(i,:)).AG <= 5;
  if contains(filelist(i,:),"sheet")
        disp(i)
        sheetnum=[sheetnum extractBetween(filelist{i},1,4)]
        
        s1=[s1 length(find(readtable(scoringfiles(i,:)).SEC==1 & filter1 & filter2))]
        s2=[s2 length(find(readtable(scoringfiles(i,:)).SEC==2 & filter1 & filter2))]    
       

  elseif contains(filelist(i,"graph")
       disp("not sheet")

  end
end

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...