The |structfun| function only works on scalar struct arrays, iterating over the fields of that scalar struct. While you _could_ use |arrayfun|, it may be easier to understand (and perform just as well) if you use a |for| loop. I know people have said "Don't use |for| loops in MATLAB, they're slow." While that may have been true in the past (and you can still write a |for| loop so it is slow in current MATLAB) the performance of |for| loops have increased significantly with the improvements we have made to MATLAB over the years. Besides a |for| loop over 8 elements of a struct array calling |size| is highly unlikely, in my experience, to be the bottleneck in your code. Answer from Steven Lord on mathworks.com
🌐
MathWorks
mathworks.com › matlab › language fundamentals › data types › structures
structfun - Apply function to each field of scalar structure - MATLAB
A = structfun(func,S,Name,Value) applies func with additional options specified by one or more Name,Value pair arguments. For example, to return output values in a structure, specify 'UniformOutput',false. You can return A as a structure when func returns values that cannot be concatenated ...
🌐
MathWorks
mathworks.com › matlabcentral › answers › 811680-understanding-the-structfun-or-cellfun-commands
Understanding the structfun() or cellfun() commands - MATLAB Answers - MATLAB Central
April 23, 2021 - As the error message and doc says, structfun applies a function to each field in a scalar struct; you have a struct array -- not what you want. And, for the specific desire you don't need either function nor a loop construct, either -- use MATLAB vectorized notation--
Top answer
1 of 4
28

I've often seen the following conversion approaches:

matlab array -> python numpy array

matlab cell array -> python list

matlab structure -> python dict

So in your case that would correspond to a python list containing dicts, which themselves contain numpy arrays as entries

item[i]['attribute1'][2,j]

Note

Don't forget the 0-indexing in python!

[Update]

Additional: Use of classes

Further to the simple conversion given above, you could also define a dummy class, e.g.

class structtype():
    pass

This allows the following type of usage:

>> s1 = structtype()
>> print s1.a
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-40-7734865fddd4> in <module>()
----> 1 print s1.a
AttributeError: structtype instance has no attribute 'a'
>> s1.a=10
>> print s1.a
10

Your example in this case becomes, e.g.

>> item = [ structtype() for i in range(10)]
>> item[9].a = numpy.array([1,2,3])
>> item[9].a[1]
2
2 of 4
2

A simple version of the answer by @dbouz , using the idea by @jmetz

class structtype():
    def __init__(self,**kwargs):
        self.Set(**kwargs)
    def Set(self,**kwargs):
        self.__dict__.update(kwargs)
    def SetAttr(self,lab,val):
        self.__dict__[lab] = val

then you can do

myst = structtype(a=1,b=2,c=3)

or

myst = structtype()
myst.Set(a=1,b=2,c=3)

and still do

myst.d = 4 # here, myst.a=1, myst.b=2, myst.c=3, myst.d=4

or even

myst = structtype(a=1,b=2,c=3)
lab = 'a'
myst.SetAttr(lab,10) # a=10,b=2,c=3 ... equivalent to myst.(lab)=10 in MATLAB

and you get exactly what you'd expect in matlab for myst=struct('a',1,'b',2,'c',3).

The equivalent of a cell of structs would be a list of structtype

mystarr = [ structtype(a=1,b=2) for n in range(10) ]

which would give you

mystarr[0].a # == 1
mystarr[0].b # == 2
Top answer
1 of 4
2

Assuming that the structure contains fields with scalar numeric values, you can use this struct2array based approach -

search_num = 6; %// Edit this for a different search number
fns=fieldnames(Columns) %// Get field names
out = fns(struct2array(Columns)==search_num) %// Logically index into names to find
                                             %// the one that matches our search 
2 of 4
2

Goal:

Construct two vectors from your struct, one for the names of fields and the other for their respective values. This has analogy to the dict in Python or map in C++, where you have unique keys being mapped to possibly non-unique values.

Simple Solution:

You can do this very simply using the various functions defined for struct in Matlab, namely: struc2cell() and cell2mat()

  1. For the particular element of interest, say 1 of your struct Columns, get the names of all fields in the form of a cell array, using fieldnames() function:

    fields = fieldnames( Columns(1) )
    
  2. Similarly, get the values of all the fields of that element of Columns, in the form of a matrix

    vals = cell2mat( struct2cell( Columns(1) ) )
    
  3. Next, find the field with the corresponding value, say 6 here, using the find function and convert the resulting 1x1 cell into a char using cell2mat() function :

    cell2mat( fields( find( vals == 6 ) ) )
    

    which will yield:

    T21
    

Now, you can define a function that does this for you, e.g.:

function fieldname = getFieldForValue( myStruct, value)

Advanced Solution using Map Container Data Abstraction:

You can also choose to define an object of the containers.map class using the field-names of your struct as the keySet and values as valueSet.

myMap = containers.Map( fieldnames( Columns(1) ), struct2cell( Columns(1) ) );

This allows you to get keys and values using corresponding built-in functions:

myMapKeys = keys(myMap);
myMapValues = values(myMap);

Now, you can find all the keys corresponding to a particular value, say 6 in this case:

cell2mat( myMapKeys( find( myMapValues == 6) )' )

which again yields:

T21

Caution: This method, or for that matter all methods for doing so, will only work if all the fields have the values of the same type, because the matrix to which we are converting vals to, need to have a uniform type for all its elements. But I assume from your example that this would always be the case.

Customized function/ logic:

struct consists of elements that contain fields which have values, all in that order. An element is thus a key for which field is a value. The essence of "lookup" is to find values (which are non-unique) for specific keys (which are unique). Thus, Matlab has a built-in way of doing so. But what you want is the other way around, i.e. to find keys for specific values. Since its not a typical use case, you need to write up your own logic or function for it.

🌐
MATLAB For Engineers
matlab4engineers.com › home › lesson
structfun Basics - MATLAB For Engineers
Python/C/C++/C#/OpenCL/OpenGL · Search · 0 · Please sign up for the course before starting the lesson. Download the data file and load it into MATLAB before you start: Download TasksTask 1 You can pass the ‘UniformOutput’, false argument to structfun in the same way as cellfun.
Find elsewhere
🌐
Medium
medium.com › analytics-vidhya › day-1-making-matlab-fun-ad850eaffbde
Day 1: Making MATLAB “fun”
May 27, 2020 - Day 1: Making MATLAB “fun” One of the most important tools that will set your code apart from others in MATLAB is the “fun” family of operations: arrayfun, structfun, cellfun, rowfun, and …
🌐
MathWorks
mathworks.com › matlabcentral › answers › 524757-apply-function-to-all-fields-in-a-structure-array
apply function to all fields in a structure array - MATLAB Answers - MATLAB Central
May 11, 2020 - https://www.mathworks.com/matlabcentral/answers/524757-apply-function-to-all-fields-in-a-structure-array#answer_431881 · Cancel Copy to Clipboard · Why the nested structure? That's where the problem arises---convert to a struct array, S as · >> S=F1 · S = 1×2 struct array with fields: f1 · f2 · K>> arrayfun(@(s) structfun(@max,s),S,'UniformOutput',false) ans = 1×2 cell array ·
🌐
Mit
lost-contact.mit.edu › afs › inf.ed.ac.uk › group › teaching › matlab-help › R2016b › matlab › ref › structfun.html
structfun
[A1,...,An] = structfun(func,S) applies the function specified by function handle func to each field of scalar structure S.
🌐
MathWorks
mathworks.com › matlab › language fundamentals › data types › structures
arrayfun - Apply function to each element of array - MATLAB
Calculate the mean for each field in S by using the arrayfun function. You cannot use structfun for this calculation because the input argument to structfun must be a scalar structure.
🌐
MathWorks
mathworks.com › matlabcentral › answers › 301329-how-to-apply-certain-action-on-struct-fields
How to apply certain action on struct fields? - MATLAB Answers - MATLAB Central
August 30, 2016 - https://www.mathworks.com/matlabcentral/answers/301329-how-to-apply-certain-action-on-struct-fields#answer_233112 ... The structfun documentation clearly states that the input structure must be a scalar structure.
🌐
Stack Overflow
stackoverflow.com › questions › 74166018 › matlab-structfun
r - Matlab Structfun - Stack Overflow
x = real(x) #impose non-imaginary # we actually want all the d_ij to be N*N, no N^2, so reshape: z_d = structfun(@(x) reshape(x,z.N,z.N), z_d, 'Uniform',0); #this one · I would say sapply() but I did not succeed yet. For more information, I am trying to translate Matlab code of a solveExactHat.m file from Balboni et al.