I am trying to extract a sequence of rows from a column of data in MATLAB. For example, my data looks like this in one column:
10
20
30
40
50
60
70
80
90
100
110
120
130
I want to select a sequence of rows and store these rows in a column vector A that looks like this after extracting the first 3 rows skipping 2 rows then selecting the next 3 rows and skipping 2 rows and selecting the next 3 to the end of the column.
Finally, the data should look like this with 9 rows and 1 column:
10
20
30
60
70
80
110
120
130
Thank you!
Let
x = [10 20 30 40 50 60 70 80 90 100 110 120 130].'; %'// data
m = 3; %// keep
n = 2; %// skip
Then
y = x(mod(0:end-1,m+n)<=m-1);
or equivalently
y = x(mod(0:numel(x)-1,m+n)<=m-1);
How this works: generate the sequence 0,1,2,... numel(x)-1. Each number corresponds to a position in x. To keep m and skip n cyclically, you apply mod(...,m+n) to that sequence. For example, for m=3, n=2 the result is sequence 0,1,2,3,4,0,1,2,.... You then select those numbers (that is, the corresponding entries of x) that are <=m-1. This results in the periodic pattern "keep, keep, keep, skip, skip".
To first skip and then keep (reverse from above): just reverse the inequality:
y = x(mod(0:end-1,m+n)>=m-1);
or
y = x(mod(0:numel(x)-1,m+n)>=m-1);
Try this, assuming a is your input column vector -
r_accept = 3; %// number of rows to accept
r_reject = 2; %// number of rows to reject
ind1 = bsxfun(#plus,1:r_accept+r_reject:numel(a),[0:r_accept-1]') %//'
out = a(ind1(ind1(:)<=numel(a))) %// desired output
I just figured out another way to compliment the nice solutions using find function.
If my data is:
x = [10; 20; 30; 40; 50; 60; 70; 80; 90; 100; 110; 120; 130]
and I want to extract a repeating sequence of rows then:
Develop an index of the repeating pattern or row sequence of keeps (3) and skips (2) rows. My index would be then:
index = [1:5 1:5 1:5]
or
index = 123451234512345
Then use the find function to logically index the "keep" sequence.
a = find(index<4)
which gives:
a = 1 2 3 6 7 8 11 12 13
then:
b = x(a)
produces
b = 10 20 30 60 70 80 110 120 130
Related
I have an array (2000x2) with two variables and want to calculate the mean of column 2 at intervals determined by column 1. How can i do this?
speed=(:,1); %values range from 0-100 cm/s
press=(:,2);
I want to calculate mean pressure at at 5 cm/s intervals of speed. So that I get 20 values for pressure that correspond to 20 intervals of speed.
Should be simple, but I'm still a beginner in Matlab.
The accumarray function does just that:
data = [0 20 33 44 22 56 25 47 81 90; 3 5 4 3 2 4 5 5 6 0].';
speed = data(:,1);
press = data(:,2);
sz = 5; % interval size
fill = NaN; % fill value in the result, for empty groups
group = floor(speed/sz)+1; % compute index of group for each value
result = accumarray(group, press, [], #mean, NaN); % compute mean of each group
I want to select a random value but previously selected value are excluded from the selection. How can make like this??
Create a list of random numbers within the range, and pick one at a time
minimum=1;
maximum=16;
randomNumbers=randperm(maximum-minimum+1)+minimum-1
and sample output is randomNumbers=[7 13 2 15 12 4 16 11 9 5 3 1 14 6 8 10]. You can display each number sequentially using, for example,
for k=1:maximum+1-minimum
randomNumbers(k)
end
This approach is generalized one.. A could have any values, some numbers repeating or non repeating.. also any number of(of course upto numel(A)) could be generated.
Code:
A = randi(50,3,3); %// replace this with your own matrix
idx = 1:numel(A); %// generating linear indices
noOfRandNos = 5; %// How many such numbers do you want?
randNos(noOfRandNos,1) = 0; %// pre Allocation
%// This loop is run as many times as the number of such numbers you require.
%// Maximum possible runs will be equal to the numel(A).
for ii = 1:noOfRandNos
randidx = randi(numel(idx)); %// generating a rand Indx within the current size of idx
randNos(ii) = A(idx(randidx)); %// Getting corresponding number in-turn from the indx
idx(randidx) = []; %// removing the particular indx so that it is not repeated
end
Sample Run:
>> A
A =
12 28 25
23 27 32
49 12 34
>> randNos
randNos =
28
49
34
12
32
To pick 5 numbers from the set 1:16 without repetition: use randsample:
result = randsample(1:16, 5);
I am a novice at Matlab and am struggling a bit with creating a loop that will a convert a 283080 x 2 matrix - column 1 lists all stockID numbers (each repeated 60 times) and column 2 contains all lagged monthly returns (60 observations for each stock) into a 60 x 4718 matrix with a column for each stockID and its corresponding lagged returns falling in 60 rows underneath each ID number.
My aim is to then try to calculate a variance-covariance matrix of the returns.
I believe I need a loop because I will be repeating this process over 70 times as I have multiple data sets in this same current format
Thanks so much for the help!
Let data denote your matrix. Then:
aux = sortrows(data,1); %// sort rows according to value in column 1
result = reshape(aux(:,2),60,[]); %// reshape second column as desired
If you need to insert the stockID values as headings (first row of result), add this as a last line:
result = [ unique(aux(:,1)).'; result ];
A simple example, replacing 60 by 2:
>> data = [1 100
2 200
1 101
2 201
4 55
3 0
3 33
4 56];
>> aux = sortrows(data,1);
>> result = reshape(aux(:,2),2,[])
>> result = [ unique(aux(:,1)).'; result ];
result =
1 2 3 4
100 200 0 55
101 201 33 56
I have a matrix like the following:
A =
5 2 10 14 11
I am looking to create an additional row using this data. The element in the fifth column, second row, is constant and known: 100
By subtracting from the above row I am looking to insert these values
B =
63 65 75 89 100
E.g. 100-11 = 89. 89-14=75
To ultimately give the following:
[A;B]
ans =
5 2 10 14 11
63 65 75 89 100
Any suggestions?
You can use the cumulative summation of the elements of A, via the MATLAB function cumsum, in order to perform this calculation:
knownvalue = 100;
firstrow = [5 2 10 14 11]
secondrow = fliplr(knownvalue - cumsum([0 firstrow(end:-1:2)]))
I believe what you are after is this:
A = [5, 2, 10, 14, 11];
Soln = [A; 100 * ones(1, length(A))];
Soln(2, 1:end - 1) = 100 - fliplr(cumsum(fliplr(A(2:end))));
EDIT: Probably go with cjh's solution (+1 for it). It requires one less call to fliplr so is probably faster.
I want to cluster an array, this array contain some angle I want to calculate the difference between of these degree and select one group between this array, this group should have maximum number and the difference between the member of that should not be larger than specific number.
for example if specific number is 30
and array is
[10 20 30 40 100 120 140]
answer should be
[10 20 30 40]
100-30 >= 30 so it is not included.
A one-line solution:
a = [10 20 30 40 100 120 140];
s = 30;
b = a( abs(a-s) < s )
a = [10 20 30 40 100 120 140]; #initial array
b = []; #result array
s = 30;
for i = 1:length(a)
if abs(a(i) - s) < s
b = [b a(i)];
end
end