Understanding Cell Array Indices
4 views (last 30 days)
Show older comments
I have a large cell array imported from a .csv file which contains numbers and strings. I am trying to use the index of a matching string to give me a row or column for the corresponding data. I am able to identify the string and it's "index" using the following:
TEXT={'103.9685,10:27:37,2016-02-03','103.9685,12:00:00,2016-01-03' '103.9685,11:27:37,2016-02-03' '103.9685,12:00:00,2016-02-03' };
%
ARRAY = cellfun(@(x)~isempty(strfind(x,'12:00:00')), TEXT);
%
INDICES = find(ARRAY(:) > 0
The challenge that I have is that this code gives me a single value index, at a value that doesn't make sense for either my number of rows or columns. Can somebody help me understand what this index value means, and how I might go about using it to find my row or column number that I'm originally looking for.
0 Comments
Accepted Answer
Guillaume
on 14 Dec 2017
Edited: Guillaume
on 14 Dec 2017
Sounds like you just picked code from somewhere without understanding what it does at all. All that code does is tell you the index of the strings in TEXT that contain '12:00:00', i.e, the 2nd and 4th one. It's made more obscure than necessary by the syntax inside the find,
INDICES = find(ARRAY); %no need for (:) or >
does exactly the same thing. And in recent matlab,
TEXT={'103.9685,10:27:37,2016-02-03','103.9685,12:00:00,2016-01-03' '103.9685,11:27:37,2016-02-03' '103.9685,12:00:00,2016-02-03' };
INDICES = find(contains(TEXT, '12:00:00'))
would be a lot simpler and clearer.
As for your question about finding row and column number, it's not very clear. Your cell array is a row vector and it contain char vectors also as row vectors, so everything is just one row. I'm going to assume you mean the location of the search string in each char array as the column and the index of which char array actually contains the string as the row, in which case:
TEXT = {'103.9685,10:27:37,2016-02-03','103.9685,12:00:00,2016-01-03' '103.9685,11:27:37,2016-02-03' '103.9685,12:00:00,2016-02-03' };
pattern = '12:00:00'
columns = cellfun(@(str) strfind(str, pattern), TEXT, 'UniformOutput', false);
rows = find(cellfun(@(col) ~isempty(col), columns));
rowcols = [rows; cell2mat(columns)]
1st row of rowcols is the row, 2nd row is the column
2 Comments
Guillaume
on 14 Dec 2017
I'm sorry to say but I don't think you actually understand what the code is doing.
[cellarray{:}] horizontally concatenates all the elements of cellarray. So it is equivalent to:
[cellarray{1}, cellarray{2}, cellarray{3}, ..., cellarray{end}]
Due to the rule of linear indexing, cellarray{1} is 'ncols', cellarry{2} is 'Bob', cellarray{3} is 1, which when concatenated to a char array becomes the character with ASCII code 1 (non-printed character), so in the end [cellarray{:}] is
'ncolsBob\1\4\7\3Jim\5\8Tom\3\6\9' %where I use \x to denote character with code x
In that char array, Bob is indeed at the 6th position.
cellfun(fun, cellarray) applies the function fun to each element of the cell array and returns the result in a matrix the same size and shape as cellarray. Now if we deconstruct the function @(x)~isempty(strfind(x, 'Bob'), the strfind search for 'Bob' in x and returns a vector of position. If 'Bob' is not found that vector will be empty. That vector is passed to isempty which thus returns true if 'Bob' is found, and false if not. That result is then negated by ~. Therefore, the cellfun returns a logical array the same size as the cell array which tells you if 'Bob' is found in each element (but not where in the element). The output of
cellfun(@(x)~isempty(strfind(x, 'Bob'), cellarray)
is thus the logical array
[0, 0, 0;
1, 0, 0;
0, 0, 0;
0, 0, 0;
0, 0, 0]
Applying find on that, which in the one output syntax returns linear indices, indeeds returns 2. The second element contains 'Bob'.
A reminder: linear indices go like this for the above array:
[1 6 11
2 7 12
3 8 13
4 9 14
5 10 15]
So, yes, the result you obtain do make sense.
I'm still not sure what result you want. If you want the row and column of which element of cellarray contains 'Bob' without caring for where in each element it is:
[row, column] = find(cellfun(@(x) ~isempty(strfind(x, 'Bob')), cellarray))
That is use the two output version of find.
More Answers (0)
See Also
Categories
Find more on Characters and Strings in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!