0

对于当前的项目,我必须将准连续值离散化到由一些预定义的分箱分辨率定义的箱中。为此,我编写了一个函数,我希望它非常高效,因为它能够使用 bsxfun 处理标量输入和向量输入。然而,经过一些分析后,我发现我这个更大的项目的几乎所有处理时间都在这个函数中产生,并且在函数中,主要是 bsxfun 部分需要时间,其次是 min-query。长话短说,我正在寻找有关如何在 MATLAB 中更快地解决此任务的建议。旁注:我通常传递带有大约 50k 个元素的向量。

这是代码:

function sampleNo = value2sample(value,bins)

%Make sure both vectors have orientations fitting bsxfun
value = value(:);
bins = bins(:)';

%Recover bin resolution (avoids passing another parameter)
delta = median(diff(bins));

%Calculate distance matrix between all combinations
dist = abs(bsxfun(@minus,value,bins));

%What we really want to know is the minimum distance per row
[minval,ind] = min(dist,[],2);

%Make sure we don't accidentally further process NaNs as 1st bin
ind(isnan(minval))=NaN;

sampleNo = ind;
sampleNo(minval>delta) = NaN;

end
4

2 回答 2

1

您的函数很慢的原因是因为您正在计算 和 的每个元素之间的距离values并将bins它们全部存储在一个数组中 - 如果有N个值和M个bin,那么您将需要NM个元素来存储所有距离,这是可能是一个非常大的数字(例如,如果每个输入有 50,000 个元素,那么输出数组中需要 25 亿个元素)。

此外,由于您的箱已排序(您没有说明这一点,但看起来您在代码中假设它)您不需要计算从每个值到每个箱的距离。你可以更聪明,

function ind = value2sample(value, bins)

    % Find median bin distance
    delta = median(diff(bins));

    % Bucket into 'nearest' bin by using midpoints
    bins = bins(:);
    mids = [-Inf; 0.5 * (bins(1:end-1) + bins(2:end))];

    [~, ind] = histc(value, mids);

    % Ensure that NaN values and points that aren't near any bin are returned as NaN
    ind(isnan(value)) = NaN;
    ind(abs(value - bins(ind)) > delta) = NaN;

end

在我的测试中,values = randn(10000, 1)运行bins = -50:50原始函数大约需要 4.5 毫秒,运行上面的代码需要 485 微秒,所以你得到了大约 10 倍的加速(并且随着你增加输入的大小,加速会更大)。

于 2016-08-16T14:39:58.057 回答
0

感谢@Chris Taylor,我能够非常有效地解决问题。代码现在的运行速度比以前快了近 400 倍。我必须对他的版本进行的唯一更改反映在下面的代码中。主要问题是histcdiscretize.

function ind = value2sample(value, bins)

% Make sure the vectors are standing
value = value(:);
bins = bins(:);

% Bucket into 'nearest' bin by using midpoints
mids = [eps; 0.5 * (bins(1:end-1) + bins(2:end))];

ind = discretize(value, mids);

唯一的问题是,在这个实现中,你的 bin 必须是非负数。除此之外,这段代码完全符合我的要求,包括与a是或超出范围时ind具有相同大小value并包含的事实。NaNsvalueNaNbins

于 2016-08-16T19:10:27.580 回答