引用和分配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。
答案 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