矩阵
DolphinDB 矩阵中的每一列都是一维数组。矩阵中行和列的下标都是从0开始。
创建矩阵
用函数 matrix 创建一个矩阵
// 创建一个整数矩阵,所有值都设为默认值0。
matrix(INT, 2, 3);
#0 | #1 | #2 |
---|---|---|
0 | 0 | 0 |
0 | 0 | 0 |
// 创建一个 SYMBOL 矩阵,所有值都设为默认值 NULL
matrix(SYMBOL, 2, 3);
#0 | #1 | #2 |
---|---|---|
函数 matrix 可以创建包含向量、矩阵、表、元组及这些数据组合的混合数据的矩阵。
matrix(1 2 3);
#0 |
---|
1 |
2 |
3 |
matrix([1],[2])
#0 | #1 |
---|---|
1 | 2 |
matrix(1 2 3, 4 5 6);
#0 | #1 |
---|---|
1 | 4 |
2 | 5 |
3 | 6 |
matrix(table(1 2 3 as id, 4 5 6 as value));
#0 | #1 |
---|---|
1 | 4 |
2 | 5 |
3 | 6 |
matrix([1 2 3, 4 5 6]);
#0 | #1 |
---|---|
1 | 4 |
2 | 5 |
3 | 6 |
matrix([1 2 3, 4 5 6], 7 8 9);
#0 | #1 | #2 |
---|---|---|
1 | 4 | 7 |
2 | 5 | 8 |
3 | 6 | 9 |
matrix([1 2 3, 4 5 6], 7 8 9, table(0.5 0.6 0.7 as id), 1..9$3:3);
#0 | #1 | #2 | #3 | #4 | #5 | #6 |
---|---|---|---|---|---|---|
1 | 4 | 7 | 0.5 | 1 | 4 | 7 |
2 | 5 | 8 | 0.6 | 2 | 5 | 8 |
3 | 6 | 9 | 0.7 | 3 | 6 | 9 |
函数 cast(X, m:n) 把一个向量X转换为一个m×n的矩阵。
m=1..10$5:2;
m;
#0 | #1 |
---|---|
1 | 6 |
2 | 7 |
3 | 8 |
4 | 9 |
5 | 10 |
cast(m,2:5);
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 3 | 5 | 7 | 9 |
2 | 4 | 6 | 8 | 10 |
用函数 setIndexedMatrix! 可以将矩阵的行与列标签设为索引,即生成一个索引矩阵。
m = matrix(1..5, 6..10);
m.rename!(2021.01.01..2021.01.05, `A`B);
m.setIndexedMatrix!();
输出返回:
label | A | B |
---|---|---|
2021.01.01 | 1 | 6 |
2021.01.02 | 2 | 7 |
2021.01.03 | 3 | 8 |
2021.01.04 | 4 | 9 |
2021.01.05 | 5 | 10 |
函数 indexedSeries 创建一个索引序列,可以视为特殊的矩阵。
m = indexedSeries(2012.01.01..2012.01.04, [10, 20, 30, 40]);
m;
label | col1 |
---|---|
2012.01.01 | 10 |
2012.01.02 | 20 |
2012.01.03 | 30 |
2012.01.04 | 40 |
DolphinDB 是列式数据库系统,在内存中以列为单位连续储存数据。DolphinDB 从左向右以列为单位填充矩阵中的元素。
使用 rename! 函数给矩阵增加行标签和列标签。
m1=1..9$3:3;
m1;
#0 | #1 | #2 |
---|---|---|
1 | 4 | 7 |
2 | 5 | 8 |
3 | 6 | 9 |
m1.rename!(`col1`col2`col3);
col1 | col2 | col3 |
---|---|---|
1 | 4 | 7 |
2 | 5 | 8 |
3 | 6 | 9 |
m1.rename!(1 2 3, `c1`c2`c3);
1 | 1 | 4 | 7 |
2 | 2 | 5 | 8 |
3 | 3 | 6 | 9 |
m1.colNames();
["c1","c2","c3"]
m1.rowNames();
[1,2,3]
重新排列矩阵
访问矩阵
检查维度 ( shape),行数( rows)和列数 ( cols):
m=1..10$2:5;
shape m;
2 : 5
rows m
2
cols m
5
有两种获得某个单元格的值的方式:m.cell(row, col) 和 m[row, col]。
m=1..12$4:3;
m;
#0 | #1 | #2 |
---|---|---|
1 | 5 | 9 |
2 | 6 | 10 |
3 | 7 | 11 |
4 | 8 | 12 |
m[1,2];
10
m.cell(1,2);
10
有两种取得某一列的值的方式:第一种是 m.col(index),其中 index 可以是数据对或者标量;第二种是 m[index] 或 m[, index],其中 index 可以是标量、数据对或者是向量。
m=1..12$4:3;
m;
#0 | #1 | #2 |
---|---|---|
1 | 5 | 9 |
2 | 6 | 10 |
3 | 7 | 11 |
4 | 8 | 12 |
m[1];
[5,6,7,8]
// 选出第1列生成一个向量。
m[,1];
// 选出第1列生成一个子矩阵。
#0 |
---|
5 |
6 |
7 |
8 |
m.col(2);
[9,10,11,12]
// 选出第2列。
m[2:0];
// 选出第0,1列。
#0 | #1 |
---|---|
5 | 1 |
6 | 2 |
7 | 3 |
8 | 4 |
m[1:3];
// 选出第1,2列。
#0 | #1 |
---|---|
5 | 9 |
6 | 10 |
7 | 11 |
8 | 12 |
m[0 2];
//选出第0列和第2列。
#0 | #1 |
---|---|
1 | 9 |
2 | 10 |
3 | 11 |
4 | 12 |
有两种取得某一行的值的方式:第一种是 m.row(index) ,其中 index 可以是数据对或者标量;第二种是 m[index, ],其中 index 可以是标量、数据对或者是向量。
m=1..12$3:4;
m;
#0 | #1 | #2 | #3 |
---|---|---|---|
1 | 4 | 7 | 10 |
2 | 5 | 8 | 11 |
3 | 6 | 9 | 12 |
m[0,];
// 返回第0行,类型为矩阵。
#0 | #1 | #2 | #3 |
---|---|---|---|
1 | 4 | 7 | 10 |
flatten(m[0,]);
// 用 flatten 函数将一个矩阵转化为向量。
[1,4,7,10]
m.row(2);
// 选出第2行。
[3,6,9,12]
m[1:3, ];
// 选出第1,2行。
#0 | #1 | #2 | #3 |
---|---|---|---|
2 | 5 | 8 | 11 |
3 | 6 | 9 | 12 |
m[3:1, ];
// 选出第2,1行。
#0 | #1 | #2 | #3 |
---|---|---|---|
3 | 6 | 9 | 12 |
2 | 5 | 8 | 11 |
m[0 2,0..3];
//选出第0行和第2行。
#0 | #1 | #2 | #3 |
---|---|---|---|
1 | 4 | 7 | 10 |
3 | 6 | 9 | 12 |
有两种取得子矩阵的方式:第一种是 m.slice(rowIndex,colIndex) 或 m[rowIndex,colIndex],其中collndex 和 rowIndex 是标量、向量或数据对。如果 colIndex 和 rowIndex 是数据对,那么上限边界值不包含在内。
m=1..12$3:4;
m;
#0 | #1 | #2 | #3 |
---|---|---|---|
1 | 4 | 7 | 10 |
2 | 5 | 8 | 11 |
3 | 6 | 9 | 12 |
m.slice(0:2,1:3);
#0 | #1 |
---|---|
4 | 7 |
5 | 8 |
m[1:3,0:2];
// 选出第1,2行,第0,1列。
#0 | #1 |
---|---|
2 | 5 |
3 | 6 |
m[1:3,2:0];
// 选出第1,2行,第1,0列
#0 | #1 |
---|---|
5 | 2 |
6 | 3 |
m[3:1,2:0];
// 选出第2,1行,第1,0列
#0 | #1 |
---|---|
6 | 3 |
5 | 2 |
m[0 2,1 3];
//选出第0,2行,第1,3列
#0 | #1 |
---|---|
4 | 10 |
6 | 12 |
m[2 1,1 3];
//选出第2,1行,第1,3列
#0 | #1 |
---|---|
6 | 12 |
5 | 11 |
修改矩阵
当我们追加一个向量到矩阵时,向量的长度必须是矩阵行数的倍数。
m=1..6$2:3;
m;
#0 | #1 | #2 |
---|---|---|
1 | 3 | 5 |
2 | 4 | 6 |
append!(m, 7 9);
#0 | #1 | #2 | #3 |
---|---|---|---|
1 | 3 | 5 | 7 |
2 | 4 | 6 | 9 |
append!(m, 8 6 1 2);
// 追加2列到m
#0 | #1 | #2 | #3 | #4 | #5 |
---|---|---|---|---|---|
1 | 3 | 5 | 7 | 8 | 1 |
2 | 4 | 6 | 9 | 6 | 2 |
append!(m, 3 4 5);
// 要追加的向量长度必须能被矩阵的行数除尽。
2.00.4及之后的版本,支持使用 m[condition]=X 来修改某些符合条件的值。condition 是一个同 m 具有相同维度的布尔矩阵。X 是一个标量或向量,当 X 是向量时,长度必须与 condition 中 true 值的个数相同。
a = 1..12$3:4
a[a<5]=5
#0 | #1 | #2 | #3 |
---|---|---|---|
5 | 5 | 7 | 10 |
5 | 5 | 8 | 11 |
5 | 6 | 9 | 12 |
使用 m[index]=X 来修改某一列,X 是一个标量或者向量。
t1=1..50$10:5;
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 11 | 21 | 31 | 41 |
2 | 12 | 22 | 32 | 42 |
3 | 13 | 23 | 33 | 43 |
4 | 14 | 24 | 34 | 44 |
5 | 15 | 25 | 35 | 45 |
6 | 16 | 26 | 36 | 46 |
7 | 17 | 27 | 37 | 47 |
8 | 18 | 28 | 38 | 48 |
9 | 19 | 29 | 39 | 49 |
10 | 20 | 30 | 40 | 50 |
t1[1]=200;
// 给第1列赋值200
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 200 | 21 | 31 | 41 |
2 | 200 | 22 | 32 | 42 |
3 | 200 | 23 | 33 | 43 |
... | ... | ... | ... | ... |
t1[1]+=200;
// 给第1列加200
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 400 | 21 | 31 | 41 |
2 | 400 | 22 | 32 | 42 |
3 | 400 | 23 | 33 | 43 |
... | ... | ... | ... | ... |
t1[1]=31..40;
// 将31..40的序列追加到第1列
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 31 | 21 | 31 | 41 |
2 | 32 | 22 | 32 | 42 |
3 | 33 | 23 | 33 | 43 |
... | ... | ... | ... | ... |
使用 m[index] = X 来修改多个列,其中 index 是向量,X 是一个标量或者向量。
t1=1..20$4:5;
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 5 | 9 | 13 | 17 |
2 | 6 | 10 | 14 | 18 |
3 | 7 | 11 | 15 | 19 |
4 | 8 | 12 | 16 | 20 |
t1[0 2 4]=101..112;
// 将序列101..112 赋值给第0,2,4列
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
101 | 5 | 105 | 13 | 109 |
102 | 6 | 106 | 14 | 110 |
103 | 7 | 107 | 15 | 111 |
104 | 8 | 108 | 16 | 112 |
... | ... | ... | ... | ... |
t1[4 2 0]=101..112;
// 将序列101..112赋值给第4,2,0列
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
109 | 5 | 105 | 13 | 101 |
110 | 6 | 106 | 14 | 102 |
111 | 7 | 107 | 15 | 103 |
112 | 8 | 108 | 16 | 104 |
... | ... | ... | ... | ... |
t1[4 2 0]+=100;
// 第4,2,0列的每个元素加100
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
209 | 5 | 205 | 13 | 201 |
210 | 6 | 206 | 14 | 202 |
211 | 7 | 207 | 15 | 203 |
212 | 8 | 208 | 16 | 204 |
... | ... | ... | ... | ... |
使用 m[start:end] = X 来修改多个列,X 是一个标量或者向量。
t1=1..50$10:5;
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 11 | 21 | 31 | 41 |
2 | 12 | 22 | 32 | 42 |
3 | 13 | 23 | 33 | 43 |
4 | 14 | 24 | 34 | 44 |
5 | 15 | 25 | 35 | 45 |
6 | 16 | 26 | 36 | 46 |
7 | 17 | 27 | 37 | 47 |
8 | 18 | 28 | 38 | 48 |
9 | 19 | 29 | 39 | 49 |
10 | 20 | 30 | 40 | 50 |
t1[1:4]=101..130;
// 追加向量101..130到第1,2,3列
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 101 | 111 | 121 | 41 |
2 | 102 | 112 | 122 | 42 |
3 | 103 | 113 | 123 | 43 |
... | ... | ... | ... | ... |
t1[4:1]=101..130;
// 追加向量101..130到第3,2,1列
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 121 | 111 | 101 | 41 |
2 | 122 | 112 | 102 | 42 |
3 | 123 | 113 | 103 | 43 |
... | ... | ... | ... | ... |
t1[4:1]+=100;
// 第3,2,1列的每个元素加100
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 221 | 211 | 201 | 41 |
2 | 222 | 212 | 202 | 42 |
3 | 223 | 213 | 203 | 43 |
... | ... | ... | ... | ... |
使用 m[index,] = X 修改某行,X 是一个标量或者向量。
t1=1..50$10:5;
// 赋值100到第1行
t1[1,]=100;
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 11 | 21 | 31 | 41 |
100 | 100 | 100 | 100 | 100 |
3 | 13 | 23 | 33 | 43 |
... | ... | ... | ... | ... |
t1[1,]+=100;
// 给第1行加100
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 11 | 21 | 31 | 41 |
200 | 200 | 200 | 200 | 200 |
3 | 13 | 23 | 33 | 43 |
... | ... | ... | ... | ... |
使用 m[start:end,] = X 修改多行,X 是一个标量或者向量。
t1=1..50$10:5;
t1[1:4,]=101..115;
// 将序列101..115赋值给第1,2,3行
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 11 | 21 | 31 | 41 |
101 | 104 | 107 | 110 | 113 |
102 | 105 | 108 | 111 | 114 |
103 | 106 | 109 | 112 | 115 |
... | ... | ... | ... | ... |
t1[4:1, ]=101..115;
// 将序列101..115赋值给第3,2,1行
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 11 | 21 | 31 | 41 |
103 | 106 | 109 | 112 | 115 |
102 | 105 | 108 | 111 | 114 |
101 | 104 | 107 | 110 | 113 |
... | ... | ... | ... | ... |
使用 m[r1:r2, c1:c2] = X 来修改矩阵窗口,X 是一个标量或者向量。
t1=1..50$5:10;
t1[1:3,5:10]=101..110;
// 将序列101..110赋值给矩阵的第1,2行和第5~9列的窗口
t1;
#0 | #1 | #2 | #3 | #4 | #5 | #6 | #7 | #8 | #9 |
---|---|---|---|---|---|---|---|---|---|
1 | 6 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 |
2 | 7 | 12 | 17 | 22 | 101 | 103 | 105 | 107 | 109 |
3 | 8 | 13 | 18 | 23 | 102 | 104 | 106 | 108 | 110 |
4 | 9 | 14 | 19 | 24 | 29 | 34 | 39 | 44 | 49 |
5 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 |
t1=1..50$10:5;
t1[5:10, 3:1]=101..110;
// 将序列101..110赋值给矩阵的第5~9行和第2~1列的窗口
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
... | ... | ... | ... | ... |
6 | 106 | 101 | 36 | 46 |
7 | 107 | 102 | 37 | 47 |
8 | 108 | 103 | 38 | 48 |
9 | 109 | 104 | 39 | 49 |
10 | 110 | 105 | 40 | 50 |
t1[10:5, 1:3]+=10;
// 给矩阵的第9~5行,第1~2列加10
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1 | 11 | 21 | 31 | 41 |
2 | 12 | 22 | 32 | 42 |
3 | 13 | 23 | 33 | 43 |
4 | 14 | 24 | 34 | 44 |
5 | 15 | 25 | 35 | 45 |
6 | 116 | 111 | 36 | 46 |
7 | 117 | 112 | 37 | 47 |
8 | 118 | 113 | 38 | 48 |
9 | 119 | 114 | 39 | 49 |
10 | 120 | 115 | 40 | 50 |
使用m[rowIndex,colIndex] = X 来修改多个单元格,其中 rowIndex 和 colIndex 可以是标量或者向量,X 是一个标量或者向量。
t1=1..20$4:5
t1[0 2, 0 2]=101;
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
101 | 5 | 101 | 13 | 17 |
2 | 6 | 10 | 14 | 18 |
101 | 7 | 101 | 15 | 19 |
4 | 8 | 12 | 16 | 20 |
t1[2 0, 2 0]=1001..1004;
t1;
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
1004 | 5 | 1002 | 13 | 17 |
2 | 6 | 10 | 14 | 18 |
1003 | 7 | 1001 | 15 | 19 |
4 | 8 | 12 | 16 | 20 |
按列对矩阵进行过滤
可以使用 lambda 表达式对矩阵的每一个列进行过滤。注意,按列对矩阵进行过滤时,lambda 表达式只能接受一个参数,并且返回的结果必须是 BOOL 类型的标量。
m=matrix(0 2 3 4,0 0 0 0,4 7 8 2);
m[x->!all(x==0)];
//返回矩阵中不全为0的列
#0 | #1 |
---|---|
0 | 4 |
2 | 7 |
3 | 8 |
4 | 2 |
m=matrix(0 2 3 4,5 3 6 9,4 7 8 2);
m[def (x):avg(x)>4];
//返回矩阵中均值大于4的列
#0 | #1 |
---|---|
5 | 4 |
3 | 7 |
6 | 8 |
9 | 2 |
对矩阵进行操作
矩阵和标量的操作:
m=1..10$5:2;
m;
#0 | #1 |
---|---|
1 | 6 |
2 | 7 |
3 | 8 |
4 | 9 |
5 | 10 |
2.1*m;
// 给矩阵中的每个元素乘2.1
#0 | #1 |
---|---|
2.1 | 12.6 |
4.2 | 14.7 |
6.3 | 16.8 |
8.4 | 18.9 |
10.5 | 21 |
m\2;
#0 | #1 |
---|---|
0.5 | 3 |
1 | 3.5 |
1.5 | 4 |
2 | 4.5 |
2.5 | 5 |
m+1.1;
#0 | #1 |
---|---|
2.1 | 7.1 |
3.1 | 8.1 |
4.1 | 9.1 |
5.1 | 10.1 |
6.1 | 11.1 |
m*NULL;
// 结果是一个NULL INT的矩阵。
#0 | #1 |
---|---|
矩阵与向量的操作:
m=matrix(1 2 3, 4 5 6);
m;
#0 | #1 |
---|---|
1 | 4 |
2 | 5 |
3 | 6 |
m + 10 20 30;
#0 | #1 |
---|---|
11 | 14 |
22 | 25 |
33 | 36 |
m * 10 20 30;
#0 | #1 |
---|---|
10 | 40 |
40 | 100 |
90 | 180 |
矩阵之间的操作:
m1=1..10$2:5
m2=11..20$2:5;
m1+m2;
// 元素逐个相加
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
12 | 16 | 20 | 24 | 28 |
14 | 18 | 22 | 26 | 30 |
m1-m2;
// 元素逐个相减
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
-10 | -10 | -10 | -10 | -10 |
-10 | -10 | -10 | -10 | -10 |
m1*m2;
// 元素逐个相乘
#0 | #1 | #2 | #3 | #4 |
---|---|---|---|---|
11 | 39 | 75 | 119 | 171 |
24 | 56 | 96 | 144 | 200 |
// 转换矩阵m2
m2 = transpose(m2);
// 矩阵相乘
m1**m2;
#0 | #1 |
---|---|
415 | 440 |
490 | 520 |
用函数处理矩阵
矩阵是一个特殊的向量,所以大部分向量的函数都适用于矩阵。
m=1..6$2:3;
m;
#0 | #1 | #2 |
---|---|---|
1 | 3 | 5 |
2 | 4 | 6 |
// 每列的平均值
avg(m);
[1.5,3.5,5.5]
// 每列的总和
sum(m);
[3,7,11]
// 每个元素的余弦值
cos m;
#0 | #1 | #2 |
---|---|---|
0.540302 | -0.989992 | 0.283662 |
-0.416147 | -0.653644 | 0.96017 |
亦可用高阶函数 each 来计算每一个列的平均值。
与矩阵相关的函数
矩阵专用函数有:
m=1..4$2:2;
transpose m;
#0 | #1 |
---|---|
1 | 2 |
3 | 4 |
inv(m);
#0 | #1 |
---|---|
-2 | 1.5 |
1 | -0.5 |
det(m);
-2
// solving m*x=[1,2]
m.solve(1 2);
[1,0]
y=(1 0)$2:1;
y;
#0 |
---|
1 |
0 |
m**y;
#0 |
---|
1 |
2 |
diag(1 2 3);
#0 | #1 | #2 |
---|---|---|
1 | 0 | 0 |
0 | 2 | 0 |
0 | 0 | 3 |