0

我在 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' 不适用于矩阵。

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

4

2 回答 2

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 的建议来替换原来的索引结构,这被证明更快(并且优化了!)。

基准测试(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.
于 2013-04-04T02:01:44.420 回答
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)。

于 2013-04-04T01:30:32.867 回答