我是Matlab的新手,只是难以完成一个可以在excel中轻松执行的简单任务。我只是试图获得矩阵中单元格之间的百分比变化。我想为这个任务创建一个for循环。数据按以下格式设置:
DAY1 DAY2 DAY3...DAY 100
主题结果
我只能执行两个数据点之间的百分比变化。如果跨越多天和多个科目,我将如何进行?请提供解释
非常感谢
例如,第1天SUBJECT1(RESULT = 1),SUBJECT2(RESULT = 4),SUBJECT3(RESULT = 5),第2天SUBJECT1(RESULT = 2),SUBJECT2(RESULT = 8),SUBJECT3(RESULT = 10),第3天SUBJECT1(RESULT = 1),SUBJECT2(RESULT = 4),SUBJECT3(RESULT = 5)。 我想要改变百分比所以输出将是第2天SUBJECT1(结果= 100%),SUBJECT2(结果= 100%),SUBJECT3(结果= 100%)。 DAY3 SUBJECT1(RESULT = 50%),SUBJECT2(RESULT = 50%),SUBJECT3(RESULT = 50%)
更新
updated2: zebediah49,
(数据(1:结束,100) - 数据(1:结束,99))./ data(1:end,99)
输出= [数据(:,2:结束)-data(:,1:端-1)] ./数据(:,1:端-1)×100;
观察上面的代码,我将如何修改它,以便将列100用作所有其他列(1-99)的索引?如果我将代码更改为以下内容:
(data(1:end,100) - data(1:end,:))./ data(1:end,:)
matlab因超出矩阵尺寸而无法使用。我将如何实施?
更新3
zebediah49,
工作得很完美!!!最初我为索引创建了一个新变量,并重新匹配索引以匹配矩阵,这不是一个好主意。处理大数字时需要永远复制。 再次感谢您的贡献。
感谢Chris为您的贡献!我正在寻找更多关于如何在矩阵中处理和操作数组的内容。
答案 0 :(得分:4)
这是matlab;你实际上并不想要一个循环。
output=input(2:end,:)./input(1:end-1,:)*100;
可能会大致按照您的意愿行事。由于您没有提供有关matlab结构的任何内容,因此您可能需要更改索引顺序等,以使其正常工作。
如果不明显,那条线将输出定义为由输入矩阵组成的矩阵,除以右移一个元素的输入矩阵。 ./
运算符很重要,因为它意味着您将每个元素除以相应的元素,而不是进行矩阵除法。
编辑:要求进一步解释:
我假设您希望将1->1->2->3->1
格式的%更改为100%, 200%, 150%, 33%
。
另一种形式可以通过减去100%
来获得。
input(2:end,:)
将获取一个子矩阵,第一行被截断。 (我把时间放在第一维......如果你想要它的另一种方式那就是input(:,2:end)
。
Matlab是1索引的,允许您使用特殊值end
来引用las元素。
因此,end-1
是倒数第二。
这里的要点是该矩阵的元素(i)是原始元素(i + 1)。
input(1:end-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列上工作,则将第二个索引设置为100
而不是:
就可以了。
相反,我会建议将第一个设置为索引,其余设置为数据。
因此,通过切断第一个来处理数据:
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;
答案 1 :(得分: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
。