为 double table 创建索引以便快速访问
create index into double table for quick access
我有一个 table 如下:
1 2 3 4 5 6 . . . .
1 1 0 0 0 1 0 . . . .
2 0 0 1 1 1 1 . . . .
3 0 1 0 0 0 1 . . . .
4 1 0 0 0 0 0 . . . .
5 0 0 1 0 1 0 . . . .
. . . . . . . . . . .
. . .
. .
.
1,2,.... 是行和列的标题。我需要索引到 table 这意味着:
索引到 row1 的一个数组(向量)包含 1(=第 1 列,因为在 table 中,cell(1,1) 为真)。另一个索引到 row2 的数组包含 3,4,5,6(因为单元格 (2,3),(2,4),(2,5),(2,6) 为真)等等...
我读 Compact MATLAB matrix indexing notation and Use a vector as an index to a matrix 很准确,但我不能写代码让它工作。
假设您有以下矩阵
>> A = randi([0,1], [5,5])
A =
1 0 1 1 1
1 0 1 0 1
1 1 1 1 0
0 1 1 0 1
0 0 0 1 0
您可以通过
分别找到每一行的向量
>> find(A(1,:))
ans =
1 3 4 5
如果你想收集这些向量,你需要决定你想以什么样的结构收集它们。
由于每个结果数组的大小不同,您可以使用元胞数组。
首先,您的示例数据并不是真正的 table,所以让我们任意生成一个:
T = table({'a' 'a' 'a' 'b' 'b'}.',{'X' 'Y' 'Z' 'X' 'Z'}.',(1:5).',...
'VariableNames',{'UserId','productId','Rating'});
接下来,我们将所有 'key' 列转换为分类数组:
T.UserId = categorical(T.UserId);
T.productId = categorical(T.productId);
然后我们使用这个分类数组来交叉制表 table:
cross_T = crosstab(T.UserId,T.productId)
现在我们寻找新矩阵中的所有 1
:
[r,c] = find(cross_T);
并使用 arrayfun
按行收集它们:
% a function to return all 1 in row
row = @(x) c(r==x).';
% preform on all rows
r = arrayfun(row,1:size(cross_T,1),'UniformOutput',false).';
所以我们得到元胞数组 r
:
作为输出
r =
[1x3 double]
[1x2 double]
并查找我们写的特定用户的数据:
>> r{2}
ans =
1 3
如果你想让它更具可读性,你可以转换成结构数组:
s = cell2struct(r,categories(T.UserId))
那么 s
的输出将是:
s =
a: [1 2 3]
b: [1 3]
我有一个 table 如下:
1 2 3 4 5 6 . . . .
1 1 0 0 0 1 0 . . . .
2 0 0 1 1 1 1 . . . .
3 0 1 0 0 0 1 . . . .
4 1 0 0 0 0 0 . . . .
5 0 0 1 0 1 0 . . . .
. . . . . . . . . . .
. . .
. .
.
1,2,.... 是行和列的标题。我需要索引到 table 这意味着: 索引到 row1 的一个数组(向量)包含 1(=第 1 列,因为在 table 中,cell(1,1) 为真)。另一个索引到 row2 的数组包含 3,4,5,6(因为单元格 (2,3),(2,4),(2,5),(2,6) 为真)等等...
我读 Compact MATLAB matrix indexing notation and Use a vector as an index to a matrix 很准确,但我不能写代码让它工作。
假设您有以下矩阵
>> A = randi([0,1], [5,5])
A =
1 0 1 1 1
1 0 1 0 1
1 1 1 1 0
0 1 1 0 1
0 0 0 1 0
您可以通过
分别找到每一行的向量>> find(A(1,:))
ans =
1 3 4 5
如果你想收集这些向量,你需要决定你想以什么样的结构收集它们。
由于每个结果数组的大小不同,您可以使用元胞数组。
首先,您的示例数据并不是真正的 table,所以让我们任意生成一个:
T = table({'a' 'a' 'a' 'b' 'b'}.',{'X' 'Y' 'Z' 'X' 'Z'}.',(1:5).',...
'VariableNames',{'UserId','productId','Rating'});
接下来,我们将所有 'key' 列转换为分类数组:
T.UserId = categorical(T.UserId);
T.productId = categorical(T.productId);
然后我们使用这个分类数组来交叉制表 table:
cross_T = crosstab(T.UserId,T.productId)
现在我们寻找新矩阵中的所有 1
:
[r,c] = find(cross_T);
并使用 arrayfun
按行收集它们:
% a function to return all 1 in row
row = @(x) c(r==x).';
% preform on all rows
r = arrayfun(row,1:size(cross_T,1),'UniformOutput',false).';
所以我们得到元胞数组 r
:
r =
[1x3 double]
[1x2 double]
并查找我们写的特定用户的数据:
>> r{2}
ans =
1 3
如果你想让它更具可读性,你可以转换成结构数组:
s = cell2struct(r,categories(T.UserId))
那么 s
的输出将是:
s =
a: [1 2 3]
b: [1 3]