【问题标题】:Dividing a matrix into two parts将矩阵分成两部分
【发布时间】:2019-12-10 14:33:06
【问题描述】:

我正在尝试对我的数据集进行分类。为此,我将使用数据集的第 4 列。如果数据集的第 4 列等于 1,则该行将添加到名为 Q1 的新矩阵中。如果数据集的第 4 列等于 2,则该行将添加到矩阵 Q2

我的代码:

i = input('Enter a start row: ');
j = input('Enter a end row: ');
search = importfiledataset('search-queries-features.csv',i,j);
[n, p] = size(search);

if j>n
   disp('Please enter a smaller number!');
end

for s = i:j
    class_id = search(s,4);
    if class_id == 1 
       Q1 = search(s,1:4)        
    elseif class_id ==2  
       Q2 = search(s,1:4)
    end
end

这会计算 Q1Q2 矩阵,但它们都是 1x4 并且当它给出新的 Q1 时,旧的会被删除。如果条件为真,我需要添加新行并将其设为 2x4。我需要扩展我的Q1 矩阵。

简而言之,我正在尝试使用for 循环和if 语句将我的数据集分为两部分。

数据集:

我需要这样的结果:

Q1 = [30  64  1  1
      30  62  3  1
      30  65  0  1
      31  59  2  1
      31  65  4  1
      33  58 10  1
      33  60  0  1
      34  58 30  1
      34  60  1  1 
      34  61 10  1]

Q2 = [34 59 0 2
      34 66 9 2]

如何防止我的代码删除Q1Q2 之前的行并获取整个矩阵?

【问题讨论】:

  • 其实主要问题不是 if 语句问题是创建数组 (Q1,Q2)
  • 您在每次迭代中都覆盖了Q1Q2。为什么要使用循环和 if 语句?如果您必须预先分配Q1Q2,然后替换它们的行。最后删除未使用的行。你为什么不按照@Adriaan 的建议使用简单的逻辑索引?
  • 我在编辑它时遇到了问题,这就是我添加新帖子的原因。

标签: matlab for-loop if-statement matrix dataset


【解决方案1】:

您计算中的主要问题是您覆盖 Q1Q2 每次循环迭代。最佳解决方案:摆脱循环并使用逻辑索引。

您可以使用logical indexing 快速确定某列在哪里等于12

search = [
  30 64 1 1 
  30 62 3 1
  30 65 0 1
  31 59 2 1
  31 65 4 1
  33 58 10 1
  33 60 0 1
  34 59 0 2
  34 66 9 2
  34 58 30 1
  34 60 1 1 
  34 61 10 1
];
Q1 = search(search(:,4)==1,:)  % == compares each entry in the fourth column to 1

Q2 = search(search(:,4)==2,:)

Q1 =
    30    64     1     1
    30    62     3     1
    30    65     0     1
    31    59     2     1
    31    65     4     1
    33    58    10     1
    33    60     0     1
    34    58    30     1
    34    60     1     1
    34    61    10     1
Q2 =
    34    59     0     2
    34    66     9     2

警告:解决缓慢!

如果您一心想要使用循环,请确保不要覆盖您的变量。每次迭代都扩展它们(非常非常慢):

Q1=[];
Q2=[];

for ii = 1:size(search,1) % loop over all rows
   if search(ii,4)==1
       Q1 = [Q1;search(ii,:)];
   end
   if search(ii,4)==2
       Q2 = [Q2;search(ii,:)];
   end
end

MATLAB 将在Q1Q2 下方放置橙色摆动,因为就地增长数组是个坏主意。或者,您可以预先分配它们与 search 一样大,然后去掉多余的部分:

Q1 = zeros(size(search)); % Initialise to be as large as search
Q2 = zeros(size(search));

Q1kk = 1; % Intialiase counters
Q2kk = 1;

for ii = 1:size(search,1) % loop over all rows
   if search(ii,4)==1
       Q1(Q1kk,:) = search(ii,:); % store
       Q1kk = Q1kk + 1; % Increase row counter
   end
   if search(ii,4)==2
       Q2(Q2kk,:) = search(ii,:);
       Q2kk = Q2kk + 1;
   end
end

Q1 = Q1(1:Q1kk-1,:); % strip off excess rows
Q2 = Q2(1:Q2kk-1,:);

【讨论】:

  • 其实我不知道 Q2 = search(search(:,4)==2,:) 我是 Matlab 的新手,但它运行良好且非常容易理解,非常感谢。
【解决方案2】:

如果Q 是您的原始矩阵,则使用accumarray 的另一个选项:

Q = accumarray(Q(:,4),1:size(Q,1),[],@(x){Q(x,:)});

您可以使用Q{1}(对于class_id = 1)、Q{2}(对于class_id = 2)等等来访问结果...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多