Array sorting in matlab - arrays

Hi i have a 289x2 array that i want to sort in MatLab. I want to sort the first column into numerical ascending order. However I want to keep the second column entry that is associated with it. Best way to explain is through an example.
x = 76 1
36 2
45 3
Now I want to sort x so that it returns an array that looks like:
x = 36 2
45 3
76 1
So the first column has been sorted into numerical order but has retained its second column value. So far I have tried sort(x,1). This sorts the first column as i want but does not keep the pairing. This returns x as:
x = 36 1
45 2
76 3
Any help would be great. Cheers!!

This is exactly what sortrows does.
x=sortrows(x); % or x=sortrows(x,1);
or if you want to use sort then get the sorted indexes first and then arrange the rows accordingly like this:
[~, idx] = sort(x); %Finding the sorted indexes
x = x(idx(:,1),:) ; %Arranging according to the indexes of the first column
Output for both approaches:
x =
36 2
45 3
76 1

Related

Add Countif to Array Formula (Subtotal) in Excel

I am new to array formulae and have noticed that while SUBTOTAL includes many functions, it does not feature COUNTIF (only COUNT and COUNTA).
I'm trying to figure out how I can integrate a COUNTIF-like feature to my array formula.
I have a matrix, a small subset of which looks like:
A B C D E
48 53 46 64 66
48 66 89
40 38 42 49 44
37 33 35 39 41
Thanks to the help of #Tom Shape in this post, I (he) was able to average the sum of each row in the matrix provided it had complete data (so rows 2 and 4 in the example above would not be included).
Now I would like to count the number of rows with complete data (so rows 2 and 4 would be ignored) which include at least one value above a given threshold (say 45).
In the current example, the result would be 2, since row 1 has 5/5 values > 45, and row 3 has 1 value > 45. Row 5 has values < 45 and rows 2 and 3 have partially or fully missing data, respectively.
I have recently discovered the SUMPRODUCT function and think that perhaps SUMPRODUCT(--(A1:E1 >= 45 could be useful but I'm not sure how to integrate it within Tom Sharpe's elegant code, e.g.,
=AVERAGE(IF(SUBTOTAL(2,OFFSET(A1,ROW(A1:A5)-ROW(A1),0,1,COLUMNS(A1:E1)))=COLUMNS(A1:E1),SUBTOTAL(9,OFFSET(A1,ROW(A1:A5)-ROW(A1),0,1,COLUMNS(A1:E1))),""))
Remember, I am no longer looking for the average: I want to filter rows for whether they have full data, and if they do, I want to count rows with at least 1 entry > 45.
Try the following. Enter as array formula.
=COUNT(IF(SUBTOTAL(4,OFFSET(A1,ROW(A1:A5)-ROW(A1),0,1,COLUMNS(A1:E1)))>45,IF(SUBTOTAL(2,OFFSET(A1,ROW(A1:A5)-ROW(A1),0,1,COLUMNS(A1:E1)))=COLUMNS(A1:E1),SUBTOTAL(9,OFFSET(A1,ROW(A1:A5)-ROW(A1),0,1,COLUMNS(A1:E1))))))
Data

Matlab: Creating a blockwise permutation

I have a vector from 1 to 40 and want to shuffle it in such a way that each block of four integers (ten blocks in total) are shuffled only with themselves.
For example: 3 4 2 1 | 7 6 5 8 | 9 11 10 12 | ...
My original idea was to append ten permutation vectors to eachother and then add a 1 to 40 vector to the big permutation vector, but it didn't work at all as expected and was logically wrong.
Has anyone an idea how to solve this?
data = 10:10:120; % input: values to be permuted
group_size = 4; % input: group size
D = reshape(data, group_size, []); % step 1
[~, ind] = sort(rand(size(D)), 1); % step 2
result = D(bsxfun(#plus, ind, (0:size(D,2)-1)*group_size)); % step 3
result = result(:).'; % step 4
Example result:
result =
20 10 30 40 60 50 70 80 110 100 120 90
How it works
Reshape the data vector into a matrix D, such that each group is a column. This is done with reshape.
Generate a matrix, ind, where each column contains the indices of a permutation of the corresponding column of D. This is done generating independent, uniform random values (rand), sorting each column, and getting the indices of the sorting (second output of sort).
Apply ind as column indices into D. This requires converting to linear indices, which can be done with bsxfun (or with sub2ind, but that's usually slower).
Reshape back into a vector.
You can use A = A(randperm(length(A))) to shuffle an array.
Example in Octave:
for i = 1:4:40
v(i:i+3) = v(i:i+3)(randperm(4));
end

Delete first n rows in column vector in Matlab & call array rows by an array of indices

I have 2 questions.
Question 1:
I have a column vector, v, with (say) 1000 rows. I want to delete first (say) n rows (for example n=300 to remove the first 300 rows of v).
Question 2:
I have an array of indices. How can it be used to get rows of another array whose index values are in first array?
I = [ 1 2 4 5] %// array of indices
Q = [ 45 22 66 87 99 10 ] %// input array
Desired Output:
O = [45 22 87 99] %// output array
For you first question:
N=300;
v=rand(1000,1); %// sample data
v(1:N)=[];
And the second:
O=Q(I)

Associating / linking an array column with another column in the array

I have an array that has some calcultations done on the second column. I would like the values from the third column to follow/be linked to the second column.
Test Code:
a1= [1,10,-11;
2,70,232;
3,33.2,-33;
4,40,44;]
a2calc=abs(a1(:,2)-max(a1(:,2))) %calculation
a2=[a1(:,1),a2calc,a1(:,3)] %new array
Example:
original a1 Array
1 10 -11
2 70 232
3 33.2 -33
4 40 44
a2 Array after column 2 calculations looks like this
1 60 -11
2 0 232
3 36.8 -33
4 30 44
I'm trying to get the final array to look like this (column 3 values follow / are linked to the second column)
1 60 232
2 0 -11
3 36.8 44
4 30 -33
What I'm having problems with is I'm not sure if I should use the index values of column 2 and if so how I can get it to look like the final output array I included in the question.
I might be wrong here, but it looks to me like the logic is:
After calculating the second column, change the order of the third column so that the third column is sorted the same way as the second. To see what I mean:
This represents the two columns, numbered from highest to lowest:
A = 1 1
4 3
2 2
3 4
If I understand it right, you want the resulting matrix to be
A = 1 1
4 4
2 2
3 3
If this is the right logic then you should check out sort with two outputs. You can use the second output to index the third column.
[~, idx] = sort(A(:, 2));
sorted_3 = sort(A(:, 3));
A(idx, 3) = sorted_3;
The output from this is:
A =
1.00000 60.00000 232.00000
2.00000 0.00000 -33.00000
3.00000 36.80000 44.00000
4.00000 30.00000 -11.00000
Good luck!

To get index of an sorted array into another array in C

I have 2 arrays say
sum:
68
78
25
45
85
Index:
0
1
2
3
4
I did bubble sort on sum and got as:
25
45
68
78
85
Now, I need to know sort index array with respect to the sum array. So, my output of array should be:
2
3
0
1
4
How can I do that?
I'd recommend you sort the index array instead, and have the comparisons made using the values the indexes "point" to. So then you don't actually need to sort the "value" array just the "index" array.
So, here is a very simple solution that I never thought of and all credits goes to my project supervisor.. and it is.
Sort both the arrays under the same loop.. Thus when ever I will refer to any index, it will give me the sorted version.

Resources