I have an array of structs and would like to set all empty attributes to NaN:
structArray =
29x1 struct array with fields:
value
id
How do I set all struct.value attributes to NaN, if they are empty?
If they are empty the conversion [structArray.value] omits the empty elements...
Given this:
x(29).id = [];
x(29).value = [];
You can set the value of all .id fields like this
[x.value] = deal(nan);
To set only a particular subset of values define a mask of values to set and then use it in your assignment statement:
maskEmptyId = arrayfun( #(a)isempty(a.id), x );
[x(maskEmptyId).id] = deal(nan);
As #Pursuit explained there is an excellent way to replace the empty fields with NaNs
However, you may also be interested in a different approach.
Instead of replacement in hindsight you may be able to prevent the empty spots to occur in the first place. Assuming they are empty because nothing has been assigned to them, you can simply initialize your struct with NaNs.
For example:
structArray = struct ('id',[],'value',NaN)
Calling this before you assign anything to structArray would initialize the value field with NaN, but will still initialize the id to be empty.
Related
For example I have a 1x5 string array. Now I saw some fields are []. What does this mean? And what is the difference between a field which is totally empty?
How can I create such fields?
array(1)=[];
array(2)=;
%or
array(3)="";
And how can I check if the input of a field is empty, NaN or ""?
array(1)=[]; means that you're removing the first element of array if the variable already exists.
array(2)=; is an invalid expression.
array(3)="" stores an empty string "" at the third index of array. Since first two indices were not initialized by you in your code snippet, so these two indices will store <missing>. If you had an array of double class, you would have got zeros instead of <missing>. Presence of <missing> can be checked by ismissing.
In a string array, you cannot have Nan or empty. You can have "" string though.
You can have those elements if you have a cell array instead.
array{1} = [];
array{2} = "";
array{3} = NaN;
Now presence of [], "", and NaN in the above cell array can be checked by isempty, strcmp and isnan respectively with cellfun.
I have a structure in Matlab, each field contains elements with varying numbers of variables. I would like to remove duplicates of numbers that appear within the same field: I know the unique() function and know how to use it to scan through fields one at a time but not an entire field.
I think I want something like:
structure(1:length(structure)).field=unique(structure(1:length(structure)).field
and get
original
field=[1,2,3] [1,4,5] [2,5,8]
to turn into
field=[1,2,3] [4,5] [8]
Maybe a complicated for loop similar to below (isn't working) which would grab the values from the first element in the field, search through each additional element, and if that value is present set it equal to =[];, and iterate through that way?
for n=1:length(RESULTS)
for m=1:length(RESULTS(n).Volumes)
for l=1:length(RESULTS)
for o=1:length(RESULTS(l).Volumes)
if RESULTS(n).Volumes(m)==RESULTS(l).Volumes(o)
RESULTS(l).Volumes(o)=[];
end
end
end
end
end
Thanks!
This is a quick-and-dirty attempt, but you might be able to improve on it. Assume your struct array and field are sa(:).v. I'm also assuming that the field contains a 1xn array of numbers, as in your example. First, make a "joint" array with the concatenation of all field values and filter the non-unique values:
joint = cell2mat({sa.v});
[uniqJoint,~,backIdx] = unique(joint);
The "uniqJoint" array has also been sorted, but the "backIdx" array contains the indices that, if applied to uniqJoint, will rebuild the original "joint" array. We need to somehow connect those to the original indices (i,j) into the struct array and within the field value sa(i).v(j). To do that, I tried creating an array of the same size as "joint" that contains the indices of the struct that originally had the corresponding element in the "joint" array:
saIdx = cell2mat(arrayfun(#(i) i * ones(1,length(sa(i).v)), ...
1:length(sa), 'UniformOutput', false));
Then you can edit (or, in my case, copy and modify the copy of) the struct array to set the field to the values that have not appeared before. To do that, I keep a logical array to mark the indices of "backIdx" as "already used", in which case I skip those values when rebuilding the fields of each struct:
sb = sa;
used = false(length(backIdx));
for i = 1:length(sa)
origInd = find(saIdx == i); % Which indices into backIdx correspond to this struct?
newInd = []; % Which indices will be used?
for curI = backIdx(origInd)
if ~used(curI)
% Mark as used and add to the "to copy" list
used(curI) = true;
newInd(end+1) = curI;
end
end
% Rewrite the field with only the indices that were not used before
sb(i).v = uniqJoint(newInd);
end
In the end, the data in sb(i).v contains the same numbers as sa(i).v without repeats, and removing those that appeared in any previous elements of the struct.
I am trying to create an array where each element is an empty array.
I have tried this:
var result = Array.fill[Array[Int]](Array.empty[Int])
After looking here How to create and use a multi-dimensional array in Scala?, I also tried this:
var result = Array.ofDim[Array[Int]](Array.empty[Int])
However, none of these work.
How can I create an array of empty arrays?
You are misunderstanding Array.ofDim here. It creates a multidimensional array given the dimensions and the type of value to hold.
To create an array of 100 arrays, each of which is empty (0 elements) and would hold Ints, you need only to specify those dimensions as parameters to the ofDim function.
val result = Array.ofDim[Int](100, 0)
Array.fill takes two params: The first is the length, the second the value to fill the array with, more precisely the second parameter is an element computation that will be invoked multiple times to obtain the array elements (Thanks to #alexey-romanov for pointing this out). However, in your case it results always in the same value, the empty array.
Array.fill[Array[Int]](length)(Array.empty)
Consider also Array.tabulate as follows,
val result = Array.tabulate(100)(_ => Array[Int]())
where the lambda function is applied 100 times and for each it delivers an empty array.
I have this structure
Data = struct('trials',{},'time',{},'theta_des',{},'vel_des',{},'trials_number',{},'sample_numbers',{});
Data(1).trials = cell(1,trials_number);
for i=1:trials_number
Data.trials{i} = struct('theta',{},'pos_err',{},'vel',{},'vel_err',{},'f_uparm',{},'f_forearm',{},'m_uparm',{},'m_forearm',{},...
'current',{},'total_current',{},'control_output',{},'feedback',{},'feedforward',{},'kp',{});
end
but when I want to add a value
Data.trials{i}.theta = 27;
I get this error...
A dot name structure assignment is illegal when the structure is empty. Use a subscript on the structure.
Any idea of how to solve it?
Thanks!
If you take a look at the documentation of struct, it says the following statement:
s = struct(field,value) creates a structure array with the specified field and values.
...
...
If any value input is an empty cell array, {}, then output s is an empty (0-by-0) structure.
Because your fields are initialized to {}, these are empty cell arrays, you will get an empty structure, so you are not able to access into the structure as it's empty. If you want to initialize the struct, use the empty braces instead []. In other words, in your for loop, do this:
for i=1:trials_number
Data.trials{i} = struct('theta',[],'pos_err',[],'vel',[],'vel_err',[],'f_uparm',[],'f_forearm' [],'m_uparm',[],'m_forearm',[],...
'current',[],'total_current',[],'control_output',[],'feedback',[],'feedforward',[],'kp',[]);
end
This should properly initialize the structure for you, and you can then access the fields accordingly. As such, if I wanted to initialize theta in the first structure within your cell array:
Data.trials{1}.theta = 27;
This will now work. You can verify the output by:
disp(Data.trials{1}.theta)
27
What are brackets [] doing in Matlab, if not filled with numbers?
Let's assume we have some objects obj1, obj2 and obj3 of a ClassA. Apparently it's possible to combine them with brackets in a .. don't know, what it actually is
objects = [obj1 obj2 obj3];
>> class(objects)
ans =
ClassA
>> objects
objects =
1x3 ClassA handle
Properties:
name
...
Whats this called?
How to iteratively build such thing?
objects = []; objects(end+1) = current_obj; does not work
objects{end+1} = current_obj; creates a cell
How can one convert to this e. g. from a cell with objects?
When using the [] notation again on a field it gives
K>> [objects.name]
ans =
Object1Object2Object3
K>> class([objects.name])
ans =
char
[obj1 obj2 obj3] is an array of objects of class ClassA, just like [1 2 3] is an array of numbers.
If you type a = []; a(2) = 1, MATLAB will return a as [0 1], in other words it will fill any unspecified elements of a with a default element which, in the case of numbers, is zero.
When you type objects = []; objects(2) = current_obj, MATLAB similarly attempts to put current_obj in the requested position 2 of objects, and then to fill the unspecified elements with default objects of class ClassA. To do this, it calls the constructor of ClassA, but you need to know that it calls the constructor with no input arguments.
Therefore, if you want to be able to support this sort of array filling with objects of your class, you need to implement the class constructor so that it will not error when called with zero input arguments. For example, you could simply check nargin, and if it's zero, supply some default inputs, otherwise accept whatever inputs were provided.
By the way, by default [] is of class double. If you want to create an empty array of class ClassA, you can use objects = ClassA.empty. empty is a built-in method of all MATLAB classes. You may find that you avoid some errors by making sure that you don't accidentally attempt to concatenate doubles with objects of class ClassA.
If you really need an empty array of objects, use some object you have and index "nothing" (from 2 to 1):
x=obj1(2:1)
Result is an empty array with a matching type. Here you can append using x(end+1). Alternatively you can use similar code to append. If x does not exist it will be created with a matching type.
if exist('x','var')
x(end+1)=obj
else
x(1)=obj
end
What you are doing is creating structures. What I would do is create the same structure for objects and then overwrite the 1st index with your first object, and then iterate through the rest:
% Assume we have classA.m file available
obj1 = classA();
obj2 = classA();
obj3 = classA();
objects = obj1;
objects(end+1) = obj2;
objects(end+1) = obj3;
Square brackets are for concatenation
If you have square brackets with elements between them, you are concatenating the elements.
The elements can abe scalars, strings, vectors, matrices and so on.
Example
Assuming that the name fields of the objects struct contains a string, you can concatenate all of them like so:
[objects.name]
The result will be:
[objects(1).name objects(2).name ... objects(end).name]