Trouble using container with cell type for key and structure array for values..
Mostra commenti meno recenti
Given this table,
TestTable_valid =
11×6 table
SerialNumber ACCurrentPreSyncEn ACCurrentPostSyncEn PassFail Model LCRSwept_Yes_No
____________________ __________________ ___________________ __________ _________ _______________
{'A017441206210001'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2C' } {'Yes'}
{'A017441229220004'} {'7.0A'} {'8.6A'} {'Passed'} {'VA2C' } {'Yes'}
{'A020621202230003'} {'0A' } {'7.7A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621203230003'} {'0A' } {'7.6A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621207230002'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621208230001'} {'0A' } {'7.1A'} {'Failed'} {'VA2CE'} {'Yes'}
{'A020621210230006'} {'1.2A'} {'0.7' } {'Failed'} {'VA2CE'} {'Yes'}
{'A020621215230003'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'}
{'A020621222230004'} {'0A' } {'0A' } {'Failed'} {'VA2CE'} {'Yes'}
{'A020622108240013'} {'7.1A'} {'0A' } {'Passed'} {'VA2CE'} {'Yes'}
{'A020622109240009'} {'7.1A'} {'7.1A'} {'Passed'} {'VA2CE'} {'Yes'}
I'm trying to create a container that uses the serial number as the key, and returns the other columns:
serials = TestTable_valid.SerialNumber
dataValues = TestTable_valid(:, 2:6)
dataStructArray = table2struct(dataValues)
% Create map: key = serial number, value = table row with C–G
lookupMap = containers.Map(serials, dataStructArray, 'UniformValues', false); % needed because data types in structure may be different.
however, I get the following error:
Error using containers.Map
Specified value type does not match the type expected for this container.
Don't know what else to try...I'm not sure cell vs. character array, vs cell array of characters, so perhaps that is the issue.....
I appreciate the help...
Jorge
6 Commenti
Matt J
il 7 Mag 2025
Given this table,...
Are we? I see no .mat attachment.
Walter Roberson
il 7 Mag 2025
It is not clear that containers.Map supports struct arrays for valueset
Adding a runnable example.
TestTable_valid = readtable('TestTable_valid.xlsx')
serials = TestTable_valid.SerialNumber
dataValues = TestTable_valid(:, 2:6)
dataStructArray = table2struct(dataValues)
% Create map: key = serial number, value = table row with C–G
lookupMap = containers.Map(serials, dataStructArray, 'UniformValues', false); % needed because data types in structure may be different.
Jorge
il 7 Mag 2025
Walter Roberson
il 7 Mag 2025
As of R2025a (currently pre-release), you will be able to use
dataStructArray = num2cell(dataValues,2);
to create a cell array in which each row is a cell array containing the variables.
Unfortunately in R2024b and earlier, building such a cell array is most easily done using a loop.
Risposta accettata
Più risposte (2)
keys = compose("A0%.2d" , 1:15);
values = struct('abc', num2cell(1:15));
d=dictionary(keys, values),
d("A008")
Is there a reason you want to use a container other than table?
Are the SerialNumbers unique? If so, you can put them in the RowNames property of the table and "query" the table using subscripting:
TestTable_valid = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1833727/TestTable_valid.xlsx')
TestTable_valid.Properties.RowNames = TestTable_valid.SerialNumber;
TestTable_valid.SerialNumber = [];
TestTable_valid.Properties.DimensionNames(1) = "SerialNumber";
% get all data for one row
TestTable_valid("A020621208230001",:)
% get just PassFail for one row
TestTable_valid.PassFail("A020621208230001")
% and of course, table, unlike dictionary, means that if you need to slice
% across all SerialNumbers, you still can:
TestTable_valid.Model
4 Commenti
Is there a reason you want to use a container other than table?
Perhaps because tables are slow?
TestTable_valid = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1833727/TestTable_valid.xlsx');
TestTable_valid.Properties.RowNames = TestTable_valid.SerialNumber;
TestTable_valid.SerialNumber = [];
TestTable_valid.Properties.DimensionNames(1) = "SerialNumber";
start = tic;
TestTable_valid("A020621208230001",:);
TestTable_valid("A017441206210001",:);
TestTable_valid("A020622109240009",:);
t1 = toc(start)
rownames = TestTable_valid.Properties.RowNames;
as_cell = arrayfun(@(IDX) {TestTable_valid{IDX,2:end}}, 1:height(TestTable_valid)).';
C = containers.Map(rownames, as_cell);
start = tic;
C("A020621208230001");
C("A017441206210001");
C("A020622109240009");
t2 = toc(start)
D = dictionary(rownames, as_cell);
start = tic;
D({'A020621208230001'});
D({'A017441206210001'});
D({'A020622109240009'});
t3 = toc(start)
Jorge
il 9 Giu 2025
Eric Sofen
il 9 Giu 2025
@Walter Roberson, Perhaps. That's why I asked the question. You and Matt are correct that if you just need to access data by looking up the SerialNumber, the fastest thing is to use a dictionary. (And we encourage you to use dictionary rather than containers.Map. Dictionary addresses several performance and behavioral issues with containers.). Lookup performance can be particularly important when doing a fast calculation in a tight loop and dictionary probably wins there. However, as I attempted to illustrate above, if Jorge wants to do things other than look up rows, then table may still be a good option. Vectorized calculations on one variable are a lot faster and easier on the table than the dictionary of structs.
Having real-world use cases is helpful for me as I think about table performance, because there are ultimately trade-offs in performance and functionality.
Walter Roberson
il 9 Giu 2025
See by the way the timing tests I posted at https://www.mathworks.com/matlabcentral/answers/113258-is-there-any-concept-like-dictionary-or-hash-tables-in-matlab-like-in-python#comment_3254879
Categorie
Scopri di più su Structures in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!