【问题标题】:group by in Matlab to find the value that resulted minimum similar to SQL在 Matlab 中分组以找到类似于 SQL 的最小值
【发布时间】:2013-09-07 10:43:47
【问题描述】:

我有一个包含 a、b、c 和 d 列的数据集 我想按 a,b 对数据集进行分组并找到 c 使得每个组的 d 最小 我可以使用“grpstats”作为“分组依据”:

grpstats(M,[M(:,1) M(:,2) ],{'min'});

我不知道如何找到导致 d 中最小值的 M(:,3) 的值

在 SQL 中,我想我们为此使用嵌套查询并使用主键。如何在 Matlab 中求解?

这是一个例子:

>> M =[4,1,7,0.3;
2,1,8,0.4;
2,1,9,0.2;
4,2,1,0.2;
2,2,2,0.6;
4,2,3,0.1;
4,3,5,0.8;
5,3,6,0.2;
4,3,4,0.5;]

>> grpstats(M,[M(:,1) M(:,2)],'min')
ans =

2.0000    1.0000    8.0000    0.2000
2.0000    2.0000    2.0000    0.6000
4.0000    1.0000    7.0000    0.3000
4.0000    2.0000    1.0000    0.1000
4.0000    3.0000    4.0000    0.5000
5.0000    3.0000    6.0000    0.2000

但是 M(1,3) 和 M(4,3) 是错误的。我正在寻找的正确答案是:

2.0000    1.0000    9.0000    0.2000
2.0000    2.0000    2.0000    0.6000
4.0000    1.0000    7.0000    0.3000
4.0000    2.0000    3.0000    0.1000
4.0000    3.0000    4.0000    0.5000
5.0000    3.0000    6.0000    0.2000

总之,我不想要第三列的最小值;但我希望它的值对应于第 4 列中的最小值

【问题讨论】:

  • 你能展示(简短的)样本数据,你得到的输出吗?不确定我是否理解你的问题。 “导致 d 中的最小值的 M(:,3) 的值”是什么意思?
  • 当然。我编辑了问题内容。

标签: sql matlab group-by


【解决方案1】:

grpstats 不会这样做,而且 MATLAB 也没有您希望的那样简单。

有时蛮力是最好的,即使它感觉不像是很棒的 MATLAB 风格:

[b,m,n]=unique(M(:,1:2),'rows');
for i =1:numel(m)
    idx=find(n==i);
    [~,subidx] = min(M(idx,4));
    a(i,:) = M(idx(subidx),3:4);
end

>> [b,a]
ans =
        2            1            9          0.2
        2            2            2          0.6
        4            1            7          0.3
        4            2            3          0.1
        4            3            4          0.5
        5            3            6          0.2

【讨论】:

  • 感谢这项工作。我正在考虑用循环来做,但试图以更有效的方式来做。
  • 是的,我试过一段时间用 MATLAB 的方式来做,但放弃了。对于像这样的小数据集,无论如何它不会有太大的不同。如果答案对您有用,请使用左侧的勾选按钮将其标记为已接受。
  • 这是一个示例数据集;真正的要大得多。还是谢谢
【解决方案2】:

我相信

temp = grpstats(M(:, [1 2 4 3]),[M(:,1) M(:,2) ],{'min'});
result = temp(:, [1 2 4 3]);

会做你需要的。如果不是,请在 cmets 中说明,我们可以解决...

如果我正确理解文档,甚至

temp = grpstats(M(:, [1 2 4 3]), [1 2], {'min'});
result = temp(:, [1 2 4 3]);

应该可以(给出列号而不是列的全部内容)...现在无法测试,因此无法保证。

【讨论】:

  • 不,两者都返回相同的错误答案。如果您在 Matlab 中运行其中任何一个,您将看到 M(:,[1 2])=[2 1] 行,即答案的第一行,它返回 M(:,3)=8。而如果您查看初始数据集,则 M(:,[1 2 4])=0.2 的值对应于 M(:,3)=9 而不是 8。它没有保留初始行,它确实找到了至少分别为第 3 列和第 4 列。我只需要第 4 列的最小值和第 3 列中的相应值。
  • 我必须在早上使用 Matlab 来测试一些替代方案时尝试这个......抱歉我现在不能这样做。
  • 如果 'min' 在 grpstats(M(:, [1 2 4 3]), [1 2], {'min'}) 将返回索引而不是值,那么它会更容易解决问题。
猜你喜欢
  • 2013-10-24
  • 1970-01-01
  • 2018-03-04
  • 2016-02-12
  • 2013-04-18
  • 2021-08-14
  • 2021-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多