MATLAB:多次从人口中随机抽样?
MATLAB: sample from population randomly many times?
我知道 MATLAB 的 datasample
允许从某个 population
select k
次。假设 population=[1,2,3,4]
并且我想从中统一采样 k=5
次并进行替换。那么:
datasample(population,k)
ans =
1 3 2 4 1
现在,我想在不使用 for 循环的情况下重复上述实验 N=10000
次。我尝试这样做:
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 循环?谢谢!
datasample
将数据的每一列解释为总体的一个元素,在所有列中抽样。
要解决此问题,您可以循环调用 datasample
N 次,而我会使用 randi
population(randi(numel(population),N,5))
假设您的人口总是 1:p,您可以简化为:
randi(p,N,5)
您似乎混淆了 datasample
的工作方式。如果您阅读函数上的 documentation,如果您指定了一个矩阵,它将从矩阵中选择的行生成数据采样。因此,如果您简单地重复 population
向量 10000 次,并且当您指定函数的第二个参数时 - 在本例中是要提取矩阵的行数,即使实际行位置本身不同,所有矩阵的实际行将是相同的,这就是为什么你得到 "error".
因此,如果您打算避免循环,我不会在这里使用 datasample
。您可以使用 datasample
,但您必须遍历每个调用并且您明确表示这不是您想要的。
我建议你做的是首先创建你的 population
向量以包含你想要的任何内容,然后生成一个随机索引矩阵,其中每个值介于 1 到尽可能多的元素之间population
。该矩阵的列数是样本数,行数是试验数。创建此矩阵后,只需使用它来索引您的向量即可获得所需的采样矩阵。要生成这个随机索引矩阵,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
我认为上面的内容可以满足您的需求。还要记住,上面的代码可以推广到你想要的任何人口向量。您只需更改矢量,它就会像宣传的那样工作。
好的,所以当前的两个答案都说不要使用 datasample
而是使用 randi
。但是,我为您提供了 datasample
和 arrayfun
.
的解决方案
>> 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', false
与 arrayfun
一起使用,因为有多个输出。 cell2mat
调用是必需的,因为 arrayfun
的结果是元胞数组。
我知道 MATLAB 的 datasample
允许从某个 population
select k
次。假设 population=[1,2,3,4]
并且我想从中统一采样 k=5
次并进行替换。那么:
datasample(population,k)
ans =
1 3 2 4 1
现在,我想在不使用 for 循环的情况下重复上述实验 N=10000
次。我尝试这样做:
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 循环?谢谢!
datasample
将数据的每一列解释为总体的一个元素,在所有列中抽样。
要解决此问题,您可以循环调用 datasample
N 次,而我会使用 randi
population(randi(numel(population),N,5))
假设您的人口总是 1:p,您可以简化为:
randi(p,N,5)
您似乎混淆了 datasample
的工作方式。如果您阅读函数上的 documentation,如果您指定了一个矩阵,它将从矩阵中选择的行生成数据采样。因此,如果您简单地重复 population
向量 10000 次,并且当您指定函数的第二个参数时 - 在本例中是要提取矩阵的行数,即使实际行位置本身不同,所有矩阵的实际行将是相同的,这就是为什么你得到 "error".
因此,如果您打算避免循环,我不会在这里使用 datasample
。您可以使用 datasample
,但您必须遍历每个调用并且您明确表示这不是您想要的。
我建议你做的是首先创建你的 population
向量以包含你想要的任何内容,然后生成一个随机索引矩阵,其中每个值介于 1 到尽可能多的元素之间population
。该矩阵的列数是样本数,行数是试验数。创建此矩阵后,只需使用它来索引您的向量即可获得所需的采样矩阵。要生成这个随机索引矩阵,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
我认为上面的内容可以满足您的需求。还要记住,上面的代码可以推广到你想要的任何人口向量。您只需更改矢量,它就会像宣传的那样工作。
好的,所以当前的两个答案都说不要使用 datasample
而是使用 randi
。但是,我为您提供了 datasample
和 arrayfun
.
>> 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', false
与 arrayfun
一起使用,因为有多个输出。 cell2mat
调用是必需的,因为 arrayfun
的结果是元胞数组。