I would like to know what the meaning of
col2=b1(1:end,lead);
is in MATLAB?
This is very basic stuff. We are led to assume that b1 is a 2-dimensional array. The contents of an array are indexed using brackets, so b1(1,1) will return the top left element of array b1. The first index in your example, 1:end is selecting every element in the first dimension (matlab indexes rows first, then columns). The second index, lead in your example, selects a particular column. We assume that lead has been allocated previously somewhere in the code.
Thence, b1(1:end,lead) returns to col2 a 1-dimensional array containing a subarray of b1. This could be accomplished more elegantly using col2=b1(:,lead);.
Related
I'm really sorry to bother so I hope it is not a silly or repetitive question.
I have been scraping a website, saving the results as a collection in MongoDB, exporting it as a JSON file and importing it in MATLAB.
At the end of the story I obtained a struct object organised
like this one in the picture.
What I'm interested in are the two last cell arrays (which can be easily converted to string arrays with string()). The first cell array is a collection of keys (think unique products) and the second cell array is a collection of values (think prices), like a dictionary. Each field is an instance of possible values for a set of this keys (think daily prices). My goal is to build a matrix made like this:
KEYS VALUES_OF_FIELD_1 VALUES_OF_FIELD2 ... VALUES_OF_FIELDn
A x x x
B x z NaN
C z x y
D NaN y x
E y x z
The main problem is that, as shown in the image and as I tried to explain in the example matrix, I don't always have a value for all the keys in every field (as you can see sometimes they are 321, other times 319 or 320 or 317) and so the key is missing from the first array. In that case I should fill the missing value with a NaN. The keys can be ordered alphabetically and are all unique.
What would you think would be the best and most scalable way to approach this problem in MATLAB?
Thank you very much for your time, I hope I explained myself clearly.
EDIT:
Both arrays are made of strings in my case, so types are not a problem (I've modified the example). The main problem is that, since the keys vary in each field, firstly I have to find all the (unique) keys in the structure, to build the rows, and then for each column (field) I have to fill the values putting NaN where the key is missing.
One thing to remember you can't simply use both strings and number in one matrix. So, if you combine them together they can be either all strings or all numbers. I think all strings will work for you.
Before make a matrix make sure that all the cells have same element.
new_matrix = horzcat(keys,values1,...valuesn);
This will provide a matrix for each row (according to your image). Now you can use a for loop to get matrices for all the rows.
For now, I've solved it by considering the longest array of keys in the structure as the complete set of keys, let's call it keys_set.
Then I've created for each field in the structure a Map object in this way:
for i=1:length(structure)
structure(i).myMap = containers.Map(structure(i).key_field, structure(i).value_field);
end
Then I've built my matrix (M) by checking every map against the keys_set array:
for i=1:length(keys_set)
for j=1:length(structure)
if isKey(structure(j).myMap,char(keys_set(i)))
M(i,j) = string(structure(j).myMap(char(keys_set(i))));
else
M(i,j) = string('MISSING');
end
end
end
This works, but it would be ideal to also be able to check that keys_set is really complete.
EDIT: I've solved my problem by using this function and building the correct set of all the possible keys:
%% Finding the maximum number of keys in all the fields
maxnk = length(structure(1).key_field);
for i=2:length(structure)
if length(structure(i).key_field) > maxnk
maxnk = length(structure(i).key_field);
end
end
%% Initialiting the matrix containing all the possibile set of keys
keys_set=string(zeros(maxnk,length(structure)));
%% Filling the matrix by putting "0" if the dimension is smaller
for i=1:length(structure)
d = length(string(structure(i).key_field));
if d == maxnk
keys_set(:,i) = string(structure(i).key_field);
else
clear tmp
tmp = [string(structure(i).key_field); string(zeros(maxnk-d,1))];
keys_set(:,i) = tmp;
end
end
%% Merging without duplication and removing the "0" element
keys_set = union_several(keys_set);
keys_set = keys_set(keys_set ~= string(0));
I have a matrix and I am interested in changing values that satisfy a certain condition inside that matrix differently, depending on where they are. Say I have a matrix smallPic. How do I obtain a matrix smallPicB with the same dimensions that changed all values that are above 50 in the first two columns to a 255, while those that are in the third and fourth column are changed to a 180?
I have this code which works, but it is pretty ugly and requires splitting the matrix and concatenating it again:
smallPic1=smallPic(:,1:2);smallPic1(smalllPic1>50)=255;
smallPic2=smallPic(:,3:4);smallPic2(smalllPic2>50)=180;
smallPicB = [smalllPic1 smalllPic2];
How would you combine the logical index with the scalar index in one command?
What doesn't work is this:
smallPic(:,smallPic(:,3:4)>50) = 180
Here, the second mention of smallPic inside the brackets does not allow indexing into the correct position of smallPic because it doesn't have the same dimensions as smallPic. So this command actually replaces values in the first two columns of smallPic that are in the same row as those values that are above 50 in the third and fourth column, instead of replacing the values in the third and fourth column themselves.
Any other suggestions?
It probably is not what you're looking for, but it can help if you have lots of assignments like that:
J = repmat(1:size(smallPic, 2), size(smallPic, 1), 1)
smallPic((J<3)&(smallPic>50))=255
smallPic((J>2)&(J<5)&(smallPic>50))=180
You can also call ismember function if column indices are not consecutive:
smallPic(ismember(J, [[1:2 5:6]])&(smallPic>50))=255
I'm new to constraint programming and toying around with some basic operations. I want to count the number of occurrences of an arbitrary element x in an array of pairs.
For instance, the following array has 2 eights, and 1 of every other element.
sampleArray = [{8,13}, {21,34}, {8,55}]
I wonder how I am to extract this information, possibly using built-in functions.
I'm not sure I understand exactly what you want to do here. Do you want to count only the first element in the pair?
Note that the example you show is an array of sets, not a 2 dimensional matrix. Extracting and count the first(?) element in each pair is probably easier if you have a two dimensional matrix (constructed with array2d).
In general there are at least two global constraints that you can use for this: "count" and perhaps also "global_cardinality". See http://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html
This related question How can I apply a function to every row/column of a matrix in MATLAB? seems to indicate one way to do this is using num2cell, which I kind of want to stay away from.
Here's what I want to do. I've got an index list for a triangle mesh, the indices index the vertex list.
I want to run func(a,b,c) on the first 3 indices, then the next three indices, and so on.
So I could reshape(idxs,3,[]) so now i've got my data into triplets as column vectors. But arrayfun does not do what I want it to do.
Looking for something like a column-map operator.
First, get your func properly vectorized, if necessary, such that the arguments can be lists of equal length:
vec_func = #(a,b,c)(arrayfun(#func,a,b,c))
Then, you can directly access every third element of idxs:
vec_func( idxs(1:3:end), idxs(2:3:end), idxs(3:3:end) )
I am getting stock prices from yahoo, and want to have each stock have its own time series data structure, but also don't want to have hundreds of variables, so naturally I would want to have an array, but when I do something like array = [stock1 stock2]; it actually merges the series together. How can I make a real array?
Thanks,
CP
[x x] notation in matlab is not an array, it is a vector. It is assumed that what you're putting together belongs together. What you probably want is a cell array which is indexed with a curly brace, ie myArray{1} = stock1; myArray{2} = stock2;. Reference here.
Ah, since you have row vectors, [stock1 stock2] is a concatenation. If you want to create a 2-by-x array instead, do something like this [stock1; stock2], which will place one array above the other.
Joining vectors using [x y] has different results depending on whether your vectors are rows or columns. If rows, then joining them with [x y] makes a longer row vector, but if columns, you'll get a Nx2 matrix. You should probably convert them to column vectors using the TRANSPOSE operator thus: [x' y']. Although you should check if transpose means the same thing with Time Series objects as at does with regular vectors.