Matlab将柱状数据转换为数据数组

Matlab将柱状数据转换为数据数组,matlab,cell-array,n-dimensional,Matlab,Cell Array,N Dimensional,是否有一种简单的方法(理想情况下没有多个for循环)根据Matlab中的一组类别对值向量进行分组 我有表格中的数据矩阵 CATEG_A CATEG_B CATEG_C ... VALUE 1 1 1 ... 0.64 1 2 1 ... 0.86 1 1 1 ... 0.74 1 1 2

是否有一种简单的方法(理想情况下没有多个for循环)根据Matlab中的一组类别对值向量进行分组

我有表格中的数据矩阵

CATEG_A    CATEG_B   CATEG_C  ...   VALUE

   1          1        1      ...   0.64
   1          2        1      ...   0.86
   1          1        1      ...   0.74
   1          1        2      ...   0.56
  ...
等等

我想要的是一个N维数组

 all_VALUE( CATEG_A, CATEG_B, CATEG_C, ..., index ) = VALUE_i
当然,可能有任意数量的值具有相同的类别组合,因此
size(end)
将是最大类别中的值的数量,而剩余的项将填充
nan

或者我会很高兴

 all_VALUE { CATEG_A, CATEG_B, CATEG_C, ... } ( index )
i、 e.向量的细胞阵列。我想这有点像创建一个透视表,但是有n维,不计算
平均值

我在帮助中找到了这个函数

A = accumarray(subs,val,[],@(x) {x})

但我不知道如何让它做我想要的

这也是一个混乱,但有效。它以ND数组的方式运行

X = [1        1        1        0.64
     1        2        1        0.86
     1        1        1        0.74
     1        1        2        0.56]; %// data
N = size(X,1); %// number of values
[~, ~, label] = unique(X(:,1:end-1),'rows'); %// unique labels for indices
cumLabel = cumsum(sparse(1:N, label, 1),1); %// used for generating a cumulative count
    %// for each label. The trick here is to separate each label in a different column
lastInd = full(cumLabel((1:N).'+(label-1)*N)); %'// pick appropriate values from 
    %// cumLabel to generate the cumulative count, which will be used as last index
    %// for the result array
sizeY = [max(X(:,1:end-1),[],1) max(lastInd)]; %// size of result
Y = NaN(sizeY); %// initiallize result with NaNs
ind = mat2cell([X(:,1:end-1) lastInd], ones(1,N)); %// needed for comma-separated list
Y(sub2ind(sizeY, ind{:})) = X(:,end); %// linear indexing of values into Y
示例中的结果是以下4D阵列:

>> Y
Y(:,:,1,1) =
    0.6400    0.8600
Y(:,:,2,1) =
    0.5600       NaN
Y(:,:,1,2) =
    0.7400       NaN
Y(:,:,2,2) =
   NaN   NaN

这是一片混乱,但这里有一个解决方案

[U,~,subs] = unique(X(:,1:end-1),'rows');

sz = max(U);
Uc = mat2cell(U, size(U,1), ones(1,size(U,2)));
%// Uc is converted to cell matrices so that we can take advantage of the {:} notation which returns a comma-separated-list which allows us to pass a dynamic number of arguments to functions like sub2ind

I = sub2ind(sz, Uc{:});

G = accumarray(subs, X(:,end),[],@(x){x});

A{prod(max(U))} = [];  %// Pre-assign the correct number of cells to A so we can reshape later
A(I) = G;
reshape(A, sz)
对于示例数据(忽略
s),返回:

A(:,:,1) = 

    [2x1 double]    [0.8600]


A(:,:,2) = 

    [0.5600]    []

其中
A(1,1,1)
[0.74;0.64]

哇-哇!!这真是太神奇了。工作完美。我将花一些时间研究你的代码。Accumarray功能非常强大。您真的需要
sz
作为单元阵列吗?你只是把它当作
[sz{:}]
@SanjayManohar
Accumaray
绝对是非常强大的。StackOverflow中有很多粉丝-:-)很好,我一开始试过了,但是每个标签部分的累积计数都被卡住了@SanjayManohar这可能是更好的解决方案…@丹,谢谢。您的解决方案实际上在内存方面更有效,因为它提供了单元数组而不是N-D arrayPerfect。还感谢您向我介绍
unique
的第三个输出。而且,
ind
最后告诉每个项目“去哪里”,这真是太好了。