Json 如何有效地将3xn坐标字符串读入matlab数组
我有一个MATLAB脚本,它接受我自己在远程服务器上创建的JSON,并包含一长串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
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而不带括号,但您必须问自己以下问题:
- 以二进制形式发出的500k值约为34MB
- 在ASCII中执行同样的操作大约需要110MB
因此,如果无法直接对原始数据进行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