在 Matlab 中累积数组

Accumulate Array in Matlab

我截取了以下代码,它可以工作但速度非常慢:

bps = [5; 10; 15; 20]
src = ['10.0.0.1'; '10.0.0.2'; '10.0.0.1'; '10.0.0.2']

uniqueSrc = unique(src);

sumBps = [];
for i=1:length(uniqueSrc)
    indy=find(ismember(src,uniqueSrc(i)));
    sumBps = [sumBps; sum(bps(indy))];
end

uniqueSrc = ['10.0.0.1'; '10.0.0.2']
sumBps = [20; 30]

src 是一个包含 IP 地址的元胞数组,而一个 IP 可以出现多次。它是从带有 textscan 和 %s 的文件中读取的。 bps 包含整数。

我需要对 src 中属于同一 IP 地址的所有整数求和,单位为 bps。 匹配是根据索引。所以src(1)就是bps(1)的IP等等。

结果应该是 IP 与相应 bps 值之和的匹配。所以 uniqueSrc(1) 是具有 sumBps(1) 的 IP,它是属于特定 IP 的所有 bps 值的总和。

虽然我的代码确实有效,但它看起来非常低效,我想知道解决这个问题的著名 matlab one-liner 是什么。

提前致谢!

编辑:添加了示例输入和输出。

accumarray的经典用法:

%// Your inputs
bps = [5; 10; 15; 20];
src = ['10.0.0.1'; '10.0.0.2'; '10.0.0.1'; '10.0.0.2'];

%// Relevant code
[uniqueSrc,~,id] = unique(cellstr(src));
sumBps = accumarray(id, bps);

上面的代码可能需要一些解释。 accumarray 是一个根据 ID 将数据分箱或分组的函数。因此,除了为每个 IP 地址分配唯一 ID 外,我所做的是将 src 转换为具有 cellstr, then used unique 的元胞数组,以获取所有唯一 IP 地址的列表。唯一的 IP 地址存储在 uniqueSrc 中,这是 unique 的第一个输出,src 中的每个 IP 地址都分配有一个唯一的 ID,存储在 id 中。很多人都没有想到的一个复杂之处是 unique 不仅在数组中找到唯一的条目,而且还 return 对这些值进行 排序 。根据这个排序结果,分配给 src 中每个元素的 ID 将遵循此排序约定。因为你要return那些IP地址的顺序(看起来是这样),那这部分我们就不用考虑了。此外,我需要将您的 IP 地址转换为元胞数组才能正常工作。

确定这些后,我们使用 accumarray,其中第一个元素是每个 IP 地址的 ID,第二个元素是每个 IP 地址映射到的值。默认情况下,accumarray 将共享相同 ID 的那些值分箱,然后 将它们相加 。这几乎描述了你到底想做什么。

我为你想要的变量得到的输出是:

>> uniqueSrc

uniqueSrc = 

    '10.0.0.1'
    '10.0.0.2'

>> sumBps

sumBps =

    20
    30

添加我的答案,因为我想展示如何连接 IP 地址和 bps 求和,另外,如果您将选项 rowsunique 结合使用,则无需转换为单元格:

bps = [5; 10; 15; 20]
src = ['10.0.0.1'; '10.0.0.2'; '10.0.0.1'; '10.0.0.2'];

[strng ii jj]= unique(src,'rows');


strcat( {strng},{char(32)*ones(size(strng,1),1)},{num2str(accumarray(jj,bps))})