目录
1. 创建数组
1.1 直接创建
1. 2 利用函数创建
2. 数组索引
3. 数组操作
3.1 数组的信息
3.2 数组维度变化
3.3 数组的最大值和最小值
3.4 数组方差、均值、标准差、总和运算
3.5 数组元素筛选及重新赋值
3.6 数组元素的排序
3.7 数组间比较
4. 数组运算
4.1 加、减法运算
4.2 乘除运算
IDL 语言支持数组运算,创建、下标与Python一样,可以利用“[]”、函数进行创建,先列标,再行标,序号从0开始。
直接创建数组适合数据量少、无规律的数组。
>>a = [1]
>>help,a
A INT = Array[1]
>>b = 1
>>help,b
B INT = 1
>>print,size(a,/Type)
2
>>print,size(b,/Type)
2
分析:加上[]后,类型变为Array,而如果不加上,仅仅是一个数,但从其存储上看,两者没区别,因此,一个数也能视为一个1×1的数组,但对于含有多元素的数组来说,必须加上“[]”
>>c= 2,3
% Keyword C not allowed in call to: PRINT
% Execution halted at: $MAIN$
>>d = [2,3]
>>help,d
D INT = Array[2]
创建多维数组,每一行都需要加上[],没一个二维矩阵也要加上[],例如,
>>a = [[1,2,3],[3,2,1]]
>>help,a
A INT = Array[3, 2]
>>a
1 2 3
3 2 1
>>a.DIM
3 2
分析:数组a是一个3列2行的数组,每一行都加上[],这个与Matlab不同,和python语法一致。
>>b = [[[1,2,3],[3,2,1]],[[0,1,0],[0,2,4]]]
>>help,b
B INT = Array[3, 2, 2]
>>b
1 2 3
3 2 1
0 1 0
0 2 4
>>>>b.DIM
3 2 2
分析:数组a是一个3列2行2维度的数组,每一个二维数据都用“[]”括起来。
创建字符串数组,也可以用这种方法。
>>e = ['Hlz','Hulizhen']
>>e
Hlz
Hulizhen
>>help,e
E STRING = Array[2]
>>f = [['Hlz'],['Hulizhen']]
>>f
Hlz
Hulizhen
>>help,f
F STRING = Array[1, 2]
分析:e是2列1行的字符串数组,f是1列2行的数组。
这种方式适合数据量大、有规律的数组,常见的函数如下表所示。
数据类型 | 创建全0数组 | 创建索引数组 |
---|---|---|
Byte 字节 | byteArr() | bindgen() |
int 整型 16位(2×8) | intarr() | indgen() |
uint 无符号整型 | uintarr() | uindgen() |
long 长整型 | lonarr() | lindgen() |
ulong 无符号长整型 | ulongarr() | ulindgen() |
long64 64位长整型 | lon64arr() | l64indgen() |
ulong64 无符号64位长整型 | ulon64arr() | ul64indgen() |
float 浮点型 | fltarr() | findgen() |
double float 双精度浮点型 | dblarr() | dindgen() |
complex 复数 | complexarr() | cindgen() |
double complex 双精度复数 | dcomplex() | dcindgen() |
string 字符串 | strarr() | sindgen() |
ptr_new 指针 | ptrarr() | 无 |
obj_new 对象 | objarr() |
例如:创建一个4×3(3列4行)的全0整型数组a,可以用intarr()函数。
>>a = Intarr(3,4)
>>a
0 0 0
0 0 0
0 0 0
0 0 0
例如:创建一个4×3(3列4行)的索引整型数组b,可以用indgen()。
>>b = Indgen(3,4)
>>b
0 1 2
3 4 5
6 7 8
9 10 11
例如:创建一个2×3×4(2行3列4维)的索引数组c,可以用indgen()。
>>c = Indgen(3,2,4)
>>c
0 1 2
3 4 5
6 7 8
9 10 11
12 13 14
15 16 17
18 19 20
21 22 23
等差数组:可以在索引数组的基础上利用数组运算在创建等差数列数组
>>d =Indgen(3,4)
>>d
0 1 2
3 4 5
6 7 8
9 10 11
>>e = d+1
>>e
1 2 3
4 5 6
7 8 9
10 11 12
>>f = e*2
>>f
2 4 6
8 10 12
14 16 18
20 22 24
元素相同的数组:可以在全0数组的基础上利用数组运算在创建等差数列数组,也可以利用replicate(Value,d1[,...,d8])
>>g = Intarr(2,3)
>>g
0 0
0 0
0 0
>>h = g+5
>>h
5 5
5 5
5 5
>>i = Replicate(5,2,3)
>>i
5 5
5 5
5 5
此外,还可以利用make_array()函数创建,具体用法,此处不具体展开。
语法:Result = MAKE_ARRAY ( [D1[, ..., D8]], DIMENSION=vector, INCREMENT=value, /INDEX, /NOZERO, SIZE=vector, START=value, TYPE=type_code, VALUE=value, /BOOLEAN, /BYTE, /COMPLEX, /DCOMPLEX, /DOUBLE, /FLOAT, /INTEGER, /L64, /LONG, /OBJ, /PTR, /STRING, /UINT, /UL64, /ULONG )
>>j = MAKE_ARRAY(2, 3, /INTEGER, VALUE = 5)
>>j
5 5
5 5
5 5
IDL语言不同于Matlab,其下标是从0开始计算的,并且多维数组顺序为,列、行、维。
>>a = Indgen(3,2,4)
>>a
0 1 2
3 4 5
6 7 8
9 10 11
12 13 14
15 16 17
18 19 20
21 22 23
>>a(0,0,0)
0
>>a(1,0,0)
1
>>a(2,0,0)
2
>>a(3,0,0)
% Attempt to subscript A with is out of range.
% Execution halted at: $MAIN$
分析:为什么 a(3,0,0)报错?因为是下标是从开始,多维的顺序是列、行、维,因此a(3,0,0)不存在。
注意:从IDL8.0开始,支持下标索引为负数,其表示从后往前数,向python看齐了!
>>a = Indgen(4,1)
>>a
0 1 2 3
>>a(-1,0)
3
每个数组都有行、列(可能还有维度)元素个数等信息,可以利用size()函数进行获取。
Result = SIZE( Expression [, /L64] [, /DIMENSIONS | , /FILE_LUN | , /FILE_OFFSET | , /N_DIMENSIONS | , /N_ELEMENTS | , /SNAME, | , /STRUCTURE | , /TNAME | , /TYPE] )
返回值:
依次表示:数度个数(一维、二维、……)、列(若不存在则不显示)、行(若不存在则不显示)、第三维(若不存在则不显示)、数据类型代码(int、long、……)、元素个数。
例如:一个数a(type)型,则显示维度个数、数据类型、元素个数
>>a = 1B
>>print,size(a)
0 1 1
例如:一个3×2的矩阵a(int型),其数组的信息为:
>>a = Indgen(2,3)+1
>>a
1 2
3 4
5 6
>>print,size(a) ;依次表示:数组类型(一维、二维、……)、列、行、数据类型代码(int、long、……)、元素个数
2 2 3
2 6
>>print,N_elements(a) ;元素个数
6
>>print,a.DIM ; 矩阵维度
2 3
>>print,Typename(a) ; 数据类型代码,0(不明确)、1(Byte)、2(int)、3(long)……
INT
例如:一个2×3的矩阵b(float)型,其数组的信息为:
>>b = [[1.0,2,3],[8,8,9]]
>>b
1.0000000 2.0000000 3.0000000
8.0000000 8.0000000 9.0000000
>>; 数据类型代码4对应的数据类型为float
>>print,Typename(b)
FLOAT
>>print,b.DIM
3 2
>>print,b.LENGTH ; 数据的长度
6
>>print,size(b)
2 3 2 4 6
>>; 分别表示矩阵的维度、列、行、数据类型代码、元素个数
例如:一个4×3×5的数组a(int),其数组的信息为:维度个数、列、行、第三维、数据类型代码,元素个数;
>>a = Indgen(3,4,5)
>>a
0 1 2
3 4 5
6 7 8
9 10 11
12 13 14
15 16 17
18 19 20
21 22 23
24 25 26
27 28 29
30 31 32
33 34 35
36 37 38
39 40 41
42 43 44
45 46 47
48 49 50
51 52 53
54 55 56
57 58 59
>>print,Size(a)
3 3 4 5 2 60
总结:数度个数(必须有)、列(若不存在则不显示)、行(若不存在则不显示)、第三维(若不存在则不显示)、数据类型代码(必须有)、元素个数(必须有)。
(1)选取数据:
可以通过下标进行选取数据,下标从0开始,度数表示反过来数,1
>>a = Indgen(2,4)
>>a
0 1
2 3
4 5
6 7
>>a[0:1,2:3]
4 5
6 7
>>a[0:1,-1]
6 7
>>a[1,0:-1] ;-1表示最后一个数;
1
3
5
7
>>a[1,0:-2] ;-2表示倒数第二个数
1
3
5
(2)维度调整:
可以通过Reform()函数改变数组的维度信息,先行后列的调整维度。
Result = REFORM( Array, D1[, ..., D8] [, /OVERWRITE] )
>>b = Reform(a,4,2)
>>b
0 1 2 3
4 5 6 7
(3)数组扩展
可以用Rebin()函数修改数组大小,修改后的行数、列数是原先行、列的整数倍,默认使用双线性内插的方法。
可以用Congrid()函数修改数组的大小,默认使用最近邻重采样。
可以用Interpolate()函数将数组调整同维度任意大小,并支持定向插值。
>>a = Indgen(2,3)+2
>>a
2 3
4 5
6 7
>>print,Rebin(a,4,9)
2 2 3 3
2 2 3 3
3 3 4 4
4 4 5 5
4 4 5 5
5 5 6 6
6 6 7 7
6 6 7 7
6 6 7 7
>>print,Congrid(a,3,4)
2 3 3
2 3 3
4 5 5
6 7 7
最大值函数max()、最小值函数min(),
Result = MAX( Array [, Max_Subscript] [, /ABSOLUTE] [, DIMENSION=value] [, MIN=variable] [, /NAN] [, SUBSCRIPT_MIN=variable])
Result = MIN( Array [, Min_Subscript] [, /ABSOLUTE] [, DIMENSION=value] [, MAX=variable] [, /NAN] [, SUBSCRIPT_MAX=variable])
注:数组中有空值的时候,可以用关键字/Nan,此时空值不计算
方差函数Variance()、均值函数Mean()、标准差Stddev()、求和函数Total()
Result = VARIANCE( X [, DIMENSION=value] [, /DOUBLE] [, /NAN] )
Result = MEAN( X [, DIMENSION=value] [, /DOUBLE] [, /NAN] )
Result = STDDEV( X [, DIMENSION=value] [, /DOUBLE] [, /NAN] )
Result = TOTAL( Array [, Dimension] [, /CUMULATIVE] [, /DOUBLE] [, /INTEGER] [, /NAN] [, /PRESERVE_TYPE] )
利用Eq等于、Lt小于、Gt大于、 LE小于等于、GE大于等于,可以判断符合条件元素对应的索引
>>a = [1,4,6,2,4,7,9,10]
>>a
1 4 6 2 4 7 9 10
>>print,a Gt 5
0 0 1 0 0 1 1 1
>>print,a lE 5
1 1 0 1 1 0 0 0
配合where()函数,可以提取满足条件的元素。
>>a = [1,4,6,2,4,7,9,10]
>>b = where(a Gt 5)
>>b
2 5 6 7
>>c = where(a le 5)
>>c
0 1 3 4
注:A>value、A (1)数据反转 Reverse()函数可以实现数据反转 Result = REVERSE( Array [, Subscript_Index] [, /OVERWRITE] ) (2)数据排序 Sort()函数实现数组元素的排序,返回排序的索引下标 注:要实现从大到小排序,可以配合反转函数Reverse(), Array_equal()函数可以用来比较两个数据是否一样! Result = ARRAY_EQUAL( Op1 , Op2, /NOT_EQUAL, /NO_TYPECONV, /QUIET ) (1)加减运算:IDL支持一个数与整个数组中的每个元素相加减,但不支持不同维度的数组相加。 分析:a是一个数,因此与数组c相加,得到的结果是c中的每一个元素都加上a这个数;b数一个1×1 的数组其与c数组的维度不一致,因此计算的结果不对,实际只计算了c中的第一个元素(因为b只有一个元素)。 减法和加法一样,如下所示。 (1)乘除运算:IDL乘法与Matlab不同,matlab中“.*”表示两个数组中对应位置的元素相乘,“*”表示两个矩阵相乘,而IDL中“*”表示两个数组中对应位置的元素相乘,“#”和“##”表示矩阵相乘,“A#B”表示A的列乘以B的行,因此A中的行数,必须等于B的列数;“A##B”表示A的行乘以B的列,因此A中的列数必须等于B中的行数(数学中的矩阵乘法); (2)幂运算: “*”表示两个矩阵相乘,但对于多次幂运算时A*A*A*A……太麻烦,因此用“^n”表示,Matlab用“.n”表示。 注:后续将针对整理数据相关的函数 不足之处,敬请斧正! 路漫漫其修远兮,吾将上下而求索>>a = [1,4,6,2,4,7,9,10]
>>a
1 4 6 2 4 7 9 10
>>print,a>5
5 5 6 5 5 7 9 10
>>print,a < 5
1 4 5 2 4 5 5 5
3.6 数组元素的排序
>>a = Indgen(2,3)+2
>>a
2 3
4 5
6 7
>>Print,Reverse(a) ;Reverse(a,1)
3 2
5 4
7 6
>>Print,Reverse(a,2)
6 7
4 5
2 3
>>a = [[2,8,5],[9,9,5]]
>>a
2 8 5
9 9 5
>>print,Sort(a)
0 2 5 1 4 3
>>b = a(Sort(a))
>>b
2 5 5 8 9 9
>>b = a(Reverse(Sort(a)))
>>b
9 9 8 5 5 2
3.7 数组间比较
>>a = [1,4,6,2,4,7,9,10]
>>b = [1,4,6,2,4,7,9,1]
>>Print,Array_equal(a,b)
>>Print,Array_equal(a,a)
1
4. 数组运算
4.1 加、减法运算
>>a = 2
>>help,a
A INT = 2
>>b = [2]
>>help,b
B INT = Array[1]
>>c = [1,2,3]
>>help,c
C INT = Array[3]
>>d = a+c
>>help,d
D INT = Array[3]
>>d
3 4 5
>>e = b+c
>>e
3
>>help,e
E INT = Array[1]
>>a = Indgen(4,1)
>>a
0 1 2 3
>>b = Make_array(4,1,Value=5)
>>b
5 5 5 5
>>c = a+b
>>c
5 6 7 8
>>d = a-2
>>d
-2 -1 0 1
>>e = a-b
>>e
-5 -4 -3 -2
4.2 乘除运算
>>a = Indgen(2,3)+1
>>a
1 2
3 4
5 6
>>b = Indgen(2,3)*2
>>b
0 2
4 6
8 10
>>c = a*b
>>c
0 4
12 24
40 60
>>a = Indgen(2,3)+1
>>b = Indgen(3,2)
>>a
1 2
3 4
5 6
>>b
0 1 2
3 4 5
>>c = a#b
>>c
13 16
40 52
>>c = a##b
>>c
6 9 12
12 19 26
18 29 40
>>d = a^2
>>d
1 4
9 16
25 36
>>d = a^3
>>d
1 8
27 64
125 216