How do I access and edit a cell array using a double for indexes?

Hi everyone,
working on some data, I came across a topic I avoided since starting with Matlab half a year ago. It's about indexing, accessing and editing data in a cell array. For example I got a 300000x1 cell array 'results' filled with 50 city names stored in a 50x1 cell named 'cities'. So each cell of 'results' contains one of the 50 names. What I want to do, is replacing the names in 'results' with their position/index in 'cities', in order to turn it into a double array and to save computing time for following tasks. I tried the following.
for k=1:length(cities)
cells = find(ismember(results,cities(k,1)));
results(cells) = k;
end;
Wich just produces the error Conversion to cell from double is not possible. I tried this because cells contains the indexes in 'results' of the just called city (cities(k,1)) And i thought this way I could also edit the values, which is obviously not possible.
My workaround would be the combination of 2 for loops, which is, regarding the length of the 'results' arrays, pretty slow.
for k=1:length(cities)
cells = find(ismember(results,cities(k,1)));
for n=1:length(cells)
results{cells(n,1),1} = num2str(k); %num2str because otherwise k-loop would not work for k>=2
end;
end;
% cellfun(@str2num, results(:,1)) in the end to convert the strings to num
But how do I get the first solution to work? How to I access the cell array correctly with a double as indexing? And is the first way really faster than the 'loop-Way'?
Many thanks in advance!
Best regards!

 채택된 답변

Stephen23
Stephen23 2015년 11월 26일
편집: Stephen23 2015년 11월 26일
Note that you cannot "turn it into a double array": you can only reassign variable names to a new variable, but this would completely replace the old cell array.
The basic problem with your first loop is there is some confusion about cell array indexing: you try to allocate a double to a cell, thus the error. If you had put the double inside the cell then it would have worked:
for k = 1:numel(cities)
idx = ismember(results,cities(k,1));
results{idx} = k;
end
Cell array indexing in a nutshell:
  • parentheses () refer to the cells themselves.
  • curly braces {} refer to the contents of the cells.
So given that results is a cell array, and k is a double, your line results(cells) = k tries to allocate the double to the cell itself, whereas what you needed to do was allocate it to the contents of the cell using curly braces: results{cells} = k.
Easiest Solution
The easiest solution is to use the second output from ismember:
>> cities = {'london','berlin','paris'};
>> results = {'berlin','paris','paris','london','paris','london','berlin','london'};
>> [~,LocB] = ismember(results,cities)
LocB =
2 3 3 1 3 1 2 1
Alternative Solution
If your really want to do this in a loop:
>> out = nan(1,numel(results));
>> for k = 1:numel(cities), out(strcmp(results,cities{k})) = k; end
>> out
out =
2 3 3 1 3 1 2 1
Note that we loop over the smaller cell array cities, not the larger one results, and we use logical indexing rather than using slow find.

댓글 수: 1

Mr Anderson
Mr Anderson 2015년 11월 26일
편집: Mr Anderson 2015년 11월 26일
thanks for your answer! but if i try your solution, this error pops up
The right hand side of this assignment has too few values to satisfy the left hand side.
EDIT:
Creating a completely new array would be fine for me, but even if doing so, i still would not know how to use the logical, or double index correctly :(
EDIT2
Thank you very much! I didnt even think about strcmp, but its the easiest way, since strcmp compares the cities{k} string with the whole results array and creates the logical to access the cells or to create a new array out
Thank you so much for helping me! :)

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Thorsten
Thorsten 2015년 11월 26일
편집: Thorsten 2015년 11월 26일
results2 = cellfun(@(c) find(ismember(cities, c)), results);

댓글 수: 1

If i try this, this error shows up
Error using cellfun Non-scalar in Uniform output, at index 15, output 1. Set 'UniformOutput' to false

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

질문:

2015년 11월 26일

댓글:

2018년 1월 2일

Community Treasure Hunt

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

Start Hunting!

Translated by