使用accumarray按索引汇总行 [英] Summing rows by index using accumarray

查看:107
本文介绍了使用accumarray按索引汇总行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以在不使用for循环的情况下对多个索引中的行或列求和吗?

Can I sum rows or columns over several indices without using a for loop?

我有一个n×n矩阵M,它表示词汇术语的同时出现,其中n是词汇的长度.

I have an n by n matrix, M, that represents the co-occurrence of vocabulary terms where n is the length of the vocabulary.

我还有一个n×n逻辑掩码L,它表示成对的词汇,其中成对形式(单数,复数).例如,用伪代码L('octopus', 'octopuses') = True

I also have a n by n logical mask, L, which represents the pairs of vocabulary where the pair has the form (singular, plural). For example, in pseudo-code, L('octopus', 'octopuses') = True

我想在M中将包含复数的任何对的条目添加到包含相应单数的对的条目中.例如,用伪代码M_sum('octopus', 'swim') = M('octopus', 'swim') + M('octopuses', 'swim');

I want to add the entries in M for any pair which contains a plural to entry for the pair that contains the corresponding singular. For example, in pseudo-code, M_sum('octopus', 'swim') = M('octopus', 'swim') + M('octopuses', 'swim');

为说明到目前为止我已经尝试过的内容,让我们使用以下玩具数据.

To illustrate what I've tried so far, let's use the following toy data.

vocabulary = {'octopus', 'octopuses', 'swim'};
% The co-occurrence matrix is symmetric
M = [0, 9, 3; 
     9, 0, 1;  
     3, 1, 0;];
% This example has only one plural singular pair
L = [0, 1, 0; 
     0, 0, 0; 
     0, 0, 0;];  

要查找单数到复数的对应关系,我可以使用find

To find the singular to plural correspondence, I can use find

[singular, plural] = find(L == 1);

如果每个单数只有一个复数,那么对行或列求和很简单

If there is only one plural for each singular, summing the rows or columns is simple

M_sum = M;
M_sum(singular, :) = M_sum(singular, :) + M(plural, :);
M_sum(:, singular) = M_sum(:, singular) + M(:, plural);
% Remove diagonal entries
M_sum(eye(size(M))==1) = 0; 

但是,如果有多个对应于一个单数的复数,则无法使用此方法.

However, if there are several plurals that correspond to one singular, this approach cannot be used.

例如

vocabulary = {'octopus', 'octopuses', 'octopi', 'swim'};
M = [0, 9, 5, 3; 
     9, 0, 7, 1; 
     5, 7, 0, 11; 
     3, 1, 11, 0;];
L = [0, 1, 1, 0; 
     0, 0, 0, 0; 
     0, 0, 0, 0; 
     0, 0, 0, 0;];  

正确答案应该是

M_sum = [0, 16, 12, 15;
         16, 0, 7, 1;
         12, 7, 0, 11;
         15, 1, 11, 0;];

但是使用上述方法会返回

But using the above method returns

M_sum = [0, 16, 5, 14;
         16, 0, 7, 1;
         5, 7, 0, 11;
         14, 1, 11, 0;];

基本上,M_sum(singular, :) = M_sum(singular, :) + M(plural, :);仅使用最后一个plural索引.

Basically, M_sum(singular, :) = M_sum(singular, :) + M(plural, :); only uses the last plural index.

我认为我需要在此处使用 accumarray ,但是我在编写正确的语句时遇到了一些麻烦,因为我有两个索引pluralsingular.如果accumarray不是正确的方法,则也欢迎使用其他解决方案.

I think that I need to use accumarray here, but I'm having some trouble formulating the correct statement because I have two indices, plural and singular. If accumarray is not the correct approach, other solutions are also welcome.

推荐答案

尝试一下:

M_sum = (L + eye(size(L,1)))*M;
M_sum = triu(M_sum, 1);
M_sum = M_sum + M_sum.';

之所以可行,是因为您已经有了矩阵L,因此可以使用矩阵乘法来选择和求和M的行.

This works because you already have matrix L, so matrix multiplication can be used to select and sum the rows of M.

在这里使用accumarray有两个缺点:

Using accumarray here would have two drawbacks:

  • 您需要应用findL转换为索引,以用作accumarray的第一个输入.再走一步.
  • accumarray只能求和个数字,不能求和行向量(第二个输入只能是列向量,不能是矩阵).因此,您需要在M的每一列中调用一次accumarray.
  • You'd need to apply find to convert L into indices to be used as first input to accumarray. So one more step.
  • accumarray can only sum numbers, not row vectors (its second input can only be a column vector, not a matrix). So you'd need to call accumarray once per column of M.

这篇关于使用accumarray按索引汇总行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆