【问题标题】:Extract large Matlab dataset subsets提取大型 Matlab 数据集子集
【发布时间】:2011-04-18 14:25:54
【问题描述】:

引用和分配 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 个整数类型转换为布尔类型

以下子集赋值:

somedata = alldata(1:m,:)

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

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

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

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

【问题讨论】:

  • 您能给我们一个您的数据库的快照示例吗?只需几行,所有列都可以。
  • 嗯——数据是……敏感的。它主要由一个观察 id、几个作为字符串保存的参考 id、几个日期字段(存储在字符串中,因为我还没有开始使用它们)、两个布尔列、几个整数字段(大多数单个整数)和一个一大堆其他字符串字段(通常少于 20-30 个字符。如果有帮助,我可以给你变量类型的实际序列?
  • 以下是其他人遇到相同问题的示例:mathworks.com/matlabcentral/newsreader/view_thread/…

标签: matlab dataset subset


【解决方案1】:

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

【讨论】:

    【解决方案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 = [];
    

    【讨论】:

    • 感谢 Amro - 将尝试一下。更笼统地说,有什么关于替代结构以提高性能的建议或建议?
    • 理论上你应该可以使用矩阵和元胞数组做所有事情,只是有点笨拙..
    猜你喜欢
    • 2010-12-28
    • 2017-10-08
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多