MATLAB and cell array handling in for loop

17,295

Solution 1

Though sage's answer above will work, it's not really proper, or efficient use of Matlab's cell arrays. You can eliminate many of the extraneous function calls by using proper cell array content indexing. you can address any element of a cell array in two ways - () or {}. () gets the cell, still as a cell. {} however, pulls out the contents of the cell, in it's base type.

So sensors(1, end) is a 1x1 cell array, but sensors{1, end} is a 1x29 char string.

For your problem:

numRows = size(sensors, 1);
for rowIdx = 1:numRows;
    sensorName = sensors{rowIdx, end};
    sql = ['select * from data where ID = ' num2str(sensors{rowIdx, 1})];
    ...
end

You could also eliminate the num2str() call if you fetched the sensor ID as a char instead of a number - i.e. if your original DB fetch that populated sensors did the cast.

In addition, if you weren't further querying from the DB, you could vectorize this whole thing, but I'm afraid I'm away from my Matlab machine, so I can't build that one off the top of my head.

Solution 2

This is a bit verbose because I explained inline, but here is how I would do it in MATLAB:

[nRows, nCols] = size(sensors); % get the numbers of rows and columns
for currRow = 1:nRows
    % The following selects the current row and the first column, gets the
    % ID, and then converts it to a number and then a string
    firstColAsStr = num2str(cell2mat(sensors(currRow,1)));

    % The following selects the current row and the last column, known to
    % be a cell containing a string, and converts directly to a character
    % array, aka a string
    lastColAsStr = char(sensors(currRow,nCols));

    % Insert here what you want to do with the items (e.g., your SQL
    % commands)

end
Share:
17,295
aXon
Author by

aXon

Updated on June 17, 2022

Comments

  • aXon
    aXon over 1 year

    I am new to MATLAB and would like to extract data from a cell array that I got from my database:

    sensors = 
    
    [ 1]    [23]    [1]    [  0]    [0.1000]            [1x29 char]
    [ 2]    [23]    [1]    [120]    [0.1000]            [1x43 char]
    [ 3]    [23]    [1]    [120]    [0.1000]            [1x42 char]
    [ 4]    [23]    [1]    [ 15]    [0.1000]    'Air Temp Grey Box'
    [ 5]    [23]    [1]    [120]    [0.1000]            [1x34 char]
    [ 6]    [23]    [1]    [120]    [0.1000]            [1x33 char]
    [ 7]    [23]    [1]    [120]    [0.1000]    'Pool Water Temp'  
    [ 8]    [23]    [2]    [  0]    [0.1000]            [1x28 char]
    [ 9]    [23]    [1]    [ 30]    [0.1000]            [1x22 char]
    [10]    [23]    [1]    [ 30]    [0.1000]            [1x22 char]
    [11]    [23]    [1]    [ 30]    [0.1000]            [1x21 char]
    [12]    [23]    [1]    [ 15]    [0.1000]            [1x20 char]
    [13]    [23]    [1]    [ 15]    [0.1000]            [1x23 char]
    [14]    [23]    [1]    [ 30]    [0.1000]            [1x22 char]
    [15]    [23]    [1]    [ 15]    [0.1000]    'Ground Air '      
    [16]    [23]    [1]    [  5]    [0.1000]    'Boiler Cold Water'
    [17]    [23]    [1]    [  5]    [0.1000]    'Boiler Hot Water' 
    [18]    [23]    [1]    [  5]    [0.1000]    'Boiler CH Flow'   
    [19]    [23]    [1]    [  5]    [0.1000]    'Boiler CH Return' 
    

    Now I would like to grab the first column, i.e. the numbers 1 to 19 as well as the respective names in the last column and use them in a for loop, e.g.:

    for ID=xxxx
        str = num2str(ID);
        SQLcommand = strcat('SELECT FROM data where ID=',str);
        answer = database.exec(SQLcommand);
        ......
    end
    

    I have tried several different attempts but never succeeded in getting just one of the elements.

    Help is appreciated :), thanks in advance. axon

  • sage
    sage almost 13 years
    I index cell arrays with parens. The last item does not work for me in MATLAB, but this does: allIds = cell2mat(sensors(:,1)); The similar line works for the last column, but pads the strings with ' ': allIds = char(sensors(:,end));
  • aXon
    aXon almost 13 years
    This did it for me: for ctr = 1:length(sensors); idStr = num2str(sensors{ctr,1}); nameStr=sensors{ctr,6}; end; This way I can grab the info that I need, thanks :) The second one works as well, giving me both things in an array of double and an array of chars :)
  • mtrw
    mtrw almost 13 years
    @sage - that syntax is a lot nicer. Unfortunately it doesn't work in Octave, ah well.
  • mtrw
    mtrw almost 13 years
    @aXon - see sage's answer, it turns out Matlab can use parentheses.
  • zellus
    zellus almost 13 years
    @mtrw: If you don't mind, I did edit your post concerning cell indexing.
  • mtrw
    mtrw almost 13 years
    @zellus - That doesn't work, at least for me. I'm running Octave 3.2.4, and sensors{1,1} returns the first row the cell array.
  • mtrw
    mtrw almost 13 years
    @zellus - Can you confirm the change you made works? Otherwise I'll go ahead and change it back.
  • zellus
    zellus almost 13 years
    @mtrw: Changes successfully tested on R2008b.
  • mtrw
    mtrw almost 13 years
    @zellus - I realize the change you made would work in MATLAB. However, it doesn't work in Octave. I thought I was clear in saying "this is how you'd do it in Octave, it might work in MATLAB." sage wrote a perfectly good answer for MATLAB, I don't see why that information needs to be repeated.
  • zellus
    zellus almost 13 years
    @mtrw: My bad. I apologize for the modifications made. But I suggest changing the 'MATLAB' part at the end of your post. The code does not work in MATLAB, at least not in R2008b.
  • Marc
    Marc almost 13 years
    Not really the most efficient use of cell arrays. You forgot about {} indexing.
  • aXon
    aXon almost 13 years
    Thanks to you as well. The data that I fetch from the DB is unaltered and therefore the sensor ID is a number instead of a string or char array. Thanks for explaining the difference between the brace types.