2

我有一个矢量图a=[1 2 3 1 4 2 5]'

我正在尝试创建一个新向量,该向量将为每一行提供 a 中元素的出现次数。例如,对于这个矩阵,结果将是[1 1 1 2 1 2 1]':第四个元素是 2,因为这是第一次重复 1。

我能看到实现这一点的唯一方法是创建一个零向量,其行数将是唯一元素的数量(这里:c = [0 0 0 0 0]因为我有 5 个元素)。我还创建了一个与 a 长度相同的零向量 d。然后,通过向量 a,将我们读取的元素 c 的行加一,并将 c 的相应数量加到 d 的当前行。

任何人都可以考虑更好的事情吗?

4

5 回答 5

9

这是一个很好的方法

C=sum(triu(bsxfun(@eq,a,a.')))

我的第一个建议是这个,不是很好的for循环

for i=1:length(a)
    F(i)=sum(a(1:i)==a(i));
end
于 2013-10-30T23:24:11.950 回答
4

这就是你想要的,没有循环:

m = max(a);
aux = cumsum([ ones(1,m); bsxfun(@eq, a(:), 1:m) ]);
aux = (aux-1).*diff([ ones(1,m); aux ]);
result = sum(aux(2:end,:).');
于 2013-10-30T23:26:53.920 回答
4

我的第一个想法:

M = cumsum(bsxfun(@eq,a,1:numel(a)));
v = M(sub2ind(size(M),1:numel(a),a'))
于 2013-10-30T23:33:06.227 回答
4

在完全不同的层面上,您可以查看tabulate以获取有关值频率的信息。例如:

tabulate([1 2 4 4 3 4])

  Value  Count  Percent
  1      1      16.67%
  2      1      16.67%
  3      1      16.67%
  4      3      50.00%
于 2013-10-30T23:34:34.543 回答
0

请注意,David、chappjc 和 Luis Mendo 提出的解决方案很漂亮,但如果向量很大,则无法使用。在这种情况下,一些天真的方法是:

% Big vector
a = randi(1e4, [1e5, 1]);
a1 = a;
a2 = a;

% Super-naive solution
tic
x = sort(a);
x = x([find(diff(x)); end]);
for hh = 1:size(x, 1)
  inds = (a == x(hh));
  a1(inds) = 1:sum(inds);
end
toc

% Other naive solution
tic
x = sort(a);
y(:, 1) = x([find(diff(x)); end]);
y(:, 2) = histc(x, y(:, 1));
for hh = 1:size(y, 1)
  a2(a == y(hh, 1)) = 1:y(hh, 2);
end
toc

% The two solutions are of course equivalent:
all(a1(:) == a2(:))

实际上,现在的问题是:我们能避免最后一个循环吗?也许使用arrayfun?

于 2013-10-31T05:51:28.063 回答