numero convertir convert concatenate array arrays string matlab type-conversion cell-array

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) convierte A en una matriz de celdas de vectores de caracteres . La matriz de entrada A 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