矢量化 - 将excel文件导入matlab

时间:2012-01-18 08:51:15

标签: matlab for-loop vectorization

我编写了以下函数,用于将excel文件导入matlab。该函数工作正常,通过插入文件的路径名,脚本将它们导入工作区。功能如下所示:

function Data = xls_function(pathName);

%Script imports the relevant .xls files into matlab - ensure that the .xls
%files are stored in a folder specified by 'pathName'.
%--------------------------------------------------------------------------
TopFolder = pathName; 
dirListing = dir(TopFolder);%Lists the folders in the directory specified
        %by pathName.
dirListing = dirListing(3:end);%Remove the first two structures as they
        %are only pointers.
for i = 1:length(dirListing);
    SubFolder{i} = dirListing(i,1).name;%obtain the name of each folder in
            %the specified path.
    SubFolderPath{i} = fullfile(pathName, dirListing(i,1).name);%obtain
            %the path name for each of the folders.
    ExcelFile{i} = dir(fullfile(SubFolderPath{i},'*.xls'));%find the 
            %number of .xls files in each of the SubFolders.
    for j = 1:length(ExcelFile{1,i});
        ExcelFileName{1,i}{j,1} = ExcelFile{1,i}(j,1).name;%find the name
                %of each .xls file in each of the SubFolders.
        for k = 1:length(ExcelFileName);
            for m = 1:length(ExcelFileName{1,k});
                [status{1,k}{m,1},sheets{1,k}{m,1},format{1,k}{m,1}]...
                    = xlsfinfo((fullfile(pathName,SubFolder{1,k},...
                    ExcelFileName{1,k}{m,1})));%gather information on the
                        %.xls files i.e. worksheet names.
                Name_worksheet{1,k}{m,1} = sheets{1,k}{m,1}{1,end};%obtain 
                        %the name of each of the .xls worksheets within 
                        %each spreadsheet.
            end
        end
    end
end

for n = 1:length(ExcelFileName);
    for o = 1:length(ExcelFileName{1,n});
            %require two loops as the number of excel spreadsheets varies 
            %from the number of worksheets in each spreadsheet. 
        TXT{1,n}{o,1} = xlsread(fullfile(pathName,SubFolder{1,n},...
            ExcelFileName{1,n}{o,1}),Name_worksheet{1,n}{o,1});%import the
                %relevant data from excel by using the spreadsheet and
                %worksheet names previously obtained. 
        Data.(SubFolder{n}){o,1} = TXT{1,n}{o,1};
    end
end

脚本的唯一问题是,如果.xls文件的数量很大,则运行时间太长。我已经读过,矢量化会改善运行时间,因此我要求提供任何有关如何通过矢量化更改此代码以更快运行的建议。

我意识到阅读这样的代码并不容易(特别是因为我的编码形式并不像我想的那样高效)但是提供的任何建议都会非常感激。

1 个答案:

答案 0 :(得分:1)

我不认为矢量化适用于你的问题 - 但是一个接着一个。

作为数据的示例,您可以使用cellfun来转换矢量化循环:

tmp = ExcelFileName{1,n}
result_cell = cellfun(@(x) xlsread(fullfile(pathName,x)),tmp, 'UniformOutput', false))

但关键问题是xlsread和matlab中其他excel相关函数的实现不佳。他们所做的是使用每个(!)函数调用,他们创建一个新的excel进程(隐藏),然后执行命令然后结束它。

我记得matlab central的一个工具重用了同一个excel实例,因此非常快 - 但不幸的是我再也找不到了。但也许你可以找到一个例子,你可以在那里重新使用它。


在相关的说明中 - Excel有一个愚蠢的限制,它不允许同时打开两个具有相同名称的文件 - 然后失败并出现一些错误。因此,如果您运行您的阅读矢量化/并行,您将获得奇怪错误的全新乐趣:D

对于我自己,我发现了通过java Apache POI libraries处理这些文档的唯一方法。这些具有很好的优势,你不需要安装Excel - 但不幸的是需要一些编程。