Understanding Cell Array Indices

4 Ansichten (letzte 30 Tage)
Bob Thompson
Bob Thompson am 14 Dez. 2017
Kommentiert: Guillaume am 14 Dez. 2017
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.

Akzeptierte Antwort

Guillaume
Guillaume am 14 Dez. 2017
Bearbeitet: Guillaume am 14 Dez. 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 Kommentare
Bob Thompson
Bob Thompson am 14 Dez. 2017
I do understand what the code is doing, though perhaps it is more bloated than necessary. Unfortunately, I cannot use 'contains' as I am running R2016a instead of R2016b or later. As an alternative method I have been using just the 'strfind' function, but this yields a similar single value index.
Index = strfind([cellarray{:}],'Bob');
Perhaps the generic example wasn't clear, I did just paste the "TEXT" array from another post on here without paying much attention to it. Consider the following array and index code. I am trying to find the index for 'Bob' so I can identify the column of data which relates to 'Bob'.
cellarray = {'ncols',3,'';
'Bob','Jim','Tom';
1,2,3;
4,5,6;
7,8,9};
Index = strfind([cellarray{:}],'Bob');
ARRAY = cellfun(@(x)~isempty(strfind(x,'''MACH''')), datain);
INDICES = find(ARRAY);
Using the above gives the results of Index = 6 and Indices = 2, which does not give me a clear row column answer that I would expect and want to utilize. Additionally, I would expect that these two answers would agree, but they do not. I could understand this lack of agreement if Index is technically identifying the index of 'Bob' within the specific cell, rather than the entire array, but either way the results from both functions do not make sense.
Is that more clear?
Guillaume
Guillaume am 14 Dez. 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.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Characters and Strings finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by