Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何有效地将3xn坐标字符串读入matlab数组_Json_Matlab - Fatal编程技术网

Json 如何有效地将3xn坐标字符串读入matlab数组

Json 如何有效地将3xn坐标字符串读入matlab数组,json,matlab,Json,Matlab,我有一个MATLAB脚本,它接受我自己在远程服务器上创建的JSON,并包含一长串3x3xN坐标,例如N=1: str = '[1,2,3.14],[4,5.66,7.8],[0,0,0],'; 我想避免字符串分裂,有没有什么方法可以使用stread或类似的方法来读取这个3×3×N张量 这是一个多粒子系统,N可能很大,但我有足够的内存将其一次性存储在内存中 任何关于如何在JSON中格式化数组字符串的建议都是非常受欢迎的。您可以使用eval函数: str = '[1,2,3.14],[4,5.66

我有一个MATLAB脚本,它接受我自己在远程服务器上创建的JSON,并包含一长串
3x3xN
坐标,例如
N=1

str = '[1,2,3.14],[4,5.66,7.8],[0,0,0],';
我想避免字符串分裂,有没有什么方法可以使用stread或类似的方法来读取这个3×3×N张量

这是一个多粒子系统,
N
可能很大,但我有足够的内存将其一次性存储在内存中


任何关于如何在JSON中格式化数组字符串的建议都是非常受欢迎的。

您可以使用
eval
函数:

str = '[1,2,3.14],[4,5.66,7.8],[0,0,0],';
result=permute(reshape(eval(['[' ,str, ']']),3,3,[]),[2 1 3])
结果=

1.00000   2.00000   3.14000
4.00000   5.66000   7.80000
0.00000   0.00000   0.00000
使用
eval
连接所有元素以创建行向量。然后将行向量重塑为三维阵列。由于在MATLAB中,元素以列方式放置在矩阵中,因此需要
排列
数组,以便对每个3*3矩阵进行转换

注1:无需将
[]
放在jSON字符串中,这样您就可以使用
str2num
而不是eval:

 result=permute(reshape(str2num(str),3,3,[]),[2 1 3])
注2: 如果按列保存数据,则无需排列:

str='1 4 0 2 5.66 0 3.14 7.8 0';
result=reshape(str2num(str),3,3,[])
更新:注意到与
eval
str2num
相关的安全和速度问题,以及之后关于使用
sscanf
的建议,我在倍频程测试了3种方法:

a=num2str(rand(1,60000));

disp('-----SSCANF---------')
tic
sscanf(a,'%f ');
toc

disp('-----STR2NUM---------')
tic
str2num(a);
toc

disp('-----STRREAD---------')
tic
strread(a,'%f ');
toc
结果如下:

-----SSCANF---------
Elapsed time is 0.0344398 seconds.
-----STR2NUM---------
Elapsed time is 0.142491 seconds.
-----STRREAD---------
Elapsed time is 0.515257 seconds.
因此,在您的情况下,使用
sscanf
更安全、更快:

str='1 4 0 2 5.66 0 3.14 7.8 0';
result=reshape(sscanf(str,'%f '),3,3,[])


您可以使用
eval
功能:

str = '[1,2,3.14],[4,5.66,7.8],[0,0,0],';
result=permute(reshape(eval(['[' ,str, ']']),3,3,[]),[2 1 3])
结果=

1.00000   2.00000   3.14000
4.00000   5.66000   7.80000
0.00000   0.00000   0.00000
使用
eval
连接所有元素以创建行向量。然后将行向量重塑为三维阵列。由于在MATLAB中,元素以列方式放置在矩阵中,因此需要
排列
数组,以便对每个3*3矩阵进行转换

注1:无需将
[]
放在jSON字符串中,这样您就可以使用
str2num
而不是eval:

 result=permute(reshape(str2num(str),3,3,[]),[2 1 3])
注2: 如果按列保存数据,则无需排列:

str='1 4 0 2 5.66 0 3.14 7.8 0';
result=reshape(str2num(str),3,3,[])
更新:注意到与
eval
str2num
相关的安全和速度问题,以及之后关于使用
sscanf
的建议,我在倍频程测试了3种方法:

a=num2str(rand(1,60000));

disp('-----SSCANF---------')
tic
sscanf(a,'%f ');
toc

disp('-----STR2NUM---------')
tic
str2num(a);
toc

disp('-----STRREAD---------')
tic
strread(a,'%f ');
toc
结果如下:

-----SSCANF---------
Elapsed time is 0.0344398 seconds.
-----STR2NUM---------
Elapsed time is 0.142491 seconds.
-----STRREAD---------
Elapsed time is 0.515257 seconds.
因此,在您的情况下,使用
sscanf
更安全、更快:

str='1 4 0 2 5.66 0 3.14 7.8 0';
result=reshape(sscanf(str,'%f '),3,3,[])


如果您能保证格式始终相同,我认为使用
sscanf
最简单、最安全、最快:

fmt  = '[%f,%f,%f],[%f,%f,%f],[%f,%f,%f],';
data = reshape(sscanf(str, fmt), 3, 3).';
根据其余数据(如何表示“
N
”),您可能需要调整
重塑
/
转置

编辑 根据您的评论,我认为这将非常有效地解决您的问题:

% Strip unneeded concatenation characters
str(str == ',') = ' ';
str(str == ']' | str == '[') = [];

% Reshape into workable dimensions
data = permute( reshape(sscanf(str, '%f '), 3,3,[]), [2 1 3]);
正如rahnema1所指出的,您可以通过调整JSON生成器来避免
permute
和/或字符删除,将数据列转换为major而不带括号,但您必须问自己以下问题:

  • 考虑到这里的代码已经非常小并且非常有效,这是否真的值得付出努力
  • 其他应用程序是否将使用JSON接口,因为本质上,您只是为了适应另一端的处理脚本而对JSON输出进行去泛化。我认为这是一个相当糟糕的设计实践,但哦,好吧 请记住:

    • 以二进制形式发出的500k值约为34MB
    • 在ASCII中执行同样的操作大约需要110MB
    现在,根据您的连接速度,我会很快变得非常恼火,因为每一个小测试运行所花费的时间大约是它应该花费的时间的3倍:)


    因此,如果无法直接对原始数据进行API调用,我至少会将该数据以JSON格式为基础。

    如果您能保证格式始终相同,我认为使用
    sscanf最简单、最安全、最快:

    fmt  = '[%f,%f,%f],[%f,%f,%f],[%f,%f,%f],';
    data = reshape(sscanf(str, fmt), 3, 3).';
    
    根据其余数据(如何表示“
    N
    ”),您可能需要调整
    重塑
    /
    转置

    编辑 根据您的评论,我认为这将非常有效地解决您的问题:

    % Strip unneeded concatenation characters
    str(str == ',') = ' ';
    str(str == ']' | str == '[') = [];
    
    % Reshape into workable dimensions
    data = permute( reshape(sscanf(str, '%f '), 3,3,[]), [2 1 3]);
    
    正如rahnema1所指出的,您可以通过调整JSON生成器来避免
    permute
    和/或字符删除,将数据列转换为major而不带括号,但您必须问自己以下问题:

  • 考虑到这里的代码已经非常小并且非常有效,这是否真的值得付出努力
  • 其他应用程序是否将使用JSON接口,因为本质上,您只是为了适应另一端的处理脚本而对JSON输出进行去泛化。我认为这是一个相当糟糕的设计实践,但哦,好吧 请记住:

    • 以二进制形式发出的500k值约为34MB
    • 在ASCII中执行同样的操作大约需要110MB
    现在,根据您的连接速度,我会很快变得非常恼火,因为每一个小测试运行所花费的时间大约是它应该花费的时间的3倍:)


    因此,如果API直接调用原始数据是不可能的,那么我至少会在JSON.

    中考虑BASE64的数据,请考虑<代码> N> 1 和效率。重新格式化JSON是可能的。只是在评估时要非常小心。如果一个有害的命令以字符串的形式出现,你将对它进行评估。<代码> STR2NUM <代码>内部运行<代码> EVA/COD>内部,所以除了输入验证(保护)之外没有太多功能上的差异。请考虑<代码> N> 1 和效率。重新格式化JSON是可能的。只是在评估时要非常小心。如果有害命令以字符串形式出现,您将对其求值。
    str2num
    运行
    eval