我有一个矩阵u
,我想遍历所有行和所有列并执行以下操作。如果元素不为零,则返回行索引的值。如果元素为零,则在该元素之后的下一个非零元素中查找行索引。我可以使用两个带有查找功能的for循环轻松地做到这一点。但是我需要做很多次(不是因为矩阵的大小,而是因为多次调用)。我怎样才能更快地完成?
这是for循环代码:
for w=scenario_size:-1:1
for t=1:time_size
l = u(t,w) ;
if l~=0
tprime = t ;
else
tprime = t+ find(u(t:end,w),1,'first') -1 ;
end
i(t,w) = tprime ;
boo(t,w) = number(tprime,w)/u(tprime,w) ;
end
end
例如,如果一列为[0,0,5,1,0,3]
,则i
为[3,3,3,4,6,6]
。 u
的任何列的最后一个元素始终为非零(我通过在结尾处人工添加一行来强制执行此操作)。
然后,boo
是某个矩阵tprime
除以相应的number
(在构造上非零)而对应的u
条目。
答案 0 :(得分:5)
您可以使用find
,cummin
和某些logical indexing解决此问题。从此示例案例开始:
>> u = randi([0 1], 10);
>> u(end, :) = 1
u =
0 0 0 0 1 0 1 0 1 1
1 0 1 1 1 0 0 0 0 1
0 0 0 0 0 1 0 1 1 0
1 1 1 0 1 1 0 0 0 0
0 0 1 0 0 0 0 0 1 0
1 1 1 0 0 0 0 0 0 0
0 1 0 1 0 0 1 1 0 1
1 1 0 1 0 1 1 1 1 1
1 0 0 1 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1
以下内容将满足您的需求:
i = nan(size(u)); % Start with all nan values
[r, ~] = find(u); % Get row indices of non-zero values
i(u ~= 0) = r; % Place row indices in locations of non-zero values
i = cummin(i, 1, 'reverse'); % Column-wise cumulative minimum, starting from bottom
结果:
i =
2 4 2 2 1 3 1 3 1 1
2 4 2 2 2 3 7 3 3 2
4 4 4 7 4 3 7 3 3 7
4 4 4 7 4 4 7 7 5 7
6 6 5 7 10 8 7 7 5 7
6 6 6 7 10 8 7 7 8 7
8 7 10 7 10 8 7 7 8 7
8 8 10 8 10 8 8 8 8 8
9 10 10 9 10 10 9 9 9 9
10 10 10 10 10 10 10 10 10 10
然后您可以通过将boo
转换为linear index来计算矩阵i
:
index = i+time_size.*repmat(0:(scenario_size-1), time_size, 1); % Create linear index
boo = number(index)./u(index);
或者,您可以从一开始就将i
计算为线性索引:
i = nan(size(u)); % Start with all nan values
index = find(u); % Get linear indices of non-zero values
i(index) = index; % Place linear indices in locations of non-zero values
i = cummin(i, 1, 'reverse'); % Column-wise cumulative minimum, starting from bottom
boo = number(i)./u(i);
答案 1 :(得分:1)
@gnovice 答案很好,只是为find
函数提供了一个替代方法
u
矩阵 >> u = randi([0 1], 10);
u(end, :) = 1;
>> u
u =
0 0 0 0 0 1 1 0 0 0
0 1 1 1 0 1 0 1 1 1
1 1 1 0 1 0 0 1 1 0
1 1 1 1 1 0 1 1 0 1
1 1 0 1 1 1 1 0 0 0
0 0 1 0 1 1 1 0 0 1
0 1 0 0 1 1 0 0 0 1
0 1 0 1 1 1 0 1 1 0
0 0 0 1 0 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
non-zeros
行索引 >> t = 1:10*10;% All elements indices
r = t(u ~= 0); % All non-zeros elements indices
>> r
r =
Columns 1 through 18
3 4 5 10 12 13 14 15 17 18 20 22 23 24 26 30 32 34
Columns 19 through 36
35 38 39 40 43 44 45 46 47 48 50 51 52 55 56 57 58 59
Columns 37 through 54
60 61 64 65 66 69 70 72 73 74 78 79 80 82 83 88 89 90
Columns 55 through 60
92 94 96 97 99 100