1

引用和分配 matlab 数据集的子集似乎效率极低,并且可能像 rows^2 一样缩放

例子:

alldata 是一个混合数据的大型数据集——比如 150,000 行乘 25 列(整数、布尔值和字符串)。

数据集的格式为:

'format', '%s%u%u%u%u%u%s%s%s%s%s%s%s%u%u%u%u%s%u%s%s%u%s%s%s%s%u%s%u%s%s%s%u%s'

然后我将 2 类型整数 cols 转换为布尔类型

以下子集分配:

somedata = alldata(1:m,:)

对于 m = 10,000 需要 >7 秒,对于较大的 m 值需要花费大量时间。绘制时间与 m 显示了 am^2 类型的关系,这很奇怪,因为复制 alldata 几乎是瞬时的,就像使用 sortrows 和 find 之类的函数一样。事实上,读取原始 .csv 数据文件比上面对大 m 值的赋值要快。

使用分析器,似乎有一个函数 subref 包含一条非常慢的线,用于检查字符串比较以确定数据集中的唯一值。这与数据集类型的存储方式(即参考表)有关吗?数据集包含大量唯一字符串值。

他们有在matlab中提取数据集子集的任何解决方案吗?例如预分配(如何?),或复制数据集并删除行而不是分配提取/子集。

我正在使用具有 1.5Gb 内存的双核机器,但任务管理器报告使用的内存少于 1Gb。

4

2 回答 2

2

我以前曾使用 MATLAB 的数据集数组处理大数据,不幸的是,它们确实存在性能问题。我发现有助于加快速度的一件事是清除观察名称 (ObsNames)属性

尝试以下修复:

%# I assume you have a 'dataset' object
ds = dataset(...);

%# clear the observation names property (It simply a label for each record)
ds.Properties.ObsNames = [];
于 2010-09-29T02:16:44.983 回答
0

Amro 建议清除观察名称:

ds.Properties.ObsNames = [];

这会带来巨大的性能优势,因为子集分配从二次(针对行 ^ 2 绘制时为线性)变为线性(当针对行绘制时),其中行以丢失 ObsNames 的较小成本。

复制 DataSet 几乎是即时的,因此当与清除不需要的行结合使用时,也会带来巨大的性能提升,尽管不是最佳的解决方案(但不会丢失 ObsNames)。与删除 ObsNames 相比,性能大约慢 2 倍。当 ObsNames 也被删除时,这只会提高 2%。


支持数据

我使用一个小脚本来分配 150,000 x 25 混合字符串/整数/布尔数据集的子集行,生成以下时间测量值(秒)。

内存堆大小对性能没有显着影响,保持在 128 MB。

Subref 表示使用了用于子集分配的标准函数

  • ObsNames=[] 表示 ObsNames 被删除

  • 删除意味着复制了数据集并清除了不需要的行。

行、子引用、子引用&ObsName=[]、删除、删除&ObsName=[]

8000、4.19、2.06、4.81、4.72

32000, 57.61, 2.49, 5.26, 5.21

72000、390.72、3.21、6.09、6.03

128000, ?(*), 4.21, 7.25, 7.19

(*) 我放弃了评估这个值。基于对 rows^2 的线性外推,我猜想 2000 秒或半小时。


脚本

clear
load('data'); % load 'alldata' dataset
% alldata.Properties.ObsNames = []; % drop obsnames

tic;
x = ((1:4).^2.*8000);

for h = 1:length(x)
    start = toc;
    somedata = alldata(1:x(h),:);
%     somedata = alldata; 
%     somedata(x(h):end,:) = []; % drop unrequired obs
    t(h) = toc - start;
    clear somedata
    disp([x(h), t(h)]);


end
于 2010-09-29T13:46:09.900 回答