首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不使用MATLAB循环的情况下找到向量中最频繁的元素?

如何在不使用MATLAB循环的情况下找到向量中最频繁的元素?
EN

Stack Overflow用户
提问于 2016-10-07 18:35:18
回答 3查看 125关注 0票数 1

对于第一个最常见的元素,我们使用mode。要找到i第四最频繁的元素,我不知道还有什么更好的方法,就是继续删除第一个最频繁的元素、第二个最频繁的元素.,直到数据集中的i-1第四最频繁的元素:

代码语言:javascript
运行
复制
for n=1:size(data,1)
   if n~=i
      data = data( data(:,1) ~= mode(data(:,1)), :);
   else
      item = data( data(:,1) == i, :);
   end
end

是否有一种更好、更快的方法来做到这一点,使用矢量化而不是循环?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-07 20:00:27

您可以利用accumarraysortunique一起为数据数组中的唯一值生成bin计数。

例如:

代码语言:javascript
运行
复制
function [val, count] = getnthmost(x, n)
% Get unique values in x (uniquevals) and their location (ic)
[uniquevals, ~, ic] = unique(x);

% Accumulate the indices and sort in descending order
[bincounts_sorted, idx] = sort(accumarray(ic, 1), 'descend');

% Get the nthmost value and its count
val = uniquevals(idx(n));
count = bincounts_sorted(n);
end

还有一个小例子:

代码语言:javascript
运行
复制
x = randi(5, 10, 1);
[val, count] = getnthmost(x, 2);

返回:

代码语言:javascript
运行
复制
x =

     2     5     1     2     2     1     3     4     3     4


val =

     1


count =

     2

注意,无论排序方向如何,sort按照它们在数组中出现的顺序来处理‘[1, 2, 3, 2]’,所以如果我们有[1, 2, 3, 2],我们的升序排序索引将是[1, 2, 4, 3],而降序排序索引将是[3, 2, 4, 1]

演练

我们在这里使用unique查找输入数组x中的所有唯一值。我们还存储可选的第三个输出,它是将x的值映射到唯一值数组中的索引。然后,我们可以使用accumarray来积累1的元素,使用从unique获得的下标。换句话说,我们得到了每个索引的计数。我们将此计数按降序排序,并存储输出索引,以便将计数映射回唯一值数组中的值。然后,我们可以使用n来选择并返回适当的值和计数。

票数 4
EN

Stack Overflow用户

发布于 2016-10-07 19:21:44

假设我们有一个数据集包含以下值:

代码语言:javascript
运行
复制
data = [5 5 4 2 5 8 8 5 8 4 ];

正如您所提到的,为了找到最频繁的项目,mode是最好的方法。但是为了找到最频繁的项目,我们研究了数据的histogram,它显示了每个元素重复的次数。在Matlab中,hist函数是用来计算直方图的。hist的第一个参数是数据,第二个参数是元素的唯一值,因此在本例中它们是2 4 5 8。

元素值

代码语言:javascript
运行
复制
unique_val = unique(data);
2 4 5 8

直方图计算

代码语言:javascript
运行
复制
[count val] = hist(data, unique_val);

要绘制直方图,可以这样使用hist

代码语言:javascript
运行
复制
hist(data, unique_val);

所以我们有这样一个数字:

代码语言:javascript
运行
复制
      _
      _  _
   _  _  _
_  _  _  _ 
2  4  5  8

视觉上我们发现5是第一最频繁的项目,8是第二最频繁的项目。

但是,要从数字上查找项目,我们可以按降序排序直方图,以获得这样的数字:

代码语言:javascript
运行
复制
_
_  _
_  _  _  
_  _  _  _
5  8  4  2

所以5是前8是第2.

在Matlab中,我们将级联计数和val作为freq

代码语言:javascript
运行
复制
freq =  [count; val].';

然后根据第一列计数对freq进行排序。(减号表示降序排序,1表示第一列):

代码语言:javascript
运行
复制
out = sortrows(freq , -1)

然后out(i,2)是第一个最频繁的项目。简而言之,所有的解释都导致了这一点:

代码语言:javascript
运行
复制
%find count of data
[count val] = hist(data(:,1),unique(data(:,1)));
freq = [count; val].';
%sort counts descendingly
out = sortrows(freq,-1);

现在,out(i,2)是最常见的元素

票数 2
EN

Stack Overflow用户

发布于 2016-10-07 21:59:39

以下是一种方法:

代码语言:javascript
运行
复制
x = [2 2 3 1 5 1 1 3 3 3 4 1 2 5 4 3 1 3 3 4]; % data
ii = 2; % find tthe second most frequent value
sx = sort(x); % sort x
ind = [true diff(sx)~=0]; % logical index of each new value in the sorted vector
counts = diff(find([ind true])); % count of each unique value
vals = sx(ind); % unique values
[~, is] = sort(counts, 'descend'); % counts in decreasing order
result = vals(is(ii)); % value with the ii-th largest count

在这个例子中,

代码语言:javascript
运行
复制
>> vals
vals =
     1     2     3     4     5
>> counts
counts =
     5     3     7     3     2
>> result
result =
     1
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39923818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档