Numpy数组的索引使用方法非常丰富,因为选取数据子集或单个元素的方式有很多。
Numpy一维数组功能从表面上看和Python的列表差不多。
array = np.arange(10)
array
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
array[5:7]
array([5, 6])
array[5:7] = 10
array
array([ 0, 1, 2, 3, 4, 10, 10, 7, 8, 9])
如上所示,如果将一个标量值赋值给一个切片时,即array[5:7]=10
,该值会自动传播给数组的整个选区。
对于Numpy数组而言,数组切片均为原始数组的视图,也就是说当你对切片进行操作的时候,视图上的修改都直接反映到源数据。如果你想要得到数组切片的一份副本,则需要使用.copy()
函数。
Numpy的切片主要应用在高维数组上比较多。
对于一个二维数组,第一个索引位置是对应的一维数组:
array2 = [np.arange(5),np.arange(5)]
array2
array2
[array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4])]
array2[1]
array([0, 1, 2, 3, 4])
array2[1][3]
3
如上,在多维数组中,如果你省略了后面的索引,那么返回对象是一个低维度的数组。
array3 = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
y3
array3
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
array3[0]
array([[1, 2],
[3, 4]])
标量和数组都可以传递给上例中的array3[0]
:
array3[0] = 5
array3[1] = array3[0].copy()
array3
array3
array([[[5, 5],
[5, 5]],
[[5, 5],
[5, 5]]])
上例中先赋值给array3[0]
数5,然后赋值给array3[1]
array3[0]的副本。
对于高纬度的ndarray,你可以在一个或多个轴上进行切片,也可以跟整数索引混合使用。
array4
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
array4[:2]
array([[1, 2, 3],
[4, 5, 6]])
array4[:2,1:]
array([[2, 3],
[5, 6]])
array4[2][1:]
array([8, 9])
相信看了上面几个实例,应该掌握了ndarray区域切片的方法。既可以使用轴(冒号)
切片,也可以与整数索引混合使用,通过配合使用,你可以选定ndarray里面的任何相邻区域元素。
现在有一个ndarray如下:
name
array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype=')
你可以使用==
运算符得到一个布尔型数组:
name == 'Bob'
array([ True, False, False, True, False, False, False])
得到的这个布尔型数组可以用作数组索引:
data
array([[-0.97133348, -0.5600425 , -0.79953394],
[-0.16137989, 0.64255114, -0.23057695],
[ 0.46766496, 0.4166806 , 1.89590574],
[ 0.20037889, 1.24162949, -1.22615282],
[ 0.04411636, -0.10187134, -2.87967816],
[-1.12559886, 1.37114668, 1.05111639],
[ 2.80698643, 0.67018108, 1.67296472]])
data[name == 'Bob']
array([[-0.97133348, -0.5600425 , -0.79953394],
[ 0.20037889, 1.24162949, -1.22615282]])
注意,利用上面布尔型数组作为索引即返回的True
的那些行。
另外需要注意的是,在Numpy中如果想要进行逻辑操作需要使用&(和)、|(或)
,Python里面的and
、or
关键字在Numpy中无效:
test = (name == 'Bob')|(name == 'Will')
test
test
array([ True, False, True, True, True, False, False])
test = (name == 'Bob') or (name == 'Will')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-52-debf1f9c9f26> in <module>
----> 1 test = (name == 'Bob') or (name == 'Will')
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
布尔型数组最主要的作用是给数组赋值,如下示例:
data
array([[ 1.88490696, -1.21508243, 0.45033942],
[-1.8350759 , -0.11018609, -0.89959447],
[-0.04100068, 0.74753441, -0.32248567],
[ 0.24694001, -0.57307637, -0.62334876],
[-0.43501341, 0.541733 , -1.91950243]])
= 100
data[data<0] = 100
data
data
array([[ 1.88490696, 100. , 0.45033942],
[100. , 100. , 100. ],
[100. , 0.74753441, 100. ],
[ 0.24694001, 100. , 100. ],
[100. , 0.541733 , 100. ]])
花式索引(Fancy indexing)
是一个Numpy术语,它指的是利用整数数组进行索引。例如:
array5
array([[0., 0., 0., 0.],
[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.],
[4., 4., 4., 4.],
[5., 5., 5., 5.],
[6., 6., 6., 6.],
[7., 7., 7., 7.]])
array5[[1,3,5,7]]
array([[1., 1., 1., 1.],
[3., 3., 3., 3.],
[5., 5., 5., 5.],
[7., 7., 7., 7.]])
另外你也可以使用负整数,如果使用负整数,那么索引会从末尾倒着开始:
array5[[-1,-3,-5,-7]]
array([[7., 7., 7., 7.],
[5., 5., 5., 5.],
[3., 3., 3., 3.],
[1., 1., 1., 1.]])
你还可以传入多个整数数组,它返回的是一个一维数组,其中的元素对应各个索引元组:
array6
array([[ 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]])
array6[[1,3,5],[0,2,3]]
array([ 4, 14, 23])
能看明白上面操作发生了什么吗?
转置transpose
是重塑的一种特殊形式,它返回的是源数据的视图。数组不仅有transpose
方法,还有一个特殊的T
属性:
array6
array([[ 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]])
array6.T
array6.T
array([[ 0, 4, 8, 12, 16, 20, 24],
[ 1, 5, 9, 13, 17, 21, 25],
[ 2, 6, 10, 14, 18, 22, 26],
[ 3, 7, 11, 15, 19, 23, 27]])
如果你需要计算矩阵的内积 X T X X^TX XTX :
np.dot(array6.T,array6)
array([[1456, 1540, 1624, 1708],
[1540, 1631, 1722, 1813],
[1624, 1722, 1820, 1918],
[1708, 1813, 1918, 2023]])
对于高维数组,transpose
需要得到一个由轴编号组成的元组才能对这些轴进行转置:
array7
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
array7.transpose((1,0,2))
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
复杂的转置一般用transpose
函数,简单的就用.T
。
通用函数是对一种ndarray中的数据执行元素级运算的函数。
函数 | 说明 |
---|---|
abs、fabs | 计算整数、浮点数或复数的绝对值。对于非复数值,可以使用更快的fabs |
sqrt | 计算各元素的平方根 |
square | 计算各元素的平方 |
exp | 计算各元素的指数 e x e^x ex |
log、log10、log2、log1p | 分别为自然对数、底数为10、2的对数和log(1+x) |
sign | 计算各元素的正负号,1为正,-1为负,0即0 |
ceil | 计算大于等于该值的最小整数 |
floor | 计算小于等于该值的最大整数 |
rint | 将各元素四舍五入到最近的整数,dtype不变 |
modf | 将数组小数和整数部分以两个独立数组的形式返回 |
isnan | 返回一个表示哪些值是NaN 的布尔型数组 |
isfinite、isinf | 返回一个表示哪些元素是有穷的(非inf,非NaN) 或无穷的布尔型数组 |
cos、cosh、sin、sinh、tan、tanh | 普通型和双曲型三角函数 |
… | … |
函数 | 说明 |
---|---|
add | 将数组中对应的元素相加 |
subtract | 从第一个数组中减去第二个数组中的元素 |
multiply | 数组元素相乘 |
divide、floor_divide | 除法或向下圆整除法(丢弃余数) |
power | 对一个数组中的元素A根据第二个数组中的元素B,计算 A B A^B AB |
maximum、fmax | 元素级的最大值计算。fmax将忽略NaN |
minimum、fmin | 元素级的最小值i计算。fmin将忽略NaN |
mod | 元素级的求模运算(除法的余数) |
copysign | 将第二个数组中的值的符号复制给第一个数组中的值 |
greater、greater_equal、less、less_equal、equal、not_equal | 执行元素级的比较运算,最终产生布尔型数组相当于> >= < <= == != |
logical_and、logical_or、logical_xor | 执行元素级的真值逻辑运算。相当于中缀运算符& | ^ |
… | … |