2013-04-03 123 views
0

我在Matlab的矩阵看起来与此类似,除了与数千行的矩阵保持了一些随机的行: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

你需要运行的行索引满足的条件,即平等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,:)]; 

更新randsample:您还可以使用find来代替原来的指标建设,议员建议,这证明是更快(和优化!)。

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. 
+0

'index5 = find(A(:,1)== 5);'我会觉得效果会更好。 – yuk 2013-04-04 02:58:21

+0

@yuk如果你得到相同的输出,为什么你会有调用find的开销,因为你可以直接索引1:n,即行索引的向量?通过以上你仅在矢量1:n上使用逻辑索引,这是你分析构建的。除非'find'正在做一些额外的性能优化,否则我认为它对于较大的矩阵将会更慢。它不需要在内存中分配新的矢量。 – gevang 2013-04-04 03:30:37

+0

@gevang我检查了你的代码速度。对于较大的矩阵来说,它并没有太慢的速度。我的代码(下面的答案)对于小矩阵(大约10000行)更快,但之后执行时间开始增加。我认为那是因为我在串联。 – 2013-04-04 03:47:09

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)执行此操作。

+0

是的,这个代码更多的则是两倍,从@gevand更快。首先'randperm'是内置函数。 'randsample'实际上称为'randperm'。其次可能是由于直接索引。我只建议不要增长'desireMat'。最好创建'mat2'并将它们连接到'desiredMat = [mat1(1:3,:); MAT2(1:3,:)];'。快一点。 – yuk 2013-04-04 15:50:20