Most efficient way to rename struct fields according to a map?
6 次查看(过去 30 天)
显示 更早的评论
Hi, I am importing ASCII data from multiple sources into MATLAB structs. Each data source uses a different naming convention for the same parameters, so I need to make sure the imported struct data uses a standardized naming convention for fields. For example, one set of data might look like:
data1 =
a1: [1x500 double]
b1: [1x500 double]
And another set of data might look like:
data2 =
a2: [1x500 double]
b2: [1x500 double]
I want to convert them both to standardized field names 'a' and 'b':
data1 =
a: [1x500 double]
b: [1x500 double]
data2 =
a: [1x500 double]
b: [1x500 double]
I have written a small function shown below that does this field replacement:
function s = repfield(s,oldList,newList)
f = fieldnames(s);
v = struct2cell(s);
for i = 1:length(oldList)
[c,i1] = intersect(f,oldList{i});
if isempty(c)
continue
elseif length(c) > 1
error('Non-unique field mapping found')
else
f{i1} = newList{i};
end
end
s = cell2struct(v,f);
So I can call
>> oldList = {{'a1','a2'},{'b1','b2'}};
>> newList = {'a','b'};
>> data1 = repfield(data1,oldList,newList)
data1 =
a: [1x500 double]
b: [1x500 double]
The code is simple enough and works pretty well. But the data I'm handling is rather large and even the maps become quite long (e.g. the variables "oldList" and "newList" in the above function call would be hundreds of elements long). So I was wondering, is this already the most efficient way or does anything else exist, for example by using containers.Map maybe? I have no experience in data handling, but this sounds to me like a common enough problem that should have an efficient solution.
Thanks!
3 个评论
Stephen23
2016-9-16
编辑:Stephen23
2016-9-16
"this sounds to me like a common enough problem that should have an efficient solution"
Rather than importing into lots of named variables (almost always a very bad idea), it would likely be much more efficient to name that data correctly in the first place, while it is being laoded. Load into a variable, and merge that into one non-scalar structure, making any adjustments to the names before merging.
回答(2 个)
Steven Lord
2016-9-16
If you're operating on scalar struct arrays, use dynamic field names.
function newS = canonicalNames(oldS, oldNames, newNames)
newS = struct;
for whichField = 1:numel(oldNames)
oldN = oldNames{whichField};
if ~isfield(oldS, oldN)
error(sprintf('Field %s does not exist in old struct array!', oldN));
end
newN = newNames{whichField};
newS.(newN) = oldS.(oldN);
end
I haven't tested this but it should work. Add additional error checking as desired; that oldS is in fact a scalar struct array, that both oldNames and newNames are cell arrays, that they have the same number of elements, that the names in newNames are valid struct field names, etc.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Structures 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!