我在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'不适用于矩阵。
我也认为这可以更高效地完成。
答案 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
)。