Matlab矩阵与向量索引排序

Matlab矩阵与向量索引排序,matlab,sorting,matrix,Matlab,Sorting,Matrix,我有一个矩阵,它的行代表音符。[A,A,B,C,C,D,D,E,F,F,G,G] 所以指数1代表A,2代表A,依此类推。在矩阵中,该索引中的元素越大,其出现在音频中的可能性就越大 我想计算在可能的12个索引之间出现频率最高的3个索引 我就是这样推理出来的。首先,我使用[B,I]=sort()对每一列进行排序。。 B现在包含排序列 我现在包含以升序方式排序的索引 因此,I[10]、I[11]和I[12]现在包含该列中最大的3个索引 现在我创建了一个名为notes的新向量。如果一个特定的注释在排序时

我有一个矩阵,它的行代表音符。[A,A,B,C,C,D,D,E,F,F,G,G] 所以指数1代表A,2代表A,依此类推。在矩阵中,该索引中的元素越大,其出现在音频中的可能性就越大

我想计算在可能的12个索引之间出现频率最高的3个索引

我就是这样推理出来的。首先,我使用[B,I]=sort()对每一列进行排序。。 B现在包含排序列 我现在包含以升序方式排序的索引

因此,I[10]、I[11]和I[12]现在包含该列中最大的3个索引

现在我创建了一个名为notes的新向量。如果一个特定的注释在排序时发现自己在I的最大3个索引中,那么相应的注释应该递增

我正在尝试前3列,它们是:

0.0690   0.0530   0.0656
0.2453   0.2277   0.2306
0.0647   0.0315   0.0494
1.2037   1.1612   1.1613
0.0772   0.0346   0.0367
0.1628   0.1429   0.1648
0.0572   0.0370   0.0493
0.4119   0.3577   0.3635
0.0392   0.0430   0.0466
0.1182   0.0921   0.0935
0.7473   0.6680   0.7088
0.0794   0.0527   0.0566
因此在B中,对于我应该得到的第一个循环迭代

 0.0392
 0.0572
 0.0674
 0.0690
 0.0772
 0.0794
 0.1182
 0.1628
 0.2453
 0.4119
 0.7473
 1.2037
我得到了(所以到现在为止一切都很好)。I(包含已排序的索引)也被正确返回,其中3个最大的索引为8、11、4(即包含最大元素的原始索引,其中8、11、4按升序排列)

问题在if条件内。在第一次迭代中,在if条件之后,“notes”列向量应该在第8位、第11位、第4位ie递增

0 
0 
0 
1 
0 
0 
0 
1 
0 
0 
1 
0 
但是,在if条件之后,只有向量中的第四位递增。事实上,在第一次迭代之后,当显示“notes”向量时,我得到

 0
 0
 0
 1
 0
 0
 0
 0
 0
 0
 0
 0
这是代码:

for col = 1:3        
    [B,I] = sort(C(:,col), 'ascend'); %B is the sorted column. I is the sorted indexes
    fprintf('Col No:');
    disp(col);
    fprintf('Sorted Column: ');
    disp(B);
    fprintf('Sorted Indexes: ');
    disp(I);

    if (I(10) == 1 || I(11) == 1 || I(12) == 1)
        notes(1,:) = notes(1,:) + 1;
    elseif (I(10) == 2 || I(11) == 2 || I(12) == 2)
        notes(2,:) = notes(2,:) + 1;
    elseif (I(10) == 3 || I(11) == 3 || I(12) == 3)
        notes(3,:) = notes(3,:) + 1;
    elseif (I(10) == 4 || I(11) == 4 || I(12) == 4)
        notes(4,:) = notes(4,:) + 1;
    elseif (I(10) == 5 || I(11) == 5 || I(12) == 5)
        notes(5,:) = notes(5,:) + 1;
    elseif (I(10) == 6 || I(11) == 6 || I(12) == 6)
        notes(6,:) = notes(6,:) + 1;
    elseif (I(10) == 7 || I(11) == 7 || I(12) == 7)
        notes(7,:) = notes(7,:) + 1;
    elseif (I(10) == 8 || I(11) == 8 || I(12) == 8)
        notes(8,:) = notes(8,:) + 1;
    elseif (I(10) == 9 || I(11) == 9 || I(12) == 9)
        notes(9,:) = notes(9,:) + 1;
    elseif (I(10) == 10 || I(11) == 10 || I(12) == 10)
        notes(10,:) = notes(10,:) + 1;
    elseif (I(10) == 11 || I(11) == 11 || I(12) == 11)
        notes(11,:) = notes(11,:) + 1;
    elseif (I(10) == 12 || I(11) == 12 || I(12) == 12)
        notes(12,:) = notes(12,:) + 1;

    end

    disp(notes);
我做错了什么?代码可能是错误的(或者可能更好)。我一点也不擅长Matlab。这是第一次使用它

非常感谢您的想法、意见和更正


提前感谢您抽出时间

您似乎想得太多了。您可以做的是使用排序并单独将其应用于每一列。
sort
函数使用第二个参数,告诉您要应用排序的维度。由于要对列进行排序,需要将第二个参数设置为1,这意味着您要对每列的行进行排序

因此,定义“注释”矩阵
C

C = [0.0690   0.0530   0.0656
0.2453   0.2277   0.2306
0.0647   0.0315   0.0494
1.2037   1.1612   1.1613
0.0772   0.0346   0.0367
0.1628   0.1429   0.1648
0.0572   0.0370   0.0493
0.4119   0.3577   0.3635
0.0392   0.0430   0.0466
0.1182   0.0921   0.0935
0.7473   0.6680   0.7088
0.0794   0.0527   0.0566];
您可以简单地执行以下操作:

[~,I] = sort(C, 1, 'descend')
'descent
'标志按降序对值进行排序。因此,
I
将是一个矩阵,其中每列告诉您每列中每个排序值的位置。因此,您只需获得
I
的前三行

同样,如果我们显示
I
的前三行,我们得到:

>> disp(I(1:3,:))

 4     4     4
11    11    11
 8     8     8
这是有道理的,对于每一列,我们分别在位置4、11和8处发现了最高值

现在,如果你想统计你在上面的矩阵中看到的位置,你可以简单地使用或

因此:

ind = I(1:3,:); %// Get the first three rows of the sorted indices
notes = histc(ind(:), 1:12); %// or
%notes = accumarray(ind(:), 1, [12 1]);
因此,对于
注释
我们得到:

notes =

     0
     0
     0
     3
     0
     0
     0
     3
     0
     0
     3
     0
因此,我们看到每列的索引4、8和11,因此我们应该每次将这些位置增加1
histc
计算发生事件的频率,因此我们可以自然地使用它,并计算我们看到4、8和11的次数,或者我们看到的前三行
I
的次数
accumarray
做同样的事情,但是
accumarray
是一个更通用的功能,它不仅仅是将同一个箱子中的东西相加
histc
是处理您的案例的更好方法,尤其是因为箱子的数量是恒定的


作为对这篇文章的编辑,您在下面的评论中说您希望能够将此应用于18个列段。最好的办法可能是在某种循环中这样做。首先计算出我们有18列的多少段,然后将其放入循环中多次,并更新我们的结果。在循环中的每次迭代中,我们需要拉出矩阵中正确的18列,并不断获取18个块,直到到达数组的末尾

我们将结果放在另一个矩阵中,其中每列是每18列段中三个最常出现的注释的结果

大概是这样的:

numColumns = size(C, 2); %// Get total number of columns for matrix
numSegments = ceil(numColumns / 18); %// Get total number of segments

finalMatrix = zeros(12, numSegments);
for idx = 1 : numSegments

    %// Make sure that when we get 18 chunks, we don't out of bounds
    if 18*idx > numColumns
        seg = C(:,(idx-1)*18 + 1 : end);
    else
        seg = C(:,(idx-1)*18 + 1 : 18*idx);
    end

    [~,I] = sort(seg, 1, 'descend');
    ind = I(1:3,:); %// Get the first three rows of the sorted indices
    notes = histc(ind(:), 1:12);

    %// Your code
    [~,y] = sort(notes, 'descend'); 
    finalvec = zeros(12,1);
    finalvec(y(1)) = 1; finalvec(y(2)) = 1; finalvec(y(3)) = 1;

    %// Place in final matrix
    finalMatrix(:, idx) = finalvec;
end

finalMatrix
将每个18段的结果存储到一列中,每列都是您在评论中所写的逻辑。

哇,谢谢!解释得很好。现在,为了构建一个包含3个最高频率音符的向量,我做了如下操作:finalvec=零(12,1);[x,y]=排序(注释“下降”);finalvec(y(1))=1;finalvec(y(2))=1;finalvec(y(3))=1;disp(finalvec);这足够了吗?是的,我觉得很好!顺便说一下,如果我有帮助的话,请考虑接受我的回答。祝你好运@JurgenCuschieri-谢谢!最简单的方法是在循环中执行此操作,并将矩阵分解为12行的18列段。此上下文中的
~
表示要放弃该输出变量。因为我没有使用它,所以分配一个变量来存储这个结果是没有意义的,所以
~
实际上会丢弃这个结果。@JurgenCuschieri-我会更新我的答案。