Most efficient way to rename struct fields according to a map?
9 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
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 Kommentare
Stephen23
am 16 Sep. 2016
Bearbeitet: Stephen23
am 16 Sep. 2016
"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.
Antworten (2)
Steven Lord
am 16 Sep. 2016
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 Kommentare
Siehe auch
Kategorien
Mehr zu Structures finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!