MATLAB:在矩阵中保留一些满足特定条件的随机行

时间:2013-04-03 23:53:03

标签: matlab matrix random-sample

我在Matlab中有一个类似于此的矩阵,除了有数千行:

A =

     5     6     7     8
     6     1     2     3
     5     1     4     8
     5     2     3     7
     5     8     7     2
     6     1     3     8
     5     2     1     6
     6     3     2     1

我想得到一个矩阵,它在第一列中有三个随机行,其中一个'5',在第一列中有一个'6'的三个随机行。所以在这种情况下,输出矩阵看起来像这样:

A =

     5     6     7     8
     6     1     2     3
     5     2     3     7
     6     1     3     8
     5     2     1     6
     6     3     2     1

行必须是随机的,而不仅仅是原始矩阵中的前三个或后三个。 我不确定如何开始这个,所以任何帮助将不胜感激。

编辑:这是迄今为止我迄今为止最成功的尝试。我发现第一列中的所有行都带有'5':

BLocation = find(A(:,1) == 5);
B = A(BLocation,:);

然后我试图像这样使用'randsample'从B中找到三个随机行:

C = randsample(B,3);

但'randsample'不适用于矩阵。

我也认为这可以更高效地完成。

2 个答案:

答案 0 :(得分:4)

您需要在满足条件的行索引上运行randsample,即等于5或6。

n = size(A,1);

% construct the linear indices for rows with 5 and 6 
indexA = 1:n; 
index5 = indexA(A(:,1)==5);
index6 = indexA(A(:,1)==6);

% sample three (randomly) from each 
nSamples = 3;
r5 = randsample(index5, nSamples);
r6 = randsample(index6, nSamples);

% new matrix from concatenation 
B = [A(r5,:); A(r6,:)];

更新:您也可以使用find来替换原来的索引结构,正如yuk建议的那样,证明速度更快(并进行了优化!)。

Bechmark (MATLAB R2012a)

A = randi(10, 1e8, 2); % 10^8 rows random matrix of 1-10

tic;
n = size(A,1);
indexA = 1:n;
index5_1 = indexA(A(:,1)==5);
toc

tic;
index5_2 = find(A(:,1)==5);
toc

Elapsed time is 1.234857 seconds.
Elapsed time is 0.679076 seconds.

答案 1 :(得分:2)

您可以按照以下方式执行此操作:

desiredMat=[];
mat1=A(A(:,1)==5,:);
mat1=mat1(randperm(size(mat1,1)),:);
desiredMat=[desiredMat;mat1(1:3,:)];
mat1=A(A(:,1)==6,:);
mat1=mat1(randperm(size(mat1,1)),:);
desiredMat=[desiredMat;mat1(1:3,:)];

上面的代码使用逻辑索引。您也可以使用find函数执行此操作(逻辑索引始终快于find)。