提取大型Matlab数据集子集

时间:2010-09-29 01:02:52

标签: matlab dataset subset

引用和分配matlab数据集的子集似乎非常低效,并且可能像行一样扩展^ 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转换为boolean类型

以下子集分配:

somedata = alldata(1:m,:)
对于m = 10,000,

需要> 7秒;对于更大的m值,

需要大量的时间。绘图时间与m显示m ^ 2类型的关系,这是奇怪的,因为复制alldata几乎是瞬时的,就像使用sortrows和find这样的函数。事实上,读取原始的.csv数据文件比上面的m值大的分配要快。

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

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

我使用的是配备1.5Gb内存的双核机器,但是任务管理器报告使用的内存不足1Gb。

2 个答案:

答案 0 :(得分:2)

我以前曾使用MATLAB的dataset数组来处理大数据,遗憾的是它确实遇到了性能问题。我发现有助于加快速度的一件事就是清除observation names (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 = [];

答案 1 :(得分:0)

Amro建议清除观察名称:

ds.Properties.ObsNames = [];

这导致大量性能优势,因为子集分配从二次(对行^ 2绘制时为线性)变为线性(对行绘制时),行以较小的成本丢失ObsNames。

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


支持数据

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

内存堆大小在性能上没有显着差异,并且保持在128 MB。

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

  • ObsNames = []表示删除了ObsNames

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

Rows,subref,subref& ObsName = [],删除,删除& ObsName = []

8000,4.19,2.06,4.81,4.72

32000,57.61,2.49,4.26,6.21

72000,390.72,3.21,6.09,6.03

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

(*)我放弃了评估这个值。基于对行^ 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