Extracting numeric values from character array

Hi, I have a character array "coords" (containing 3D coordinates), which looks something like this:
val =
'[ 48. -24. 48.]'
'[ 50. -22. 58.]'
'[ 48. -20. 50.]'
I would like to find the index of a specific coordinate, something like:
find(coords == [50 -22 58])
How do I do that? Transforming coords as follows:
coords_num = str2double(coordinates)
just leads to:
coords_num = NaN

 Respuesta aceptada

Stephen23
Stephen23 el 16 de Sept. de 2018
Editada: Stephen23 el 16 de Sept. de 2018
This is easy with sscanf:
>> coords = ['[ 48. -24. 48.]';'[ 50. -22. 58.]';'[ 48. -20. 50.]';'[ 49. -23. 52.]']
coords =
[ 48. -24. 48.]
[ 50. -22. 58.]
[ 48. -20. 50.]
[ 49. -23. 52.]
>> mat = reshape(sscanf(coords.','[%f%f%f]'),3,[]).' % convert to numeric
mat =
48 -24 48
50 -22 58
48 -20 50
49 -23 52
>> idx = all(mat==[50,-22,58],2) % match row
idx =
0
1
0
0
>> find(idx)
ans = 2

7 comentarios

MiauMiau
MiauMiau el 26 de Sept. de 2018
Editada: MiauMiau el 26 de Sept. de 2018
Hi Stephen - I have a question. I realize that when I use mat = reshape(sscanf(coords.','[%f%f%f]'),3,[]).' the original coords char-array had dimensions of 2044 x 16 char, but mat has now only 284 rows (it is 284 x 3) - why is that? Thank you again
Stephen23
Stephen23 el 27 de Sept. de 2018
Editada: Stephen23 el 27 de Sept. de 2018
"why is that?"
Probably because at some point the char data did not match the format string, and so sscanf stopped parsing the char array at that point. Have a look at the 284th and 285th rows, and see if they matche your description.
Please upload your original char array in a .mat file, by clicking the paperclip button.
MiauMiau
MiauMiau el 27 de Sept. de 2018
Thanks - I have attached it to the original question.
Stephen23
Stephen23 el 27 de Sept. de 2018
Editada: Stephen23 el 27 de Sept. de 2018
@MiauMiau: so I guess you had a look and found the same bug in your data that I found, on row 284:
>> coords(283:290,:)
ans =
[ 24. -30. 58.]
[58. -4. 34.]
[ 28. -24. 74.]
[ 34. -32. 52.]
[ 46. -24. 42.]
[ 46. -22. 42.]
[ 42. -26. 60.]
[ 34. -22. 66.]
Row 284 is padded with space characters, which the sscanf format string cannot match, so it stops. The solution is to either:
  • fix the code that creates that char array, or
  • remove trailing space characters. This will probably require reshaping to a char vector, e.g.:
>> str = reshape(coords.',1,[]);
>> str = regexprep(str,'] +[',']['); % remove trailing spaces
>> mat = reshape(sscanf(str,'[%f%f%f]'),3,[]).' % convert to numeric
mat =
16 -30 66
44 -36 58
16 -28 66
14 -28 66
16 -32 66
14 -30 66
28 -32 56
... lots of rows here
52 -8 44
52 -12 44
48 -14 42
50 -20 48
52 -20 50
52 -20 48
48 -14 46
52 -14 42
48 -16 46
48 -20 46
>> size(mat)
ans =
2044 3
MiauMiau
MiauMiau el 27 de Sept. de 2018
Not exactly a bug since these are euclidean coordinates and in this line the y coordinates has only one digit. Anyway, I can't change the original code - what do you mean by your second comment? Thanks
Stephen23
Stephen23 el 27 de Sept. de 2018
Editada: Stephen23 el 27 de Sept. de 2018
"Not exactly a bug since these are euclidean coordinates and in this line the y coordinates has only one digit. "
Nowhere in my comment did I say that the bug is due to the number of digits. As I wrote, the bug is due to the trailing space characters, which means that this line is formatted differently to all other rows of that char array. It is a bug in that data because that row is formatted differently to all of the others: it has trailing space characters, which none of the other rows do. Nothing to do with digits at all. For example, this works perfectly:
[ 24. -30. 58.]
[ 58. -4. 34.]
[ 28. -24. 74.]
proving that the bug has nothing to do with how many digits any number has.
If you look at that row carefully and compare with the other rows, you will see that each of the three numbers is missing exactly one leading space character. If you add in each of those missing leading space characters, you get numbers that align with all of the other rows and without any trailing spaces required. So there is definitely something buggy about that row!
"what do you mean by your second comment?"
Do you mean my second suggestion for how to deal with that bug in your data? Well, I thought that my code would make that reasonably clear, but here is a step-by-step explanation of my suggestion:
  • "remove trailing space characters. This will probably require reshaping to a char vector:"
Lets have a look at just the rows 283 to 285:
>> tmp = coords(283:285,:)
tmp =
[ 24. -30. 58.]
[58. -4. 34.]
[ 28. -24. 74.]
Check that row yourself: does it have three trailing space characters? Answer: yes it does. Now lets reshape those three rows into a vector:
>> vec = reshape(tmp.',1,[])
vec =
[ 24. -30. 58.][58. -4. 34.] [ 28. -24. 74.]
^^^ Oh no! The trailing space characters!
How can we deal with those pesky trailing space characters? How about we get rid of them? How could we do that, considering that we don't know where they are, or how many there might be? A regular expression would lets us do that. See my previous comment to see one way to do that.
MiauMiau
MiauMiau el 27 de Sept. de 2018
Many thanks for all your time and help, that is really very helpful!

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 16 de Sept. de 2018
T = regexp( regexprep(coordinates, '\[|\]', ''), 'split') ;
coords_num = str2double(T) ;

3 comentarios

Thank you very much, but I get this error:
T = regexp( regexprep(coordinates, '\[|\]', ''), 'split') ;
Error using regexprep
The 'STRING' input must be either a char row vector, a cell array of char row vectors, or
a string array.
Why is that? If its of any help, it says "2092 x 16 char" (2092 coordinates stored).
Walter Roberson
Walter Roberson el 16 de Sept. de 2018
Use cellstr(coordinates) where I had coordinates()
MiauMiau
MiauMiau el 17 de Sept. de 2018
Thank you - just for others to know: I tried using cellstr on coordinates, but that let to an empty array T. The answer of Stephen works however - many thanks to both

Iniciar sesión para comentar.

Etiquetas

Preguntada:

el 16 de Sept. de 2018

Comentada:

el 27 de Sept. de 2018

Community Treasure Hunt

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

Start Hunting!

Translated by