2015-09-26 483 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