2015-09-26 486 views
3

我知道MATLAB的datasample允许从某个​​选择k次。假设population=[1,2,3,4],我想统一采样,替换,k=5次。然后:MATLAB:随机抽样多次?

datasample(population,k) 
ans = 
    1  3  2  4  1 

现在,我想重复上述实验N=10000倍,而无需使用一个for循环。我试图做:

datasample(repmat(population,N,1),5,2) 

但输出我得到的是(只是一个简短的摘录如下):

1  3  2  1  3 
1  3  2  1  3 
1  3  2  1  3 
1  3  2  1  3 
1  3  2  1  3 
1  3  2  1  3 
1  3  2  1  3 
1  3  2  1  3 
1  3  2  1  3 

每一行(实验的结果)是一样的!但显然他们应该是不同的......就好像一些随机种子不在行之间更新。我怎样才能解决这个问题?或者我可以使用的其他方法避免for循环?谢谢!

回答

4

datasample将数据的每一列解释为您的人口的一个元素,在所有列中进行抽样。

为了解决这个问题,你可以拨打datasample N次的循环,而不是我会用randi

population(randi(numel(population),N,5)) 

假设你的人口始终是1:对,你可以简化为:

randi(p,N,5) 
+0

你和rayryeng有相同的解决方案。非常感谢,它的工作原理!你的观点更简洁一些,所以我会接受它作为答案。 –

+0

@space_voyager - 很酷。请记住,我写的代码可以推广到任何你想要的人口向量。 Daniel编码的假设是总体向量总是为'1:p',其中'p'是所需元素的数量。无论哪种方式,祝你好运! – rayryeng

+0

@rayryeng:“假设你的人口总是1:p,你可以简化为”;) – Daniel

5

你似乎混淆了datasample的工作方式。如果你阅读了函数documentation,如果你指定了一个矩阵,它将从矩阵中选择的行生成一个数据采样。因此,如果仅仅重复10000次向量,并且指定了函数的第二个参数 - 在这种情况下是指要提取多少行矩阵,即使实际行位置本身不同,实际行在所有的矩阵将是相同的,这就是为什么你得到这个“错误”。如果你想避免循环,我不会在这里使用datasample。您可以使用datasample,但是您必须循环每次通话,并明确表示这不是您想要的。

我会建议你做的是首先创建你的​​载体,以便拥有你想要的任何东西,然后生成一个随机索引矩阵,其中每个值在1到最多与​​中的元素数相同。矩阵的列数是样本数量,行数是试验次数。一旦你创建了这个矩阵,只需使用它来索引你的向量来获得所需的采样矩阵。要生成这个随机索引矩阵,randi是一个不错的选择。

像这样的事情出现在脑海:

N = 10000; %// Number of trials 
M = 5; %// Number of samples per trial 
population = 1:4; %// Population vector 

%// Generate random indices 
ind = randi(numel(population), N, M); 

%// Get the stuff 
out = population(ind); 

下面是输出的第10行:

>> out(1:10,:) 

ans = 

    4  3  1  4  2 
    4  4  1  3  4 
    3  2  2  2  3 
    1  4  2  2  2 
    1  2  3  4  2 
    2  2  3  2  1 
    4  1  3  2  4 
    1  4  1  3  1 
    1  1  2  4  4 
    1  2  4  2  1 

我觉得上面的你想要做什么。同时请记住,上面的代码概括了你想要的任何种群向量。你只需要改变矢量,它会像广告一样工作。

3

好,所以两个当前的答案都说不要使用datasample并使用randi来代替。但是,我有一个解决方案为您与datasamplearrayfun

>> population = [1 2 3 4]; 
>> k = 5; % Number of samples 
>> n = 1000; % Number of times to execute datasample(population, k) 
>> s = arrayfun(@(k) datasample(population, k), n*ones(k, 1), 'UniformOutput', false); 
>> s = cell2mat(s); 
s = 

    1  4  1  4  4 
    4  1  2  2  4 
    2  4  1  2  1 
    1  4  3  3  1 
    4  3  2  3  2 

我们需要确保使用'UniformOutput', falsearrayfun因为有一个以上的输出。由于arrayfun是一个单元阵列,所以需要调用cell2mat

+0

这是我得到上述答案之前所做的。不过,我认为兰迪解决方案更清洁。不管怎么说,还是要谢谢你。 –

+1

工作!...虽然'arrayfun'在技术上是一个循环。 – rayryeng

+0

@space_voyager是的,我只是想用'datasample'来做。 – IKavanagh