Can I fixed number of rows randomly from the dataset?
example
A=[1 2 3 4;
5 6 7 8;
9 10 11 12;
13 14 15 16;
17 18 19 20];
I want to random select training dataset 3 rows and random select testing dataset 2 rows.
training_dataset= [1 2 3 4;
13 14 15 16;
5 6 7 8;];
and
testing_dataset= [ 9 10 11 12;
17 18 19 20];
I found only the random number from the array.
Thank you so much
This solution uses the randperm and setdiff commands.
indTrainRow = randperm(size(A,1),3)
indTestRow = setdiff(1:size(A,1),indTrainRow)
training_dataset = A(indTrainRow,:);
testing_dataset = A(indTestRow,:);
You can also use randsample but this requires the Statistics toolbox.
indTrainRow = randsample(1:size(A,1),3,'false')
After posting this I found some related posts. My mistake for not finding these before answering.
Related Posts:
Random selection of matrix columns
How can I divide/split up a matrix by rows between two other matrices?
Related
I would like to sum specific columns of each row in a matrix using a for loop. Below I have included a simplified version of my problem. As of right now, I am calculating the column sums individually, but this is not effective as my actual problem has multiple matrices (data sets).
a = [1 2 3 4 5 6; 4 5 6 7 8 9];
b = [2 2 3 4 4 6; 3 3 3 4 5 5];
% Repeat the 3 lines of code below for row 2 of matrix a
% Repeat the entire process for matrix b
c = sum(a(1,1:3)); % Sum columns 1:3 of row 1
d = sum(a(1,4:6)); % Sum columns 4:6 of row 1
e = sum(a(1,:)); % Sum all columns of row 1
I would like to know how to create a for loop that automatically loops through and sums the specific columns of each row for each matrix that I have.
Thank you.
Here is a solution that you don't need to use for loop.
Assuming that you have a matrix a of size 2x12, and you want to do the row sums every 4 columns, then you can use reshape() and squeeze() to get the final result:
k = 4;
a = [1:12
13:24];
% a =
% 1 2 3 4 5 6 7 8 9 10 11 12
% 13 14 15 16 17 18 19 20 21 22 23 24
s = squeeze(sum(reshape(a,size(a,1),k,[]),2));
and you will get
s =
10 26 42
58 74 90
I am analyzing the efficiency of multiple circuits using matlab. The output is a maximum working distance and the power of the circuit analyzed. The output of this vectors is the following:
>> display(distance)
distance =
8 21 21 4 3 8 3 8 2 6 10 7 6 8 12 11 6 8
>>display(power)
power =
Columns 1 through 13
3.2047 3.5666 3.7578 1.8184 3.0810 3.7973 2.8699 3.3953 2.5971 3.1933 3.8191 3.7992 3.4802
Columns 14 through 18
4.1104 4.0836 3.2191 3.9155 0.2394
As you can see I have the circuit 1 that has a power of 3.2047 and a maximum distance of 8m. I have the circuit 6 that has the same maximum distance with a 3.7973 power. I want to rearrange the distance vector in order to it to be crescent (starting with 2 and ending with 21 for instance) and be able to rearrange the power accordingly. Below you have the display that I would like to see doing this to clarify this question.
>> display(distanceReorganized)
distanceReorganized =
2 3 3 4 6 6 6 7 8 8 8 8 8 10 11 12 21 21
>>display(powerReorganized)
powerReorganized =
Columns 1 through 13
2.5971 2.8699 3.0810 1.8184 3.1933 3.4802 3.9155 3.7992 0.2394 3.2047 3.3953 3.7973 4.1104
Columns 14 through 18
3.8191 3.2191 4.0836 3.5666 3.7578
Use the second output argument from sort.
[~,I] = sort(distance, 'ascend');
distanceReorganized = distance(I);
powerReorganized = power(I);
Edit: Based on your comment, sortrows should do what you are looking for:
circuitData = table(distance', power', 'VariableNames', {'Distance', 'Power'});
sortrows(circuitData,{'Distance','Power'})
You can then reassign the columns of the table to new vector variables should you wish to.
Here is the documentation for sortrows.
If I have this matrix:
A:
X Y Z
1 1 2
0 3 4
0 5 6
2 7 8
7 9 10
8 11 12
3 13 14
12 14 16
15 17 18
How could I create new matrix B, C, D and E which contains:
B:
0 3 4
0 5 6
C:
X Y Z
1 1 2
2 7 8
3 13 14
D:
7 9 10
8 11 12
E:
12 14 16
15 17 18
The idea is to construct a loop asking if 0<A<1 else 1<A<5 else 6<A<10 else 11<A<15. and create new matrix from that condition. Any idea about how to store the results of the loop?
I suggest you an approach that uses the discretize function in order to group the matrix rows into different categories based on their range. Here is the full implementation:
A = [
1 1 2;
0 3 4;
0 5 6;
2 7 8;
7 9 10;
8 11 12;
3 13 14;
12 14 16;
15 17 18
];
A_range = [0 1 5 10 15];
bin_idx = discretize(A(:,1),A_range);
A_split = arrayfun(#(bin) A(bin_idx == bin,:),1:(numel(A_range) - 1),'UniformOutput',false);
celldisp(A_split);
Since you want to consider 5 different ranges based on the first column values, the arguments passed to discretize must be the first matrix column and a vector containing the group limits (first number inclusive left, second number exclusive right, second number inclusive left, third number exclusive right, and so on...). Since your ranges are a little bit messed up, feel free to adjust them to respect the correct output. The latter is returned in the form of a cell array of double matrices in which every element contains the rows belonging to a distinct group:
A_split{1} =
0 3 4
0 5 6
A_split{2} =
1 1 2
2 7 8
3 13 14
A_split{3} =
7 9 10
8 11 12
A_split{4} =
12 14 16
15 17 18
Instead of using a loop, use logical indexing to achieve what you want. Use the first column of A and check for the ranges that you want to look for, then use this to subset into the final matrix A to get what you want.
For example, to create the matrix C, find all locations in the first column of A that are between 1 and 5, then subset the matrix along the rows using these locations:
m = A(:,1) >= 1 & A(:,1) <= 5;
C = A(m,:);
You can repeat this in a similar way for the rest of the matrices you want to create.
I have a matrix
A= [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16; 17 18 19 20]
I want to do some calculation on this matrix. But actually I do not need all the rows. So I have to discard some of the rows from the above matrix before doing a calculation. After discarding 3 rows, we will have a new matrix.
B= [1 2 3 4; 9 10 11 12; 17 18 19 20];
Now I have to use B to make some other calculations. So how can I discard some of the unwanted rows from a matrix in matlab? Any suggestion will be helpful. Thanks.
Try this: (Use when no. of rows to keep is lesser)
%// Input A
A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16; 17 18 19 20];
%// Rows (1-3,5) you wanted to keep
B = A([1:3, 5],:)
Output:
B =
1 2 3 4
5 6 7 8
9 10 11 12
17 18 19 20
Alternative: (Use when no. of rows to discard is lesser)
%// rows 2 and 3 discarded
A([2,3],:) = [];
Output:
>> A
A =
1 2 3 4
13 14 15 16
17 18 19 20
Note: Here (in the alternate method), the output replaces the original A. So you need to back up A if you need it afterwards. You could do this before discarding operation to backup Input matrix
%// Input A is backed up in B
B = A;
You can select the indices of the rows you want to keep:
A([1,3,5],:)
ans =
1 2 3 4
9 10 11 12
17 18 19 20
Having the values of time sequence, I would like to reshape it into a nx4 matrix [X y], for the purpose of using these values as input and output values for machine learning algorithm.
X(i) is a 1x3 input vector and y is output scalar value.
The algorithm takes as an input every 2nd sequence value (3 values) in order to predict the 4th value.
To give a practical example, let's say we have a sequence
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
The [X y] matrix should be the following:
[1 3 5 7; 2 4 6 8; 9 11 13 15; 10 12 14 16]
To get every second row I wrote the following code:
vec1 = timeSeries(1:2:end);
XyVec1 = reshape(vec1,4,[])'
similarly it could be written to get even numbers:
vec2 = timeSeries(2:2:end);
XyVec2 = reshape(vec2,5,[])'
The thing that I don't know how to do is to interleave matrix vec1 and vec2 rows to get
[vec(1,:); vec2(1,:);vec1(2,:), vec2(2,:)...]
Does anyone know how to interleave the rows of two (or more) matrices?
Try
result = zeros(size(vec1,1)+size(vec2,1),size(vec1,2));
result(1:2:end,:) = vec1;
result(2:2:end,:) = vec2;
Reuse matlab indexing facilities ot insert elements in correct rows
Sample octave mock-up: http://ideone.com/RVgmYA
There is this one-liner option
result = kron(vec1, [1;0]) + kron(vec2, [0;1]);
However, #Joel Falcou is faster. Having set the input vectors as
vec1 = rand(1000,1000);
vec2 = -rand(1000,1000);
it gives
Elapsed time is 0.007620 seconds. (indexing)
Elapsed time is 0.054607 seconds. (kron)
Good luck :) figuring out what's going on with those reshape(), permutes():
a = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16];
reshape(permute(reshape(a,2,4,[]),[2,1,3]),4,[])'
the result
ans =
1 3 5 7
2 4 6 8
9 11 13 15
10 12 14 16
To interleave the vectors as mentioned in the end of your question you can use
reshape([vec1, vec2]', 4, [])'
for
vec1 =
1 3 5 7
9 11 13 15
vec2 =
2 4 6 8
10 12 14 16
it returns
>> reshape([vec1, vec2]', 4, [])'
ans =
1 3 5 7
2 4 6 8
9 11 13 15
10 12 14 16