arrays - concatenate - convertir de string a numero matlab
¿Cómo reemplazar todo tipo de "cadena" por tipo "char" en una matriz de celdas? (4)
A partir de MATLAB R2017b puede usar conversstringstochars:
[test{:}] = convertStringsToChars(test{:});
Contexto
En R2016b, MATLAB introdujo un nuevo tipo de datos de string , además del tipo de datos de char habitual. Hasta ahora, todo bien, pero ahora me está dando muchos problemas con la caja de herramientas JSONlab que estoy usando.
Por ejemplo, en R2015b, loadjson
devuelve una matriz de caracteres de celda 1x3:
dd = loadjson(''["Titi", "Toto", "Tata"]'')
dd =
''Titi'' ''Toto'' ''Tata''
Pero en R2018a, loadjson
devuelve una matriz de cadena 1x3:
dd = loadjson(''["Titi", "Toto", "Tata"]'')
dd =
1×3 cell array
{["Titi"]} {["Toto"]} {["Tata"]}
Problema
Por no tener que cambiar mi código en todas partes, me gustaría parchear la rutina loadjson
para reemplazar todos string
tipos de string
que puede devolver con tipos de caracteres. Por ejemplo, en la siguiente matriz de celdas:
test = { ''hello'', "world", 0.3; ''how'', ''are'', "you"}
test =
2×3 cell array
{''hello''} {["world"]} {[0.3000]}
{''how'' } {''are'' } {["you" ]}
Me gustaría reemplazar todas las cadenas:
cellfun(@isstring, test)
ans =
2×3 logical array
0 1 0
0 0 1
¿Hay alguna forma de hacerlo rápidamente (es decir, sin recorrer todos los elementos)?
PD: Sé de jsondecode y jsonencode para reemplazar JSONLab en el futuro, pero hasta ahora solo quiero parchear las cosas rápidamente.
Otra solución, discutida en el blog UndocumentedMATLAB , es la función "semi-documentada" de controllib.internal.util.hString2Char
. Así es como lo usas:
test = { ''hello'', "world", 0.3; ''how'', ''are'', "you"};
fixed_test = controllib.internal.util.hString2Char(test);
fixed_test =
2×3 cell array
{''hello''} {''world''} {[0.3000]}
{''how'' } {''are'' } {''you'' }
De acuerdo con la publicación del blog, esta función recursiva a través de la entrada, por lo que funciona incluso en una situación como esta:
test = {"target1", struct(''field'',{123,''456'',"789"})};
ft = controllib.internal.util.hString2Char(test);
{ft{2}.field}
ans =
1×3 cell array
{[123]} {''456''} {''789''}
Echa un vistazo a la publicación del blog para algunas advertencias.
Puede usar cellfun
, pero tiene más o menos el mismo rendimiento que un bucle:
test = {''hello'', "world", 0.3; ''how'', ''are'', "you"};
ind = cellfun(@isstring, test);
test(ind) = cellfun(@char, test(ind), ''UniformOutput'', false)
Puede usar cellstr
(confusamente, a pesar de que "str" sugiera cadenas ) para convertir cadenas en arrays de caracteres sin bucles ni cellfun
... los documentos indican lo siguiente:
C = cellstr(A)
convierteA
en una matriz de celdas de vectores de caracteres . La matriz de entradaA
puede ser una matriz de caracteres, una matriz categórica o, comenzando en R2016b, una matriz de cadena.
test = {''hello'', "world", 0.3; ''how'', ''are'', "you"}; % multi-type test cell array
ind = cellfun(@isstring, test); % indexing for string type items
test(ind) = cellstr(test(ind)) % char-ify the strings!
Una nota de rendimiento cellfun
para verificaciones de clase
En las respuestas tanto mías como de Luis, cellfun
se usa para determinar qué elementos son cadenas. Puede mejorar el rendimiento de cellfun
para esta tarea ...
Según los documentos de cellfun
, hay algunas opciones de matriz de caracteres que son mucho más rápidas que sus homólogos de función-manejo. Para la indexación de isstring
, es probable que sea mucho más rápido ejecutar el primero de estos:
% rapid
ind = cellfun(''isclass'', test, ''string'');
% akin to looping
ind = cellfun(@isstring, test);
Tienen la misma salida, en una prueba simple veo una mejora de velocidad de 4x:
% Create large test array of random strings
c = cell(100,1000);
c = cellfun(@(x) string(char(randi([65,122],1,10))), c, ''uni'', 0);
% Create functions for benchmarking
f=@()cellfun(''isclass'', c, ''string'');
g=@()cellfun(@isstring,c);
% Timing on MATLAB R2017b
timeit( f ) % >> 0.017sec
timeit( g ) % >> 0.066sec