【问题标题】:matrix get min values of a matrix before max values occurred矩阵在最大值出现之前获取矩阵的最小值
【发布时间】:2012-08-02 13:42:42
【问题描述】:

我试图在矩阵的最大值出现之前获取矩阵的最小值。我有两个矩阵:矩阵数据和矩阵a。矩阵 a 是矩阵数据的子集,由矩阵数据的最大值组成。我有以下代码,但显然做错了什么。

edit:

矩阵 a 是矩阵数据的最大值。我是从:

for x=1:size(data,1)
a(x)=max(data(x,:));
end
a=a'
clear x 

矩阵b代码:

for x=1:size(data,1)
b(x)=min(data(x,(x<data==a)));
end
b=b'
clear x

matrix data   matrix a   matrix b
1  2   3  4      4        1
6  5   4  7      7        4
9  6  12  5     12        6

我需要矩阵数据中出现的矩阵 a 之前出现的所有最小值

【问题讨论】:

  • 您是如何获得Max 数据的,它是否正确?另外你能详细说明问题是什么吗?您没有得到正确的最小值还是代码中存在实际错误?
  • 最好为变量使用其他名称而不是内置函数的名称,即使大小写不同...
  • 你想要什么?能给我举个例子吗?例如。 data=[1 3 5 4 2 0] --> a=5 然后你想要最小的子集[1 3 5]

标签: matlab max min


【解决方案1】:

简短:

[a,idxmax] = max(data,[],2);
b = arrayfun(@(ii) min(data(ii,1:idxmax(ii))), 1:size(data,1));

相同
b=NaN(1,size(data,1)); % preallocation!
for ii=1:size(data,1)
    b(ii) = min(data(ii,1:idxmax(ii)));
end

忽略最大值本身

如果您想要之前所有的最小值(不包括最大值),最大值可能是第一个数字,并且您尝试取空矩阵的最小值。解决方案是使用单元格输出,可以为空:

b = arrayfun(@(ii) min(data(ii,1:idxmax(ii)-1)), 1:size(data,1),'uni',false);

用 NaN 替换空单元格

如果您想将空单元格替换为 Nan,然后返回矩阵,请使用:

b(cellfun(@isempty,b))={NaN};
b=cell2mat(b);

或者直接使用早期版本,当b(ii)等于a(ii)时,将b(ii)替换为a(ii)同样的结果:

b = arrayfun(@(ii) min(data(ii,1:idxmax(ii))), 1:size(data,1));
b(b'==a) = NaN

示例:

data=magic(4)

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

输出:

a' = 16    11    12    15

b =
    16     5     6     4

b =[1x0 double]    [5]    [6]    [4]

对于使用单元格输出并忽略最大值本身的第二个解决方案。



顺便说一句:

for x=1:size(data,1)
    a(x)=max(data(x,:));
end
a=a'
clear x

可以替换为

a=max(data,[],2);

【讨论】:

  • 绝对是最短的答案,通过使用 matlabs 内置矩阵 for 循环,arrayfun - 不错。我试图走完整的矩阵路径,但代码可读性较差。
  • 关于首先出现的最大值,为什么输出必须是一个单元格?可以用 NaN 或 0 代替吗?
  • 使用 for 循环,是的,但是您必须使用 if/then/else 过滤掉它,而不是直接使用 arrayfun,因为它想用相同的维度吐出东西;和0x1 != 1x1 我将编辑以附加此
  • @GuntherStruyf 你能解释一下这个索引吗:[a,idxmax] = max(data,[],2);
  • @BernardUntalanJr。 max documentation中描述下的第 6 行
【解决方案2】:

这并不漂亮,但这是我迄今为止发现的唯一一种没有循环的方式。

如果循环没问题,我会推荐 Gunther Struyf 回答作为 matlab 内置数组循环函数的最紧凑用法,arrayfun

如果您想要列分钟而不是行,则某些转置等可能是多余的......

[mx, imx] = max(data');
inds = repmat(1:size(data,2), [size(data,1),1]);
imx2 = repmat(imx', [1, size(data,2)]);
data2 = data;
data2(inds >= imx2) = inf;
min(data2');

注意:如果不需要数据,我们可以删除额外的data2 变量,并减少行数。

所以来演示一下这是做什么的,(看看我是否正确理解了这个问题):

输入

>> data = [1,3,-1; 5,2,1]

我得到最小值:

>> min(data2')
ans = [1, inf]

即它只在每行的最大值之前找到最小值,其他任何东西都设置为inf

言辞:

  • 为每一行获取最大值的索引
  • 生成列索引矩阵
  • 使用repmat 生成一个矩阵,与每行最大索引的数据大小相同
  • 将数据设置为无穷大,其中列索引> max_index 矩阵
  • 像往常一样找到最小值。

【讨论】:

  • 你也可以用bsxfun(@ge,1:size(data,1),imx')生成索引矩阵inds&gt;=imx2
  • 这不是又一个变相的matlab循环函数吗?
  • 是的,但是一个快的,反正比 repmat 快。也更容易,因为您不必预先分配并让索引在您的代码中飞来飞去
  • @mutzmatron。感谢底部的解释。我是编程新手,不了解程序是如何运行的。
  • @mutzmatron,更多内容在这里:blogs.mathworks.com/loren/2008/08/04/… ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
相关资源
最近更新 更多