我有一组大的(4000个值)未分类的,正常分布的点。我将这些数据点中的每一个都放入限制在BinLimit数组中的容器中。然后我将每个bin中的值数量列表。
X是原始数据的数组,N是数据点的数量。所需的箱数(TotalBins)由用户指定。
方法#1
for i=1:TotalBins
Freq(i) = length(find(X >= BinLimit(j) & X <= BinLimit(j+1)));
j = j + 1;
end
方法#2:
sort(X);
for i=1:N
if (X(i) >= BinLimit(j) && X(i) <= BinLimit(j+1))
Freq(j) = freq(j) + 1;
elseif (j < TotalBins)
Freq(j+1) = freq(j+1) + 1;
j = j + 1;
end
end
现在,我知道第一个解决方案速度较慢 - 对于总Bins(25-50)的正常值,它慢了大约8倍但是我想知道是否有比我正在做的更快,更有效的解决方案方法#2。
答案 0 :(得分:4)
使用histc。
N = HISTC(X,EDGES),对于向量X, 计算X中的值的数量 介于EDGES中的元素之间 矢量(必须包含 单调非递减值)。 N是含有的LENGTH(EDGES)载体 这些都很重要
N(k)将计算 值X(i)如果EDGES(k)&lt; = X(i)&lt; 边缘(K + 1)。最后一个垃圾箱将计数 与EDGES匹配的任何X值(结束)。 EDGES中值之外的值是 不计算在内。使用-inf和inf in EDGES包括所有非NaN值。
E.g。
BinLimit = sort(rand(50,1));
X = rand(4000,1);
Freq = histc(X,BinLimit);
%%# Generating data
X = rand(1000000,1);
BinLimit = sort(rand(50,1));
%%# OP's method
disp('Method #1');
disp('=========');
tic;
j =1;
TotalBins = numel(BinLimit)-1;
for i=1:TotalBins
Freq(i) = length(find(X >= BinLimit(j) & X <= BinLimit(j+1)));
j = j + 1;
end
toc
%%# histc
disp('histc');
disp('=====');
tic;
histc(X,BinLimit);
toc
%%# My method
disp('Alternative');
disp('===========');
tic;
TotalBins = numel(BinLimit)-1;
Freq = zeros(TotalBins,1);
for i = 1:TotalBins
Freq(i) = sum(X >= BinLimit(i) & X <= BinLimit(i+1));
end
toc
经过几次热身后:
Method #1
=========
Elapsed time is 0.803120 seconds.
histc
=====
Elapsed time is 0.030633 seconds.
Alternative
===========
Elapsed time is 0.704808 seconds.
答案 1 :(得分:2)
除了使用HISTC之外,这里还有一个矢量化的单行解决方案:
X = randn(4000,1); %# column vector
BinLimits = linspace(-4,4,10); %# row vector
Freq = sum( bsxfun(@ge, X, BinLimits(1:end-1)) & bsxfun(@le, X, BinLimits(2:end)) )
请注意,它不是 space - 因为它创建了一个大小的矩阵:
length(X) by length(BinLimits)-1
答案 2 :(得分:0)
我认为在检查X是否属于bin时可能会出错。对于落在BinLimits上的X值,您可能会获得多个容器。
X >= BinLimit(j) & X <= BinLimit(j+1)
无论如何,既然你要求一个循环解决方案,那么这个方法比你的方法2表现更好。
j=1;
i=1;
while i<=N
while i<=N && X(i)<=BinLimit(j+1)
i=i+1;
end
Freq(j) = i-1;
j = j+1;
end
Freq=diff([0 Freq]);
它需要对X进行排序,就像在代码中一样。下面是排序X数组讨论的所有方法的时间(histc对于排序X也更快,因此这是一个公平的比较):
Sort
===========
Elapsed time is 0.019205 seconds.
Method #1
=========
Elapsed time is 0.209979 seconds.
histc
=====
Elapsed time is 0.009595 seconds.
Alternative
===========
Elapsed time is 0.228400 seconds.
Method 2
===========
Elapsed time is 0.025400 seconds.
my method
===========
Elapsed time is 0.011920 seconds.
bsxfun by Amro
===========
Elapsed time is 0.179937 seconds.
如您所见,此循环结构的表现几乎与histc一样(25%更差)。
那是针对排序的X(排序时间也在上面的结果中给出)。这是未排序数组的histc结果(与上面相同的X,随机置换排列)
histc
=====
Elapsed time is 0.030367 seconds.
如您所见,对排序数组进行排序和histc的时间与在未排序数组上运行histc类似。