如何在两个向量中有效地创建所有价值对的热图?

发布于 2025-02-09 19:40:32 字数 1255 浏览 1 评论 0原文

MATLAB中的问题

具有与整数值相同的2个1-D数组。考虑到相同索引的值是一对,我想计算每对有多少对,然后将其存储在矩阵中以稍后将其打印为aa heatmap。

这是我要存档的一个小示例:

v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];

% Magic happens here

heatMatrix = [0, 2;
              1, 2];

结果如下:我们有:

  • 0次,v1 = 0,v2 = 0(heatmatrix [1,1])
  • 2倍v1 = 0,v2 = 1(指数2和4,heatmatrix [1,2])
  • 1次,对v1 = 1,v2 = 0(索引3,heatmatrix [2,1])
  • 2时间对v1 = 1,v2 = 1(指数1(指数1) 5,Heatmatrix [2,2])

我的代码

使用MATLAB循环做到的,该循环速度慢,尤其是对于长向量的速度慢:

% Alocating random vectors
rng(0);
maxVal = 255;
nbElem = 1e6;
v1 = randi(nbElem, 1);
v2 = randi(nbElem, 1);
heatMatrix = zeros(maxVal, maxVal);

% Creating heat matrix
tic();
for ii = 1:maxVal
  for jj = 1:maxVal
    heatMatrix(ii, jj) = sum((v1 == i) & (v2 == j));
  end
end
toc();

性能问题

,我必须在1E7元素的领域中处理长向量。我正在使用Intel(R)Core(TM)i7-6700 CPU @ 3.40GHz,并具有7.5 GB的RAM。我的表演如下:

”在此处输入图像描述

我正在寻找

一种加快执行此任务的方法。我主要是在寻找一种以更智能的方式向量或执行任务的方法(也许我不知道MATLAB功能)。

Problem

In MATLAB I have 2 1-D array of the same size with integer values. Considering that the values at a same index are a pair, I want to count how many pairs of each I have and store that in a matrix to later print it a a heatmap.

Here is a small example of what I want to archive:

v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];

% Magic happens here

heatMatrix = [0, 2;
              1, 2];

The result is as follow because we have:

  • 0 time the pair v1=0, v2=0 (heatMatrix[1, 1])
  • 2 times the pair v1=0, v2=1 (indices 2 and 4, heatMatrix[1, 2])
  • 1 time the pair v1=1, v2=0 (index 3, heatMatrix[2, 1])
  • 2 time the pair v1=1, v2=1 (indices 1 and 5, heatMatrix[2, 2])

My code

I have done that using MATLAB loops which is slower than reasonable especially for long vectors:

% Alocating random vectors
rng(0);
maxVal = 255;
nbElem = 1e6;
v1 = randi(nbElem, 1);
v2 = randi(nbElem, 1);
heatMatrix = zeros(maxVal, maxVal);

% Creating heat matrix
tic();
for ii = 1:maxVal
  for jj = 1:maxVal
    heatMatrix(ii, jj) = sum((v1 == i) & (v2 == j));
  end
end
toc();

Performance issues

I have to deal with long vectors, in the realm of 1e7 elements. I am working with an Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz and have 7.5 GB of RAM. And my performances are as follow:

enter image description here

Question

I am looking for a way to speed up the execution of this task. I'm mostly looking for a way to vector or perform the task in a smarter way (maybe there is a MATLAB function I'm not aware of).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

囚我心虐我身 2025-02-16 19:40:32

选项1:accomararay()

/code> 可以处理2D索引,因此:

v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];

hm = accumarray([v1;v2].'+1,1)

% hm = [0, 2;
%       1, 2];

只需确保您的索引以1。


选项2:sparse()

sparse() 可以处理重复索引,因此:

v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];

hm = full(sparse(v1+1,v2+1,1))

% hm = [0, 2;
%       1, 2];

这两个选项都比您的解决方案快,并且比您的解决方案快,比您的解决方案更快@Billbokeey的解决方案。但是看起来累积阶段速度更快。

Option 1: accumarray()

accumarray() can handle a 2D index, so:

v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];

hm = accumarray([v1;v2].'+1,1)

% hm = [0, 2;
%       1, 2];

Just make sure that your index start with 1.


Option 2: sparse()

sparse() can handle duplicate index, so:

v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];

hm = full(sparse(v1+1,v2+1,1))

% hm = [0, 2;
%       1, 2];

Both options are way faster than your solution and faster than the @BillBokeey's solution. But it looks like accumarray is a bit faster.

三寸金莲 2025-02-16 19:40:32

一种简单的方法是:

  • 意识到V1和V2中的值对是您的heatmatrix中的索引,并将其转换为线性索引

  • 使用 unique 获取唯一索引以及输入线性索引向量

    中的相应索引

  • accomaray

  • 使用unique_ind索引填充矩阵

% Alocating random vectors
rng(0);
maxVal = 255;
nbElem = 1e6;
v1 = randi(maxVal,nbElem,1);
v2 = randi(maxVal,nbElem,1);
heatMatrix = zeros(maxVal, maxVal);
heatMatrix2 = zeros(maxVal, maxVal);

% Creating heat matrix
tic();
for ii = 1:maxVal
  for jj = 1:maxVal
    heatMatrix(ii, jj) = sum((v1 == ii) & (v2 == jj));
  end
end
toc();

% faster
tic();
ind = sub2ind([maxVal maxVal],v1,v2);
[unique_ind,~,ix] = unique(ind);
C = accumarray(ix,1).';
heatMatrix2(unique_ind) = C;
toc();

isequal(heatmatrix,heatmatrix2)

%%%% Elapsed time is 24.850305 seconds.
%%%% Elapsed time is 0.049509 seconds.
%%%% 1

如果我怀疑,您的值实际上从0到maxval

% Alocating random vectors
rng(0);
maxVal = 255;
nbElem = 1e6;
v1 = randi(maxVal+1,nbElem,1)-1;
v2 = randi(maxVal+1,nbElem,1)-1;
heatMatrix = zeros(maxVal+1, maxVal+1);
heatMatrix2 = zeros(maxVal+1, maxVal+1);

% Creating heat matrix
tic();
for ii = 1:(maxVal+1)
  for jj = 1:(maxVal+1)
    heatMatrix(ii, jj) = sum((v1 == (ii-1)) & (v2 == (jj-1)));
  end
end
toc();

% faster
tic();
ind = sub2ind([maxVal+1 maxVal+1],v1+1,v2+1);
[unique_ind,~,ix] = unique(ind);
C = accumarray(ix,1).';
heatMatrix2(unique_ind) = C;
toc();

isequal(heatMatrix,heatMatrix2)

%%%% Elapsed time is 24.748371 seconds.
%%%% Elapsed time is 0.055760 seconds.
%%%% 1

A simple way to do this is to:

  • Realize the value pairs in v1 and v2 are the indexes in your heatMatrix and transform them to linear indexes

  • Use unique to get the unique indexes, as well as the corresponding indexes in the input linear indexes vector

  • Calculate the repetitions of each index in ix with accumarray

  • Use the unique_ind indexes to fill the matrix

%

% Alocating random vectors
rng(0);
maxVal = 255;
nbElem = 1e6;
v1 = randi(maxVal,nbElem,1);
v2 = randi(maxVal,nbElem,1);
heatMatrix = zeros(maxVal, maxVal);
heatMatrix2 = zeros(maxVal, maxVal);

% Creating heat matrix
tic();
for ii = 1:maxVal
  for jj = 1:maxVal
    heatMatrix(ii, jj) = sum((v1 == ii) & (v2 == jj));
  end
end
toc();

% faster
tic();
ind = sub2ind([maxVal maxVal],v1,v2);
[unique_ind,~,ix] = unique(ind);
C = accumarray(ix,1).';
heatMatrix2(unique_ind) = C;
toc();

isequal(heatmatrix,heatmatrix2)

%%%% Elapsed time is 24.850305 seconds.
%%%% Elapsed time is 0.049509 seconds.
%%%% 1

If, as I suspect, your values actually range from 0 to maxVal:

% Alocating random vectors
rng(0);
maxVal = 255;
nbElem = 1e6;
v1 = randi(maxVal+1,nbElem,1)-1;
v2 = randi(maxVal+1,nbElem,1)-1;
heatMatrix = zeros(maxVal+1, maxVal+1);
heatMatrix2 = zeros(maxVal+1, maxVal+1);

% Creating heat matrix
tic();
for ii = 1:(maxVal+1)
  for jj = 1:(maxVal+1)
    heatMatrix(ii, jj) = sum((v1 == (ii-1)) & (v2 == (jj-1)));
  end
end
toc();

% faster
tic();
ind = sub2ind([maxVal+1 maxVal+1],v1+1,v2+1);
[unique_ind,~,ix] = unique(ind);
C = accumarray(ix,1).';
heatMatrix2(unique_ind) = C;
toc();

isequal(heatMatrix,heatMatrix2)

%%%% Elapsed time is 24.748371 seconds.
%%%% Elapsed time is 0.055760 seconds.
%%%% 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文