eyes enberg
eyes enberg

Reputation: 586

Trying to format a pre-existing table in a specific way

I have a data set with dimensions 3500 x 20.

What I want to do is firstly remove the first 2 columns from it, leaving me with 18 columns.

I want to now replace each 3 columns by a column of their mean. For example, after deleting first 2 columns, take an average of new columns 1-3 and store that as a column in the new matrix, then take an average of columns 4-6 and store that as the next column in the new matrix, then take an average of columns 7-10 and store that as the next column .....

This is my attempt so far:

function newMatrix = preprocess(originalMatrix)
nrows = size(originalMatrix, 1); % number of rows of original table (3500)
ncolsOriginal = size(originalMatrix,2); % number of cols of original table (20)
ncolsNew = (ncolsOriginal - 2)/3 % number of cols of the new matrix we want (18/3 = 6)
originalMatrix = table2array(originalMatrix(:,3:ncolsOriginal)) % convert original table to matrix
newMatrix = zeros(nrows, ncolsNew) % initialise new matrix
for i = 1:ncolsNew:3
    newMatrix{:,i} = mean(originalMatrix(i:i+2)'); % calculate mean of 3 sets of columns at a time and store it as a single column in new matrix. 
end
end

On the last line (right before the penultimate 'end') I get this error:

Cell contents assignment to a non-cell array object.

Does anyone know why this is the case? If anyone can give me some pointers it would be highly appreciated.

Upvotes: 1

Views: 44

Answers (2)

Manja
Manja

Reputation: 31

I hope this helps.

function newMatrix = preprocess(originalMatrix)
    matrixTmp = originalMatrix(:,3:20);

    [rows, cols] = size(matrixTmp);
    newCols = cols/3;
    newMatrix = zeros(rows, newCols);

    count = 1;
    for i=1:3:cols
        tmp = matrixTmp(:,i:i+2);
        newMatrix(:,count) = mean(tmp, 2);
        count = count + 1;
   end
end

Upvotes: 1

hbaderts
hbaderts

Reputation: 14316

The problem in your code is that you use curly braces {} for indexing within the for loop. These are reserved for cell arrays. For normal matrices, you have to use normal parentheses (). Then your code should work (though I didn't verify that).

However, this problem can easily be vectorized by reshapeing the original matrix into a space, where you can just take the mean along one dimension.

Our goal will be to make a 3D-matrix, where the first dimension (columns) are still the same columns. We choose to take the means along the second dimension - so it should be length 3 and contain the 3 columns which should be averaged. Finally, the third dimension contains the 6 resulting columns. We can create this matrix by

reshape(originalMatrix,size(originalMatrix,1),3,[])

We can then easily take the mean along the second dimension:

mean(reshape(originalMatrix,size(originalMatrix,1),3,[]),2)

which leaves us with a 2000 x 1 x 6 matrix, which contains the desired results. To remove the size 1 dimension, we squeeze the matrix.

squeeze(mean(reshape(originalMatrix,size(originalMatrix,1),3,[]),2))

So the function becomes

function newMatrix = preprocess(oldMatrix)
    originalMatrix = table2array(originalMatrix(:,3:end))
    newMatrix = squeeze(mean(reshape(originalMatrix,size(originalMatrix,1),3,[]),2))
end

Upvotes: 2

Related Questions