Eli
Eli

Reputation: 83

create index into double table for quick access

I have a table as below:

  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,.... are title of rows and columns. I need to index into table this means that : one array (vector) that index into row1 that is contain 1 (=column 1 because in table cell(1,1) is true). another array that index into row2 that is contain 3,4,5,6 (because cells (2,3),(2,4),(2,5),(2,6) are true) and etc ...

I read Compact MATLAB matrix indexing notation and Use a vector as an index to a matrix with accuracy but I can not write code for it work.

Upvotes: 0

Views: 141

Answers (2)

EBH
EBH

Reputation: 10440

Since each of the result array is in different size, you could use cell array.
First your sample data is not really a table, so let's make an arbitrary one:

T = table({'a' 'a' 'a' 'b' 'b'}.',{'X' 'Y' 'Z' 'X' 'Z'}.',(1:5).',...
    'VariableNames',{'UserId','productId','Rating'});

Next, we will convert all the 'key' columns to categorical arrays:

T.UserId = categorical(T.UserId);
T.productId = categorical(T.productId);

Then we use this categorical arrays to cross-tabulate the table:

cross_T = crosstab(T.UserId,T.productId)

And now we look for all the 1 in the new matrix:

[r,c] = find(cross_T);

And use an arrayfun to collect them by row:

% 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).';

So we get as output the cell array r:

r = 
    [1x3 double]
    [1x2 double]

And to look for the data on specific user we write:

>> r{2}
ans =
     1     3

Is you want this to be more readable you can convert into structure array:

s = cell2struct(r,categories(T.UserId))

So then the output for s will be:

s = 
    a: [1 2 3]
    b: [1 3]

Upvotes: 1

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22215

Say you have the following 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

you can find the vector for each row separately, by doing

>> find(A(1,:))
ans =

   1   3   4   5

If you want to collect these vectors, you need to decide how in what kind of structure you want to collect them.

Upvotes: 0

Related Questions