【问题标题】:Auto-fill matrix without row-repetitions无行重复的自动填充矩阵
【发布时间】:2017-06-04 19:15:20
【问题描述】:

我有一系列数字:

test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5]

我想随机填充到一个 3x5 矩阵中,而同一行中没有相同的数字。

如何在 matlab 中做到这一点?可能我可以随机化测试向量并将其填充到 5x3 矩阵中,但如果没有在同一行中获得相同的数字,我不知道该怎么做。

【问题讨论】:

    标签: matlab matrix random


    【解决方案1】:

    如果您想用test 中的所有值填充一个 3×5 矩阵,并确保每一行没有重复值,您可以非常简洁地使用 toeplitz 首先生成一个索引矩阵,然后用randperm随机排列维度:

    index = toeplitz(1:3, [3 5:-1:2]);
    index = index(randperm(3), randperm(5));
    

    还有一个样本index

    index =
    
         1     5     4     2     3
         4     3     2     5     1
         5     4     3     1     2
    

    如果您在 test 中的值是数字 1 到 5,那么您应该只需要这样做。如果test 可以是具有5 个不同数字的任何向量,每个数字三个,那么您可以获得test 向量的unique 值并使用index 对其进行索引。该解决方案将推广到任何test 向量:

    test = [3 3 3 7 7 7 5 5 5 9 9 9 4 4 4];    % Sample data
    uniqueValues = unique(test);               % Get the unique values [3 4 5 7 9]
    M = uniqueValues(index);                   % Use index as generated above
    

    结果将保证是 test 中内容的重新排序版本:

    M =
    
         3     9     7     4     5
         7     5     4     9     3
         9     7     5     3     4
    

    【讨论】:

    • 太好了,非常感谢。然而我犯了一个小错误。我希望最终矩阵是 3x5 而不是我一开始写的 5x3。对不起这个错误。你能帮我解决这个小变化吗?
    • 太棒了,谢谢 gnovice。我有最后一个问题要问你,希望你能帮助我。说 test = [1 1 1 2 2 2 3 3 3] 我想将它填充到没有行 repetionen 的 3x5 矩阵中,并将多余的单元格留空(或 =)这是如何完成的?
    • @J.Birch:我不清楚您的要求。如果您在test 中只有 9 个值,则无法确保在每行 5 中没有重复值,如您的问题所要求的那样。您只是希望每一行都与其他行不同吗?
    • 所以这就是我要找的:我在 1D“测试”向量中有数字序列,例如我想要的 test = [1 1 1 2 2 2 3 3 3]随机填充到 3x5 矩阵中,即使我在测试向量中只有 9 个数字。我想填充 3x5 矩阵,所以我没有在同一行中重复的任何值(0 或 nan 除外)并用 0 或 nan 填充所有空格。我有道理吗?
    • 嗨,新手。我非常感谢您在上述答案中的解释,很抱歉我在解释问题时犯了错误。我提出了一个新问题 (stackoverflow.com/questions/44371149/…),希望您有时间再次帮助我。提前非常感谢
    【解决方案2】:

    你可以取testunique矩阵,从中挑选任意三个元素,填入所需的5X3矩阵。

    test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5] ;
    test_unique = unique(test) ;
    A = zeros(5,3) ;
    for i = 1:size(A,1)
        A(i,:) = randsample(test_unique,3) ;
    end
    

    randsample需要一个统计工具箱,如果没有,可以使用randperm,如下图。

    test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5] ;
    test_unique = unique(test) ;
    
    A = zeros(5,3) ;
    for i = 1:size(A,1)
        A(i,:) = test_unique(randperm(length(test_unique),3)) ;
    end
    

    如果你想要 3X5 矩阵:

    test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5] ;
    test_unique = unique(test) ;
    A = zeros(3,5) ;
    for i = 1:size(A,1)
        A(i,:) = randsample(test_unique,5) ;
    end
    

    【讨论】:

    • 太好了,非常感谢。然而我犯了一个小错误。我希望最终矩阵是 3x5 而不是我一开始写的 5x3。对不起这个错误。你能帮我解决这个小变化吗?
    • 代码已编辑......这将是一个小改动......你本可以轻松完成。
    【解决方案3】:

    这是一种蛮力的做法

    % data
    test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5];
    
    % randomly permute the indices
    indices = randperm(numel(test));
    
    % create a random matrix
    matrix = reshape(test(indices), 5, 3);
    
    % while number of unique elements in any of the rows is other than 3
    while any(arrayfun(@(x) numel(unique(matrix(x,:))), (1:size(matrix,1)).')~=3)
        % keep generating random matrices
        indices = randperm(numel(test));
        matrix = reshape(test(indices), 5, 3);   
    end;
    
    % here is the result
    result=matrix;
    

    编辑:如果您想要评论中提到的 3x5,那就容易多了。下面只有一行。

    [~, result] = sort(rand(3,5),2);
    

    【讨论】:

    • 太好了,非常感谢。然而我犯了一个小错误。我希望最终矩阵是 3x5 而不是我一开始写的 5x3。对不起这个错误。你能帮我解决这个小变化吗?
    • 如果你想要3x5[~, result] = sort(rand(3,5),2);
    • 太棒了,谢谢 Vahe。我有最后一个问题要问你,希望你能帮助我。说 test = [1 1 1 2 2 2 3 3 3] 我想将它填充到没有行 repetionen 的 3x5 矩阵中,并将多余的单元格留空(或 =)这是如何完成的?
    • 如果我理解正确你想要什么result(ismember(result, [4,5]))=0;,你可以在之后添加这个
    猜你喜欢
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    相关资源
    最近更新 更多