Matlab表/数据集类型优化
我正在Matlab中搜索“观测变量”表的一些优化数据类型,这些数据类型可以通过列(通过变量)和行(通过观测)快速方便地访问 以下是现有Matlab数据类型的比较:Matlab表/数据集类型优化,matlab,matrix,data-structures,dataset,tuples,Matlab,Matrix,Data Structures,Dataset,Tuples,我正在Matlab中搜索“观测变量”表的一些优化数据类型,这些数据类型可以通过列(通过变量)和行(通过观测)快速方便地访问 以下是现有Matlab数据类型的比较: 矩阵非常快,hovewer,它的维度没有内置的索引标签/枚举,并且您不能总是按列索引记住变量名 表的性能非常差,尤其是在读取for循环中的单个行/列时(我认为它运行一些缓慢的转换方法,并且设计得更像Excel) 标量结构(列数组结构)数据类型-快速以列方式访问作为向量的变量,但缓慢地以行方式转换为观测值 非标度结构(结构数组)-快速按
----
TEST1 - reading individual observations
Matrix: 0.072519 sec
Table: 18.014 sec
Array of structures: 0.49896 sec
Structure of arrays: 4.3865 sec
----
TEST2 - reading individual variables
Matrix: 0.0047834 sec
Table: 0.0017972 sec
Array of structures: 2.2715 sec
Structure of arrays: 0.0010529 sec
Nobs = 1e5; % number of observations-rows
varNames = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O'};
Nvar = numel(varNames); % number of variables-colums
M = randn(Nobs, Nvar); % matrix
T = array2table(M, 'VariableNames', varNames); % table
NS = struct; % nonscalar structure = array of structures
for i=1:Nobs
for v=1:Nvar
NS(i).(varNames{v}) = M(i,v);
end
end
SS = struct; % scalar structure = structure of arrays
for v=1:Nvar
SS.(varNames{v}) = M(:,v);
end
%% TEST 1 - reading individual observations (row-wise)
disp('----'); disp('TEST1 - reading individual observations');
tic; % matrix
for i=1:Nobs
x = M(i,:); end
disp(['Matrix: ', num2str(toc()), ' sec']);
tic; % table
for i=1:Nobs
x = T(i,:); end
disp(['Table: ', num2str(toc), ' sec']);
tic;% nonscalar structure = array of structures
for i=1:Nobs
x = NS(i); end
disp(['Array of structures: ', num2str(toc()), ' sec']);
tic;% scalar structure = structure of arrays
for i=1:Nobs
for v=1:Nvar
x.(varNames{v}) = SS.(varNames{v})(i);
end
end
disp(['Structure of arrays: ', num2str(toc()), ' sec']);
%% TEST 2 - reading individual variables (column-wise)
disp('----'); disp('TEST2 - reading individual variables');
tic; % matrix
for v=1:Nvar
x = M(:,v); end
disp(['Matrix: ', num2str(toc()), ' sec']);
tic; % table
for v=1:Nvar
x = T.(varNames{v}); end
disp(['Table: ', num2str(toc()), ' sec']);
tic; % nonscalar structure = array of structures
for v=1:Nvar
for i=1:Nobs
x(i,1) = NS(i).(varNames{v});
end
end
disp(['Array of structures: ', num2str(toc()), ' sec']);
tic; % scalar structure = structure of arrays
for v=1:Nvar
x = SS.(varNames{v}); end
disp(['Structure of arrays: ', num2str(toc()), ' sec']);
测试脚本:
----
TEST1 - reading individual observations
Matrix: 0.072519 sec
Table: 18.014 sec
Array of structures: 0.49896 sec
Structure of arrays: 4.3865 sec
----
TEST2 - reading individual variables
Matrix: 0.0047834 sec
Table: 0.0017972 sec
Array of structures: 2.2715 sec
Structure of arrays: 0.0010529 sec
Nobs = 1e5; % number of observations-rows
varNames = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O'};
Nvar = numel(varNames); % number of variables-colums
M = randn(Nobs, Nvar); % matrix
T = array2table(M, 'VariableNames', varNames); % table
NS = struct; % nonscalar structure = array of structures
for i=1:Nobs
for v=1:Nvar
NS(i).(varNames{v}) = M(i,v);
end
end
SS = struct; % scalar structure = structure of arrays
for v=1:Nvar
SS.(varNames{v}) = M(:,v);
end
%% TEST 1 - reading individual observations (row-wise)
disp('----'); disp('TEST1 - reading individual observations');
tic; % matrix
for i=1:Nobs
x = M(i,:); end
disp(['Matrix: ', num2str(toc()), ' sec']);
tic; % table
for i=1:Nobs
x = T(i,:); end
disp(['Table: ', num2str(toc), ' sec']);
tic;% nonscalar structure = array of structures
for i=1:Nobs
x = NS(i); end
disp(['Array of structures: ', num2str(toc()), ' sec']);
tic;% scalar structure = structure of arrays
for i=1:Nobs
for v=1:Nvar
x.(varNames{v}) = SS.(varNames{v})(i);
end
end
disp(['Structure of arrays: ', num2str(toc()), ' sec']);
%% TEST 2 - reading individual variables (column-wise)
disp('----'); disp('TEST2 - reading individual variables');
tic; % matrix
for v=1:Nvar
x = M(:,v); end
disp(['Matrix: ', num2str(toc()), ' sec']);
tic; % table
for v=1:Nvar
x = T.(varNames{v}); end
disp(['Table: ', num2str(toc()), ' sec']);
tic; % nonscalar structure = array of structures
for v=1:Nvar
for i=1:Nobs
x(i,1) = NS(i).(varNames{v});
end
end
disp(['Array of structures: ', num2str(toc()), ' sec']);
tic; % scalar structure = structure of arrays
for v=1:Nvar
x = SS.(varNames{v}); end
disp(['Structure of arrays: ', num2str(toc()), ' sec']);
我会使用矩阵,因为它们是最快、最简单的使用方法,然后创建一组枚举列标签,使列索引更容易。以下是几种方法:
使用对象: 给定变量名,并假设它们按从第1列到第N列的顺序映射,您可以创建如下映射:
varNames = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O'};
col = containers.Map(varNames, 1:numel(varNames));
现在,您可以使用映射按变量名访问数据列。例如,如果要从矩阵数据
中获取变量A
和C
的列(即第一列和第三列),可以执行以下操作:
subData = data(:, [col('A') col('C')]);
使用: 您可以创建一个结构,其中变量名作为其字段,相应的列索引作为其值,如下所示:
enumData = [varNames; num2cell(1:numel(varNames))];
col = struct(enumData{:});
下面是col
包含的内容:
struct with fields:
A: 1
B: 2
C: 3
D: 4
E: 5
F: 6
G: 7
H: 8
I: 9
J: 10
K: 11
L: 12
M: 13
N: 14
O: 15
您可以访问A
和C
列,如下所示:
subData = data(:, [col.A col.C]);
% ...or with dynamic field names...
subData = data(:, [col.('A') col.('C')]);
subData = data(:, [ColVar.A ColVar.C]);
制作一组变量: 您可以在工作区中为每个列名创建一个变量,并在其中存储列索引。这将用更多的变量污染您的工作区,但为您提供了一种访问列数据的简洁方法。下面是一个简单的方法,使用备受诟病的: 访问列
A
和C
非常简单:
subData = data(:, [A C]);
使用一个: 这可能有点过分,但如果要在许多分析中使用相同的列标签和索引映射,可以创建一个枚举类,将其保存在计算机上的某个位置,而不必担心再次定义列枚举。例如,这里有一个带有15个枚举值的
ColVar
类:
classdef ColVar < double
enumeration
A (1)
B (2)
C (3)
D (4)
E (5)
F (6)
G (7)
H (8)
I (9)
J (10)
K (11)
L (12)
M (13)
N (14)
O (15)
end
end
为获得准确的结果,应使用进行计时。此外,只需使用一个矩阵,并在上面/后面/下面或列包含的某个地方添加注释。在一个通常是第一个注释部分的函数中,即当您键入
help FunctionName
时得到的函数,我已经检查过了,并且用timeit
计时会得到大致相同的结果。我原以为gnovice的containers.Map解决方案会适合您的喜好。这是我对这个问题的最初反应。我唯一能想到的另一件事是扩展一个基本类,比如struct。感谢您提供有趣的解决方案!但在所有这些情况下,对于枚举列标签和数据集本身,我将使用不同的matlab变量。我曾尝试从内置Matlab双类继承并添加属性或枚举来保存变量名,但没有成功:“当内置类的子类定义属性时,Matlab不再支持索引和串联操作”@Sairus:True,将内置数据类型子类化可能会降低效率,因为您必须自己实现索引和连接方法(在链接中列出)。不过,我不清楚为什么这些选项不够好。如果效率至关重要,那么一个简单的矩阵似乎就是您想要的,唯一的问题是记住哪个列标签映射到哪个索引。上面的解决方案应该可以帮你省去这些麻烦。我正在开发一个系统,该系统可以依次处理一组信号到多个数据集,并且将许多标签传递给每个处理函数是相当尴尬的。或者,我可以编写数据存储类,它保存您答案中的原始矩阵和标签结构,并使用获取和设置方法(使用写时复制应该足够快)。但是,我的函数将取决于“核心”类结构。然而,我认为这是现有Matlab数据类型要解决的一个更常见的问题。