Matlab数组有不同数据类型的列?

时间:2014-03-17 06:31:32

标签: arrays matlab struct vectorization cell-array

我想在MatLab中创建一个SQL样式的表,这意味着每一行都是一个观察,每一列都是一个字段。它全部是数字的,所以我应该能够将它保存在2D数组中,但为了节省空间,我需要一些字段比其他字段占用更少的比特。

有没有一种方法可以得到一个数组A,其中A(:,1)的类型为uint32,而A(:,2)的类型为uint8,例如?

我目前正在使用数组的数组来完成此操作,其中单元格数组中的每个单元格代表一列(作为nx1数组),然后我访问单个记录的值数组-样式。示例:要获取记录45的字段2,我使用A {2}(45)。问题是,这不是非常快速的,因为我无法对其进行矢量化以获得特定记录的所有字段(侧面问题:是否像A一样进行矢量化的方式{1:3}(45)?)。

1 个答案:

答案 0 :(得分:3)

简而言之,不,在Matlab中无法做到这一点。这与Matlab的基本数据类型的工作方式不一致。但那没关系。在Matlab中执行表格式工作的高效方法是使用类似于您已经获得的内容 - 包含列作为同类数组的单元格或其他复合类型 - 但更改代码以使用向量化的面向列的函数。

听起来你在询问如何在Matlab中构造一个类似于表的对象,使得具有异构类型的记录的字段在内存中是连续的,如C struct或传统的记录导向RDBMS表的物理布局。 Matlab的数据类型不能像那样工作。所有Matlab的原始数组都是同类型的,在内存中连续排列;所有异构类型都是由引用它们“包含”的基本数组的单元格,结构体,对象或其他复合类型构建的。

因此,有很多方法可以构建具有不同列类型的表,使用像您正在执行的单元格,或table,或滚动您自己的关系样式类。但它们都归结为将不同基元类型存储在单独的基本数组中的复合类型,因此它们都具有与基于单元格的实现相同的访问时间特征。您当前的“列数组”结构很好,并且是您在Matlab中表示数据的典型方式。其他实现将为您提供不同的语法和更强大的功能 - 这是使用它们的一个很好的理由 - 但它们的底层数据结构看起来非常像您已经拥有的。 (对于它的价值,@ Marcin提到的table数据类型听起来很棒:方便的语法和一组很好的功能。但它基本上是基于单元的解决方案的包装器,具有相同的性能特征。 )

Matlab不是用于迭代异构字段的单个“记录”并且一次只使用一个或几个,就像许多其他语言中的典型情况一样。要在Matlab中快速完成,您必须重新组织算法以跨列或其他基本数组的元素进行操作。这基本上就是“矢量化” 。你能行的;使用ismemberunique,索引映射,accumarray之类的东西,可以在惯用的Matlab代码中高效地完成各种关系式操作。你只需要改变你的方法。

替代

在Matlab中执行“表”的另一种方法是执行结构或单元格的数组,其中结构或单元格的每个字段都包含标量值。 (N col col表的M行是结构的M-long数组T,每个结构都有N个字段; T(i)获得第i行。)这将使您更快地访问个人“记录“因为它已经建成了。但它在速度和内存方面都很糟糕,因为每个记录的每个元素都存储在它自己的1×1原始数组中。 (例如,使用O(M*N)原始数组而不是O(N),M行乘N cols表结束。)并且您不能对该排列使用任何矢量化操作。

其他一些想法

如果您有任何字符串列,则可能需要构建一个或两个自定义字符串类型。 Matlab的基本字符串类型charcellstr是缓慢且占用大量内存的,并且不支持您可能希望对列执行的某些多态操作。

小心那些int类型。由于历史原因,Matlab的混合型算术的推广规则很奇怪。当双打混合时,双打变得狭窄,并且它们最终会“污染”他们传入的函数中的数据。这使得在实践中使用的内容比你预期的要少;你需要有他们的守卫代码。

(严格来说,你可以通过下载到MEX或Java并在那里编写所有代码来做连续记录样式的东西,但是那时你只是编写C或Java而不是Matlab,在这种情况下为什么要使用Matlab ?)

相关问题