1

我是 Matlab 的新手,只是不知道如何做一个可以在 excel 中轻松执行的简单任务。我只是想获得矩阵中单元格之间的百分比变化。我想为此任务创建一个 for 循环。数据设置为以下格式:

                DAY1 DAY2 DAY3...DAY 100

主题结果

我只能执行获取两个数据点之间的百分比变化。如果跨越多天和多个主题,我将如何进行?并请提供解释

谢谢一堆

例如,对于第 1 天的主题 1(结果 = 1)、主题 2(结果 = 4)、主题 3(结果 = 5)、第 2 天的主题 1(结果 = 2)、主题 2(结果 = 8)、主题 3(结果 = 10),第 3 天 主题 1(结果 = 1)、主题 2(结果 = 4)、主题 3(结果 = 5)。我想要百分比变化,所以输出将是第 2 天的 SUBJECT1(RESULT=100%)、SUBJECT2(RESULT=100%)、SUBJECT3(RESULT=100%)。DAY3 主题1(结果=50%),主题2(结果=50%),主题3(结果=50%)

更新:

嗨,感谢您的回复。对困惑感到抱歉。zebediah49 非常接近我正在寻找的东西。例如,我的数据是 10 x 10 双倍。我只是想获得从列到列的百分比变化。例如,如果我想要所有列(从第 2:10 列)从第 1 行到第 10 行的百分比变化。我希望代码适用于任何矩阵维度(例如,1000 x 1000 双)zebediah49 你能解释一下你发布的代码吗?谢谢

更新2:zebediah49,

(数据(1:end,100)-数据(1:end,99))./data(1:end,99)

输出=[数据(:,2:end)-数据(:,1:end-1)]./data(:,1:end-1)*100;

观察上面的代码,我将如何修改它,以便将第 100 列用作所有其他列(1-99)的索引?如果我将代码更改为以下内容:

(数据(1:end,100)-数据(1:end,:))./data(1:end,:)

matlab 由于超出矩阵尺寸而无法使用。我将如何实施呢?

更新 3

zebediah49,

完美运行!!!最初我为索引创建了一个新变量,并重新计算索引以匹配矩阵,这不是一个好主意。在处理大量数据时,复制需要很长时间。再次感谢您的贡献。

也感谢克里斯的贡献!!!我正在寻找更多关于如何处理和操作矩阵中的数组。

4

2 回答 2

4

这是matlab;你实际上并不想要一个循环。

output=input(2:end,:)./input(1:end-1,:)*100;

大概会做你想要的。由于您没有提供有关您的 matlab 结构的任何信息,因此您可能必须更改索引顺序等才能使其正常工作。

如果不是很明显,该行将输出定义为由输入矩阵组成的矩阵,除以输入矩阵右移一个元素。./运算符很重要,因为它意味着您将每个元素除以其对应的元素,而不是进行矩阵除法。

编辑:要求进一步解释:我假设您希望 % change of the form1->1->2->3->1100%, 200%, 150%, 33%. 另一种形式可以通过减法得到100%

input(2:end,:)将抓取一个子矩阵,其中第一行被切断。(我把时间放在第一个维度上......如果你想要它的另一种方式input(:,2:end)。Matlab 是 1-indexed,并允许你使用特殊值end来引用 las 元素。因此,end-1是倒数第二个.这里的重点是这个矩阵的元素(i)是原始的元素(i+1)。

input(1:end-1,:),和上面一样,也会抓取一个子矩阵,只是它缺少最后一列。

然后我将元素 (i) 除以元素 (i+1)。由于我选择子矩阵的方式,它们现在排成一行。

作为半图形演示,使用我上面的数字:

input:          [1 1 2 3 1]
input(2,end):     [1 2 3 1]
input(1,end-1): [1 1 2 3]

当我进行除法时,它是第一/第一,第二/第二等。

input(2:end,:)./input(1:end-1,:):
   [1   2   3   1  ]
./ [1   1   2   3  ]
---------------------
== [1.0 2.0 1.5 0.3]

设置为 (:) 的额外索引意味着它将在所有其他维度上执行该过程。

EDIT2:修订后的问题:如何排除一行,并将其保留为索引。你说你尝试了一些效果(data(1:end,100)- data(1:end,:))./data(1:end,:)。Matlab 不会喜欢这样,因为逐个元素的运算符需要它们的大小相同。如果您希望它仅适用于第 100 列,则将第二个索引设置为 is100而不是:会这样做。相反,我建议将第一个设置为索引,其余设置为数据。因此,通过切断第一个数据来处理数据:

output=[data(2:end,2:end)-data(2:end,1:end-1)]./data(2:end,1:end-1)*100;

或者,(如果您忽略开头,matlab 假定1为 ;忽略结尾,它end假定(:)(1:end).

output=[data(2:,2:end)-data(2:,1:end-1)]./data(2:,1:end-1)*100;

但是,您可能仍希望返回索引,在这种情况下,您需要将该子数组附加回来:

output=[data(1,1:end-1) data(2:,2:end)-data(2:,1:end-1)]./data(2:,1:end-1)*100];

不过,这可能不是您应该这样做的方式——将数据保存在一个矩阵中,将时间或其他任何内容保存在一个单独的数组中。这使得对数据执行此类操作变得更加容易,而不必担心排除时间。绘图时特别好。

还有件事儿:

(data(:,2:end)-data(:,1:end-1))./data(:,1:end-1)*100;

等同于

data(:,2:end)./data(:,1:end-1)*100-100;
于 2012-05-24T06:31:59.747 回答
2

假设 zebediah49 在上面的评论中猜对了并且你想要

1  4  5
2  8 10
1  4  5

变成

   1    1    1
 -.5  -.5  -.5

然后试试这个:

data = [1,4,5; 2,8,10; 1,4,5];
changes_absolute = diff(data);
changes_absolute./data(1:end-1,:)

ans =

    1.0000    1.0000    1.0000
   -0.5000   -0.5000   -0.5000

不需要中间变量,直接写diff(data)./data(1:end,:). 我只是认为上面的内容可能更容易阅读。从该结果到百分比数字留给读者作为练习。:-)

哦,如果你真的想要 50%,而不是 -50%,就abs在最后一行使用。

于 2012-05-24T07:19:27.263 回答