【问题标题】:Matlab: Grouping and minimizing unique column element's index of a matrixMatlab:对矩阵的唯一列元素索引进行分组和最小化
【发布时间】:2012-12-02 12:16:18
【问题描述】:

我们有以下矩阵result

result =
  Columns 1 through 13
     3     1     1     1     1     1     6     2     3     6     2     1     6
     4     3     3     5     7     5    10    10     4    10     6     9     8
     6     4     4     7     9     7     0     0     0     0     0     0     0
    10     5     5     8     0     0     0     0     0     0     0     0     0
  Columns 14 through 25
     2    10     3    10     3     8     8     0     0     0     0     0
     8     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0

其列唯一元素索引大小为(不含零):

Indexes of result:
  Columns 1 through 13
     4     4     4     4     3     3     2     2     2     2     2     2     2
  Columns 14 through 25 
     2     1     1     1     1     1     1 

我想执行以下场景: 从第一列开始,我们希望限制每个非唯一值在矩阵中仅出现一次。 所以以 col1 为起点,矩阵的其余部分应重新排列为:

result =
  Columns 1 through 13
     3     1     1     1     1     1     0     2     0     0     2     1     0
     4     0     0     5     7     5     0     0     0     0     0     9     8
     6     0     0     7     9     7     0     0     0     0     0     0     0
    10     5     5     8     0     0     0     0     0     0     0     0     0
  Columns 14 through 25
     2     0     0     0     0     8     8     0     0     0     0     0
     8     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0
 Indexes of result (without zeros):
  Columns 1 through 13
     4     2     2     4     3     3     0     1     0     0     1     2     1
  Columns 14 through 25 
     2     0     0     0     0     1     1      

现在我们看到 col4 有最独特的元素,所以我们考虑它的值继续第二次重新排列,结果是:

result =
  Columns 1 through 13
     3     0     0     1     0     0     0     2     0     0     2     0     0
     4     0     0     5     0     0     0     0     0     0     0     9     0
     6     0     0     7     9     0     0     0     0     0     0     0     0
    10     0     0     8     0     0     0     0     0     0     0     0     0
  Columns 14 through 25
     2     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0

Indexes of result (without zeros):
  Columns 1 through 13
     4     0     0     4     1     0     0     1     0     0     1     1     0  
  Columns 14 through 25 
     1     0     0     0     0     1     1    

根据需要多次执行此操作,在该示例中,对于 col5 和 col8 再进行两次,我们达到了预期的结果:

result =
  Columns 1 through 13
     3     0     0     1     0     0     0     2     0     0     0     0     0
     4     0     0     5     0     0     0     0     0     0     0     0     0
     6     0     0     7     9     0     0     0     0     0     0     0     0
    10     0     0     8     0     0     0     0     0     0     0     0     0
  Columns 14 through 25
     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0

Indexes of result (without zeros):
  Columns 1 through 13
     4     0     0     4     1     0     0     1     0     0     0     0     0  
  Columns 14 through 25 
     0     0     0     0     0     0     0 

执行此操作的最有效方法是什么? 我可以看看你的建议吗?

提前谢谢你。

【问题讨论】:

  • @EitanT 我的问题是找到一种方法来执行这个特定的分组 - 最小化 plus 以找到最有效的方法。
  • 你不是已经自己实现了吗?那你是怎么得到这些结果的?
  • @EitanT 我已经实现了它,而无需将尽可能多的元素与更少的列相关联。结果代表了期望的结果,并且是手工制作的。

标签: matlab size unique minimize


【解决方案1】:

您的问题措辞不佳,因此以下是我设法从中理解的逐步细分。

假设您有以下矩阵:

result=[3  1  1  1  1  1  6  2  3  6  2  1  6  2 10  3 10 3  8  8  0  0  0  0  0;
        4  3  3  5  7  5 10 10  4 10  6  9  8  8  0  0  0  0 0  0  0  0  0  0  0;
        6  4  4  7  9  7  0  0  0  0  0  0  0  0  0  0  0  0 0  0  0  0  0  0  0;
       10  5  5  8  0  0  0  0  0  0  0  0  0  0  0  0  0  0 0  0  0  0  0  0  0]

1) 要计算每列中唯一元素的数量,只需在每列上调用 unique 并计算非零元素:

count = arrayfun(@(n)sum(unique(result(:, n)) ~= 0), 1:size(result, 2))

2) 要使第 1 列的所有重复元素无效,我们可以这样做:

idx = arrayfun(@(n)ismember(result(:, n), result(:, 1)), 2:N, 'Uniform', 0);
result(logical([idx{:}])) = 0

现在我们需要遍历所有列并取消所有非唯一元素,因此我们使用循环来执行此操作。因此最终的解决方案是:

N = size(result, 2);
ii = 0;
while (ii <= N)

    % # Count the number of unique elements in each column
    count = arrayfun(@(n)sum(unique(result(:, n)) ~= 0), 1:N);

    % # Advance to the next column with the maximum number of unique elements
    ii = ii + find(count(:, ii + 1:N) == max(count(:, ii + 1:N)) & count(ii + 1:N), 1);
    if isempty(ii)
        break
    end

    % # Nullify non-unique elements starting from column i
    idx = arrayfun(@(n)(ismember(result(:, n), result(:, ii)) & n ~= ii), 1:N, 'Uniform', 0);
    result(logical([idx{:}])) = 0;
end

这会产生您想要的结果:

result=
    3  0  0  1  0  0  0  2  0  0  0  0  0  0  0  0  0  0 0  0  0  0  0  0  0
    4  0  0  5  0  0  0  0  0  0  0  0  0  0  0  0  0  0 0  0  0  0  0  0  0
    6  0  0  7  9  0  0  0  0  0  0  0  0  0  0  0  0  0 0  0  0  0  0  0  0
   10  0  0  8  0  0  0  0  0  0  0  0  0  0  0  0  0  0 0  0  0  0  0  0  0

希望有帮助!

【讨论】:

  • 尊敬的先生,非常感谢您。我非常感谢您花费时间和精力来帮助您不认识的人。你的解决方案是正确的。很好@EitanT。附:我没有在您的个人资料中看到您的电子邮件,请通过我的电子邮件与我联系。
  • 很高兴为您提供帮助。这就是 StackOverflow 的用途!
猜你喜欢
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
  • 2014-09-22
  • 2012-10-16
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多