我在Matlab中有一行代码:
output = find(input);
其中列向量“output”包含列向量“input”中其元素非零的所有索引。例如,如果:
input = [1 3 4 0 0 2 0];
然后结果,output = find(输入);将是:
output =
1
2
3
6
对应于非零的数组“输入”的第1(“1”),第2(“3”),第3(“4”)和第6(“2”)索引。
由于我的“输入”数组非常大,这行代码消耗了我所有的本地RAM以及大量的虚拟内存,导致系统慢慢爬行。
任何人都知道减少这种操作的内存需求的好方法(或任何方式)?我想把“查找”代码放在一个循环中,但由于数组“输出”的大小(以及这个数组的索引)取决于“查找”操作的结果,我看不出它是如何可能的这样做。出于想法。
提前感谢您的任何意见/建议。 -gkk
答案 0 :(得分:3)
如果你有比零更多的非零值,也许你可以使用补语,即:output=find(input==0)
而不是默认值,相当于output=find(input~=0)
此外,您可以使用逻辑索引,比较:
>> output1 = find(input);
>> output2 = (input~=0);
>> whos output*
Name Size Bytes Class Attributes
output1 1x4 32 double
output2 1x7 7 logical
注意它是如何存储为“booleans”的向量,每个是一个字节(对于“double”为8个字节)
答案 1 :(得分:2)
如果您有足够的内存来保存与input
大小相同的数组,则可以将调用替换为find
output = 1:length(input);
output = output(input~=0);
如果input
的元素少于2 ^ 32-1,则可以将其初始化为uint32
,从而进一步节省内存。
更好的方法可能是将input
数组转换为sparse,如果input
包含大量零,则可以节省内存,然后在其上使用find
,即
input = sparse(input);
output = find(input);
修改强>
要分段执行find
操作,我会执行以下操作:
nIn = length(input);
blockLength = 100000;
nBlocks = ceil(nIn/blockLength); %# work in chunks of 100k entries
out = cell(nBlocks,1);
for i=1:nBlocks
out{i} = (i-1)*blockLength+1:i*blockLength; %# assign as your favorite integer format here
out{i} = out{i}(input(out{i})~=0);
end
out = cat(1,out{:});