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

The*_*ous 5 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)那样的矢量化方法?).

And*_*nke 3

简而言之,不,在 Matlab 中不可能做到这一点。它与 Matlab 基本数据类型的工作方式不一致。但没关系。在 Matlab 中执行表式工作的高性能方法是使用类似于您已经获得的 \xe2\x80\x93 单元格或其他复合类型,其中包含列作为同构数组 \xe2\x80\x93 ,但将代码更改为对它们使用向量化的面向列的函数。

\n\n

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

\n\n

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

\n\n

Matlab 并不是为迭代具有异构字段的单个“记录”并一次处理一个或多个记录而构建的,这在许多其他语言中是典型的。为了快速使用 Matlab,您必须重新组织算法以跨列或其他原始数组的元素进行操作。从根本上来说,这就是“矢量化。你能行的; 各种关系式操作都可以在惯用的 Matlab 代码中高效完成,使用ismemberunique、索引映射、accumarray等。你只需要改变你的方法。

\n\n

备择方案

\n\n

在 Matlab 中制作“表”的另一种方法是制作结构体或单元格数组,其中结构体或单元格的每个字段都保存一个标量值。(M 行 N 列表是一个 M 长的T结构数组,每个结构有 N 个字段;T(i)获取第 i 行。)这将使您更快地访问单个“记录”,因为它已经构造好了。但它在速度和内存方面都很糟糕,因为每个记录的每个元素都存储在它自己的 1×1 原始数组中。(例如,一个 M 行乘 N 列的表最终使用O(M*N)原始数组而不是O(N)。)并且您不能在该排列上使用任何向量化操作。

\n\n

其他一些想法

\n\n

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

\n\n

小心那些int类型。由于历史原因,Matlab 对混合类型算术的提升规则很奇怪。双精度数在混合时会缩小为整数,并且最终可能会“污染”它们传递到的函数中的数据。这使得整数在实践中没有你想象的那么有用;你需要在它们周围有保护代码。

\n\n

(严格来说,您可以通过下降到 MEX 或 Java 并在那里编写所有代码来完成连续记录样式的内容,但是您只是编写 C 或 Java 而不是 Matlab,在这种情况下为什么要使用 Matlab 呢?)

\n