第四章
4.1.3NumPy数组运算
数组允许我们进行批量操作而无需任何for循环,称之为向量化
。在任何两个等尺寸的数组之间的算术操作都应用了逐元素
的方式,带有标量计算的算术操作会把计算参数传递给数组的每一个元素。
>>>arr = np.array([[1., 2., 3.], [4., 5., 6]])
>>>arr
array([[1., 2., 3.],
[4., 5., 6.]])
>>>arr * arr
array([[ 1., 4., 9.],
[16., 25., 36.]])
>>>arr ** 2
array([[ 1., 4., 9.],
[16., 25., 36.]])
>>>arr / 2
array([[0.5, 1. , 1.5],
[2. , 2.5, 3. ]])
同尺寸数组之间的比价会产生一个布尔数值
的数组:
>>>arr2 = np.array([[0., 9., 3], [4., 7., 9]])
>>>arr2
array([[0., 9., 3.],
[4., 7., 9.]])
>>>arr2 > arr
array([[False, True, False],
[False, True, True]])
4.1.4数组的索引与切片
一维数组的索引与切片与列表类似,但是数组的切片是原数组的视图
,视图与复制不同的是,任何对视图的修改都将反映到原数组上
:
>>>arr = np.arange(10)
>>>arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>arr[5]
5
>>>arr[5:8]
array([5, 6, 7])
>>>arr[5:8] = 12
>>>arr
array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
#数组的子集仍是数组
>>>arr_slice = arr[5:8]
>>>arr_slice
array([12, 12, 12])
#arr_slice的改变会体现到原数组上
>>>arr_slice[1] = 12345
>>>arr
array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8,
9])
与列表一样。使用[:]
会取所有的值:
>>>arr_slice[:] = 555
>>>arr
array([ 0, 1, 2, 3, 4, 555, 555, 555, 8, 9])
如果要复制数组,则要使用.copy()
方法:
>>>arr_slice2 = arr[1:4].copy()
>>>arr_slice2 = 666
#原数组不会被改变
>>>arr
array([ 0, 1, 2, 3, 4, 555, 555, 555, 8, 9])
在二维数组中,每个索引值对应的元素不再是一个值,而是一个一维数组:
>>>arr2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
#单个索引相当于取第几行
>>>arr2d[1]
array([5, 6, 7, 8])
#通过两次索引获取单个值
>>>arr2d[2][1]
9
##另一种写法
>>>arr2d[2, 1]
9
在多维数组中,单词索引返回的是降低一个维度的数组,我们可以根据索引对数组中的值进行更改,但要注意选中的子集都是原数组的视图,任何对子集的更改都会反映到原数组上。
#arr3d是一个2x2x3的数组
>>>arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
>>>arr3d
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
#arr3d[1]是一个2X3的数组
>>>arr3d[1]
array([[ 7, 8, 9],
[10, 11, 12]])
三维数组是二维数组在空间Z轴
上的堆积,一个a x b x c
的三维数组如图所示。a代表的是"高"
,b是每一层的"行数"
,c是每一层的"列数"
。准确理解abc的含义才能更准确的对三维数组进行索引和切片。
4.1.4.1数组的切片索引
一维数组的切片与列表相似,但是二维数组的切片便有些不同了:
>>>arr2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>>arr2d
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
arr2d[:2]
的含义为选择arr2d的前两行
:
>>>arr2d[:2]
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
arr2d[: , :2]
的含义为选择arr2d的所有行的前两列
:
>>>arr2d[:,:2]
array([[ 1, 2],
[ 5, 6],
[ 9, 10]])
通过向二维数组传入切片值和索引值的组合,可以方便我们提取数组的子集,之前我们要更改二维数据表中的某一列需要使用zip()函数,现在使用数组的方法,只需要一步即可搞定,效率翻番。
4.1.5布尔索引
布尔索引向我们提供了一个更简便的对数组进行取子集的方式:
#生成一个随机6X3数组
>>>arr5 = np.random.randn(6,3)
>>>arr5
array([[ 0.43199127, 0.58234213, 0.2910352 ],
[-0.40600261, -0.45900332, -0.07530472],
[ 0.40338536, -1.49898794, 1.07477081],
[-0.87551375, 0.82412989, -0.19018902],
[ 0.95046982, -0.3471458 , 1.77490251],
[-0.42049412, -0.61986475, -0.21496551]])
生一个含有6个值的数组,假设arr6中的每个值对应arr5中的每一行,根据arr6对arr5进行索引。
>>>arr6 = np.array([1, 4, -5, 9, -8, 7])
array([ 1, 4, -5, 9, -8, 7])
我们提取arr5中在arr6中大于0的行:
>>>arr6 > 0
array([ True, True, False, True, False, True])
>>>arr5[arr6 >0]
array([[ 0.43199127, 0.58234213, 0.2910352 ],
[-0.40600261, -0.45900332, -0.07530472],
[-0.87551375, 0.82412989, -0.19018902],
[-0.42049412, -0.61986475, -0.21496551]])
使用"~"
对条件进行取反操作:
>>>arr5[~ (arr6 >0)]
array([[ 0.40338536, -1.49898794, 1.07477081],
[ 0.95046982, -0.3471458 , 1.77490251]])
当需要选择两个或多个条件时,可以使用 &
(and) 和 |
(or)对布尔值进行联合。我们取arr5中大于0小于5的值在arr6对应的行,NumPy不识别and和or,需使用相应符号。
>>>arr5[(arr6 > 0) & (arr6 <5)]
array([[ 0.43199127, 0.58234213, 0.2910352 ],
[-0.40600261, -0.45900332, -0.07530472]])
这里arr6中的每个值没有特殊意义,但在实际操作中可以赋予它们相应的意义,更方便我们对数据进行操作。
微生物基因组
1,插入和缺失是基因序列改变的重要途径,基因组中的重复序列是插入/缺失发生的重要位点。细菌重复序列通常分为两大类:低复杂性重复序列(串联重复)和较长重复序列。原核生物高度压缩的基因组中同样存在大串联重复。
2,基因转换是由同源重组中同源序列的不对等交换产生的,它使细菌基因组上的多基因家族协同进化(在较长的时间内保持基因间高水平相似性)。
3,比较基因组学揭示功能保守基因分布在复制起始位点附近,而在终止位点附近则含有大量的假定基因和可能通过种间横向获得的基因,这可能是因为终止位点附近有更高的突变率、较低的表达水平,和高频外源DNA的插入。