基于Matlab的不同大小的多重采样

基于Matlab的不同大小的多重采样,matlab,random-sample,Matlab,Random Sample,我正在尝试实现这段代码,以便它能尽快工作 假设我有100个不同的值,你可以把它看作是pop=1:100或pop=randn(1100),以保持简单。我有一个向量n,它给出了我想要得到的样本的大小。比如说,n=[1 3 10 6 2]。我想做的是取5个不同的pop样本(实际上是length(n)),每个样本由n(I)元素组成,不需要替换。这意味着对于我的第一个示例,我希望从pop中得到1个元素,对于第二个示例,我希望得到3个,对于第三个示例,我希望得到10个,依此类推 老实说,我对采样的元素并不感

我正在尝试实现这段代码,以便它能尽快工作

假设我有100个不同的值,你可以把它看作是
pop=1:100
pop=randn(1100)
,以保持简单。我有一个向量
n
,它给出了我想要得到的样本的大小。比如说,
n=[1 3 10 6 2]
。我想做的是取5个不同的
pop
样本(实际上是
length(n)
),每个样本由
n(I)
元素组成,不需要替换。这意味着对于我的第一个示例,我希望从
pop
中得到1个元素,对于第二个示例,我希望得到3个,对于第三个示例,我希望得到10个,依此类推

老实说,我对采样的元素并不感兴趣。我想要得到的是第I个样本中存在的元素的总和。如果我用循环实现它,这将是微不足道的,但我试图避免使用它们来尽可能快地保存代码。我必须为许多不同的人群做这项工作,
length(n)
非常大

如果我必须用一个循环来完成,这将是:

pop = randn(1,100);
n = [1 3 10 6 2];
sum_sample = zeros(length(n),1);
for i = 1:length(n)
  sum_sample(i,1) = sum(randsample(pop,n(i)));
end

有办法做到这一点吗?

您可以创建一个函数句柄,用于选择随机样本并将其相加。然后,您可以使用arrayfun对n的所有值执行此函数:

pop = randn(1,100);
n = [1 3 10 6 2];
sr = @(n) sum(randsample(pop,n));
sum_sample = arrayfun(sr,n);

您可以这样做:

pop = randn(1,100);
n = [1 3 10 6 2];
sampled_data_index = randi(length(pop),1,sum(n));
sampled_data = pop(sampled_data_index);
randi
函数随机选择指定范围内适合索引的整数值。获得索引后,您可以立即使用这些索引从
pop
数据库中对数据进行采样

如果您想拥有唯一的索引,可以将
randi
函数替换为
randperm

sampled_data_index = randperm(length(pop),sum(n));
最后:

可以使用以下代码将所有采样值作为单元变量:

pop = randn(1,100);
n = [1 3 10 6 2];
fun = @(m) pop(randperm(length(pop),m));
C = arrayfun(fun,n,'UniformOutput',0)
还具有采样数据的总和:

funs = @(m) sum(pop(randperm(length(pop),m)));
sumC = arrayfun(funs,n)

找出最快的方法是比较不同的方法

事实上,在这种情况下,循环似乎非常快

pop = randn(1,100);
n = [1 3 10 6 2];

tic
sr = @(n) sum(randsample(pop,n));
sum_sample = arrayfun(sr,n);
toc %% Returns about 0.004

clear su
tic
for t=numel(n):-1:1
    su(t)=sum(randsample(pop,n(t)));
end
toc %% Returns about 0.003

不要做假设。用一个真实的例子、真实的值和一个你想做的最少的代码例子来更新你的文章。因此,以
pop=randn(1:100)
n=[1 3 10 6 2]
为例。我刚刚编辑了我的问题,介绍了我将如何在循环中执行此操作。请记住,矢量化或使用arrayfun之类的工具通常会产生开销。因此,向量化这样一个微小的计算实际上可能会减慢速度。我也在考虑你的第一种方法,但如果你想在每个样本中都有唯一性,但不一定要在所有样本的并集中都有唯一性,那么它会变得有点混乱(我相信这就是asker循环目前的工作方式)。如果这不是一个问题,这应该是相当快的。如果您使用最后2行代码,对于每个函数执行,样本将是唯一的。如果我没有弄错你说的话。要做性能分析,我会建议更大的维度。我用
pop=randn(1100000)
n=randi(100000,110000)
尝试了这两种情况,得到了几乎相同的运行时间。由此,我假设MATLAB通过在for循环中遍历数组,在内部实现了
arrayfun