我正在使用Matlab API将数据从专有格式加载到一系列结构中。以下是加载文件后数据集外观的示例:
>>字段名(数据(1))
ans =
'Grid_Point_ID' 'Grid_Point_Latitude' 'Grid_Point_Longitude' 'Grid_Point_Altitude' 'Grid_Point_Mask' 'BT_Data'
>>数据(1).BT_Data
ans =
BT_Data: [1x66 struct]
>>字段名(数据(1).BT_Data(1))
ans =
'Flags' 'BT_Value_Real' 'BT_Value_Imag' 'Pixel_Radiometric_Accuracy' 'Incidence_Angle' 'Azimuth_Angle' 'Faraday_Rotation_Angle' 'Geometric_Rotation_Angle' 'Snapshot_ID_of_Pixel' 'Footprint_Axis1' 'Footprint_Axis2'
我想遍历所有data(i).BT_Data(j)
。我的data
已经很长了,但我无法得到BT_Data
的大小/长度(每个data(i)
会有所不同):
>>长度(数据(1).BT_Data)
ans =
1
>>大小(数据(1).BT_Data)
ans =
1 1
我的预期结果是ans = 66
(或size()
的等效数组)。
我对结构数据格式并不十分熟悉,这可能是我斗争的一部分。但是length(data)
工作得很好,所以我很困惑为什么它不适用BT_Data
(我也试过BT_Data(:)
)。
我能找到的最相关的上一个答案是1757250,但我无法让它起作用(我认为它不适用于此处)。感谢您提供的任何见解。
------
编辑------
这里有一点了解我如何使用API甚至达到我所处的位置:
>> system('ln -sf /opt/rwapi-matlab/lib/rwapi/smos/config/xml_rw_api.usr_conf.xml。');
SETENV( 'XML_RW_API_HOME', '/选择/ rwapi与Matlab / LIB / rwapi');
路径(路径, '/选择/ rwapi-MATLAB');>> prod = RWAPI.product('SM_OPEB_MIR_SCLF1C_20110202T013659_20110202T014642_346_060_1')
阵列SMOS Matlab接口版本1.4
(c)2010年加拿大阵列系统计算公司(http://www.array.ca)
分发或修改此软件需要获得Array的书面许可prod =
RWAPI.product handle Package: RWAPI Properties: filename: 'SM_OPEB_MIR_SCLF1C_20110202T013659_20110202T014642_346_060_1' header: [1x1 struct] xml_datablock: []
方法,事件,超类
>> data = prod.dataset(2)
data =
没有属性的RWAPI.dataset句柄。 包装:RWAPI
方法,事件,超类
>>数据(1)
ans =
Grid_Point_ID: 251721 Grid_Point_Latitude: 25.5000 Grid_Point_Longitude: -102.2590 Grid_Point_Altitude: 1.4714e+03 Grid_Point_Mask: 2 BT_Data: [1x66 struct]
>>数据(1).BT_Data
ans =
BT_Data: [1x66 struct]
>>数据(1).BT_Data(1)
ans =
Flags: 6229 BT_Value_Real: 262.5275 BT_Value_Imag: 0 Pixel_Radiometric_Accuracy: 6160 Incidence_Angle: 31966 Azimuth_Angle: 10299 Faraday_Rotation_Angle: 65277 Geometric_Rotation_Angle: 58605 Snapshot_ID_of_Pixel: 65752530 Footprint_Axis1: 19649 Footprint_Axis2: 14625
>>卫生组织
名称大小字节类属性ans 1x1 1逻辑
数据1x19091 112 RWAPI.dataset
prod 1x2 112 RWAPI.product
答案 0 :(得分:2)
我找到了一种解决方法,虽然它并不令人满意:
>> a = data(1).BT_Data
a =
BT_Data: [1x66 struct]
>>长度(a.BT_Data)
ans =
66
我现在将此标记为答案,因为我怀疑会有其他“正确”的方法来做到这一点。
安德鲁的回答确实解决了这个问题(为什么这个解决方法有效)。
答案 1 :(得分:2)
好吧,我真的怀疑这些RWAPI类中的覆盖subsref方法是一个奇怪的东西。通过定义具有轻微病态subsref的类,我能够重现所有观察到的行为。
classdef stupidref
%STUPIDREF Reproduce odd indexing behavior that jpatton saw. Buggy.
properties
BT_Data = repmat(struct('foo',42, 'bar',42), [1 66]);
end
methods
function B = subsref(A,S)
s = S(1);
subs = s.subs;
chain = S(2:end);
switch s.type
case '()'
B = builtin( 'subsref', A, s );
if ~isempty(chain)
B = subsref(B, chain);
end
case '.'
% Non-standard behavior!
if ~isempty(chain) && isequal(chain(1).type, '()')
B = subsref(A.(s.subs), chain);
else
B = struct(s.subs, A.(s.subs));
end
end
end
end
end
这与data(1).BT_Data
和fieldnames(data(1).BT_Data(1))
之间的奇怪差异以及重复添加“.BT_Data”的制表符完成一致。
>> data = stupidref;
>> data(1).BT_Data
ans =
BT_Data: [1x66 struct]
>> fieldnames(data(1).BT_Data)
ans =
'BT_Data'
>> fieldnames(data(1).BT_Data(1))
ans =
'foo'
'bar'
>> length(data(1).BT_Data)
ans =
1
>> data(1).BT_Data.BT_Data.BT_Data.BT_Data.BT_Data.BT_Data % produced by tab-completion
ans =
BT_Data: [1x66 struct]
>>
你的解决方法很好 - 一旦你打电话给a = data(1).BT_Data
,你就会得到一个正常的结构,并且非标准的subsref就不用了。您可以使用getfield
在单行中获得相同的效果。
>> btdata = getfield(data(1).BT_Data, 'BT_Data')
btdata =
1x66 struct array with fields:
foo
bar
我会将此报告为RWAPI库作者的可能错误。
您可以随意将此代码编辑到您自己的解决方案中;这不仅仅是支持诊断的答案。
答案 2 :(得分:1)
你的一些结果似乎是矛盾的。首先,如果字段BT_Data
包含1乘66结构数组,我希望看到这样的输出:
>> data(1).BT_Data
ans =
1x66 struct array with fields:
Flags
... %# etc.
你看到这个:
>> data(1).BT_Data
ans =
BT_Data: [1x66 struct]
向我建议BT_Data
实际上是1对1的结构,其中一个字段名为BT_Data
, 字段包含1×66结构数组。这将解释当您获得第一个BT_Data
(1乘1结构)的长度和大小时所看到的内容。如果是这种情况,您应该得到以下结果:
>> size(data(1).BT_Data.BT_Data)
ans =
1 66
但是,这仍然无法解释您在执行此操作时看到的输出:
fieldnames(data(1).BT_Data(1))
那让我失望了。您可能希望检查BT_Data
实际上是一个结构,而不是通过这样做来检查可能具有不同索引和显示行为的其他类型的对象:
isstruct(data(1).BT_Data)
如果1
是结构,则应该返回BT_Data
。