This question already has answers here:
Grouping matrix rows in terms of one column
(2 answers)
Closed 9 years ago.
How can I calculate the mean of a group of rows and put the in a matrix such as:
1 4 5
1 34 4
1 65 0
1 5 3
2 3 44
2 52 4
2 5 6
3 9 2
3 9 1
3 9 9
So I can have a matrix as
1 27 4
2 20 18
3 9 4
Thx
Assuming original data is in matrix A:
indx=unique(A(:,1));
for ii=1:numel(indx)
RowMean(ii,:)=mean(A(1,:)==indx(ii),:);
end
Related
Consider the matrix:
1 2 3
4 5 6
7 8 9
I'd like to take the middle column, assign it to a variable, and replace the middle row with it, giving me
1 2 3
2 5 8
7 8 9
I'm extracting the middle column using
a:m[;enlist1]
which returns
2
5
8
How do I replace the middle row with a? Is a flip necessary?
Thanks.
If you want to update the matrix in place you can use
q)show m:(3;3)#1+til 10
1 2 3
4 5 6
7 8 9
q)a:m[;1]
q)m[1]:a
q)show m
1 2 3
2 5 8
7 8 9
q)
cutting out "a" all you need is:
m[1]:m[;1]
You can use dot amend -
q)show m:(3;3)#1+til 10
1 2 3
4 5 6
7 8 9
q)show a:m[;1]
2 5 8
q).[m;(1;::);:;a]
1 2 3
2 5 8
7 8 9
Can see documentation here:
http://code.kx.com/wiki/Reference/DotSymbol
http://code.kx.com/wiki/JB:QforMortals2/functions#Functional_Forms_of_Amend
Making it slightly more generic where you can define the operation, row, and column
q)m:3 cut 1+til 9
1 2 3
4 5 6
7 8 9
Assigning the middle column to middle row :
q){[ m;o;i1;i2] .[m;enlist i1;o; flip[m] i2 ] }[m;:;1;1]
1 2 3
2 5 8
7 8 9
Adding the middle column to middle row by passing o as +
q){[ m;o;i1;i2] .[m;enlist i1;o; flip[m] i2 ] }[m;+;1;1]
1 2 3
6 10 14
7 8 9
Given two parameters:
n %number of repetitions per value
k %max value to repeat
I would like to create a vector of size n*k, which is a concatenation of k vectors of size n, such that the i'th vector contains the value i at each coordinate.
Example:
n = 5;
k = 9;
Desired result:
[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,9];
Is there an elegant way to achieve this?
Thanks!
quite a few ways to do it:
method 1:
A=1:k
repelem(A',n,1)'
method 2:
A=1:k
kron(A', ones(n,1))'
method 3:
A=1:k
B=repmat(A, n, 1)
B(:)'
method 4:
A=1:k
B=ones(n,1)*A
B(:)'
Here is an alternative method
A = reshape(mtimes((1:k).',ones(1,n)).',1,n*k)
A =
Columns 1 through 22
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5
Columns 23 through 44
5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8 9 9 9 9
Column 45
9
It multiplies each element by ones n times
>> mtimes((1:k).',ones(1,5)).'
ans =
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
and then reshapes the whole matrix to one vector
I currently have a 3 by 3 matrix "m":
1 2 3
4 5 6
7 8 9
I would like to add a row to matrix 'm' to have a resultant matrix of:
1 2 3
4 5 6
7 8 9
10 11 12
A matrix in q is just a list of lists where inner lists represent rows.
m: ((1 2 3);(4 5 6);(7 8 9))
In order to add one more row all you have to do is add one more inner list to it:
m: m,enlist 10 11 12
enlist is important here, without it you'll end up with this:
q)((1 2 3);(4 5 6);(7 8 9)),10 11 12
1 2 3
4 5 6
7 8 9
10
11
12
I agree; using 0N!x to view the structure is very useful.
To achieve what you want then you can simply do;
q)show m:3 cut 1+til 9 /create matrix
1 2 3
4 5 6
7 8 9
q)show m,:10 11 12 /join new 'row'
1 2 3
4 5 6
7 8 9
10 11 12
q)
This question already has answers here:
Sorting entire matrix according to one column in matlab
(2 answers)
Closed 7 years ago.
In Matlab, how would I sort the 6th column where the 6th column represents a top score:
8 5 2 9 5 0
4 6 4 9 3 1
5 2 3 1 8 1
8 3 2 1 6 10
To form an output of:
8 3 2 1 6 10
5 2 3 1 8 1
4 6 4 9 3 1
8 5 2 9 5 0
Assuming your matrix is called A,
B = sortrows(A, -6)
Should do a descending order sort based on the 6th column.
See this matlab documentation for more information.
Anybody know a fast way to produce a matrix consisting of a linspace for each row? For example, the sort of pattern I'm looking for in this matrix is:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
...
1 2 3 4 5 6 7 8 9 10
Anyone know any fast tricks to produce this WITHOUT using a for loop?
I just figured this out, so just in case anyone else was troubled by this, we can achieve this exact pattern by:
a=linspace(1,10,10);
b=ones(3,1)*a;
This will give:
>> a = 1 2 3 4 5 6 7 8 9 10
>> b = 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You need to use repmat.
Example:
>> B = repmat(1:10,[3 1])
B =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You can vary the value of 3 there. You can change it accordingly.
Another shortcut I can recommend is similar to repmat, but you specify a base array first of a = 1:10;. Once you do this, you specify a series of 1s in the first dimension when indexing which should produce a matrix of the same vectors with many rows as you want, where each row consists of the base array a. As such:
%// number of times to replicate
n = 4;
a = 1:10;
a = a(ones(1,n),:);
Result:
a =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Insert this command: transpose(ndgrid(1:10,1:n));, where n is the number of rows desired in the result.
You can consider these solutions:
With basic matrix indexing (taken from here)
b=a([1:size(a,1)]' * ones(1,NumToReplicate), :) %row-wise replication
b=a(:, ones(NumToReplicate, 1)) %column-wise replication
With bsxfun:
bsxfun(#times,a,(ones(1,NumToReplicate))') %row-wise replication
bsxfun(#times,a',(ones(1,NumToReplicate))) %column-wise replication
You are welcome to benchmark above two solutions with repmat.