京东-优惠雷达
新人页面
精选商品
首月0月租体验,领12个月京东PLUS
自营热卖

利用python进行数据分析(五)

不良人 1年前   阅读数 108 0

为了函数这节内容,翻了四本书… …虽然这本书讲的不是最系统的,内容还是按着这本书的顺序来吧。

3.2 函数
函数是一段具有特定功能的、可复用的语句组。如果需要多次重复相同或者类似的代码,就非常值得写一个可复用的函数。函数定义通常的格式为:

def <函数名>(<参数(0个或多个)>):
	<函数体>
	return <返回值>

定义一个函数,计算(A+B)/C的值:

>>>def cal_num(A, B, C=1):
       s = ( A + B ) / C
	   return s
>>>cal_num(4, 6)
10.0
>>>cal_num(4, 6, C=2)
5.0
>>>cal_num(4, 6, 2)
5.0

首先自定义函数的命名不可以与python内置函数重复,否则会影响正常函数功能的执行。

每个函数都具有位置参数关键字参数,在上面的函数中,有三个参数ABC,其中AB 为位置参数,即在调用函数时必须要按顺序输入的参数;C即是关键字参数也是默认参数,即在调用函数时,如果未输入C的值,则默认使用C=1进行函数调用,而如果使用此参数的话,即可以通过C=2的方式传入函数,也可以通过在第三个参数位置输入2方式传入函数。需要注意的是,关键字参数必须跟在位置参数后面

3.2.1 全局变量和局部变量
全局变量局部变量是指python中变量的作用域,即变量有效的范围,也称命名空间。在函数内部,任意变量都是默认只在函数内部生效的,即在函数调用时生效,函数执行结束后便被销毁。简言之,局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。看如下示例:

>>>a = ['a', 'b', 'c']              
>>>def func(n):                     
	   a = []                       
	   for i in range(n):           
		   a.append(i)              
  	   print('a是局部变量:')             
	   return a                     
                                 
>>>func(5)                                                  
a是局部变量:
[0, 1, 2, 3, 4]
>>>print('a是全局变量:')                 
>>>print(a)
a是全局变量:
['a', 'b', 'c']                       

在上面的示例中,我们首先在函数外定义了一个列表a,然后在函数也同样内定义了一个空列表a,并为它加入新的值。然后,我们先调用函数再打印列表a,可以看到得到了两个不同的列表,这说明函数内部定义的a并没有影响到函数外部的a,即局部变量的有效范作用围只在函数内部。

同样,函数外部定义的a也没有被函数内部使用,那如果想让函数调用函数外部的变量该怎么办?需要在函数内部使用global声明该变量为全局变量,如下:

>>>a = ['a', 'b', 'c']              
>>>def func(n):                     
	   global a                       
	   for i in range(n):           
		   a.append(i)              
  	   print('a成为全局变量:')             
	   return a                     
                                 
>>>func(5)
a成为全局变量:
['a', 'b', 'c', 0, 1, 2, 3, 4] 
>>>print('a是全局变量:')                 
>>>print(a)
a是全局变量:
['a', 'b', 'c', 0, 1, 2, 3, 4] 

可以看到,在函数外面定义的a不仅被函数内部调用了,且被修改了。

3.2.2 返回多个值
函数可以返回多个值,通常是返回了一个元组对象,因此我们可以对这个对象进行元组的操作,最常见的就是拆包。

>>>def func(n):
	   a = []
	   for i in range(n):
	  	   a.append(i)
	   return a[0], a[1], a[2]
>>>func(5)
(0, 1, 2)
>>>a, b, c = func(5)
>>>a
0

有时,我们需要函数返回一个字典,最简单的情况下:

>>>def func(n):
	   a = []
	   for i in range(n):
		   a.append(i)
	   return {'a[0]':a[0], 'a[1]':a[1], 'a[2]':a[2]}
>>>func(5)
{'a[0]': 0, 'a[1]': 1, 'a[2]': 2}

也可能需要集合:

>>>def func(n):
	   a = []
	   for i in range(n):
		   a.append(i)
	   return {a[0], a[1], a[2]}
>>>func(5)
{0, 1, 2}

在这些情况下,我们可以对返回的结果进行更多处理。

3.2.3 函数是对象
python中的函数也是对象,因此我们可以将函数作为参数传递给其他函数,使代码看起来更为模块化。

假设我们要对一个凌乱的字符串列表进行数据清洗,输出为整齐的数据。通过观察,发现字符串中含有标点与空格且大小写不一,结合内建的字符串方法与正则表达式,第一种方法如下:

>>>states = [' qwer', 'asdf!', 'zxcv', 'Zxcv', 'ZXCV', 'tyui hjk##', 'uIop uoqi?', 'zxc?v']
>>>import re
>>>def clean_strings(strings):
	   result = []
	   for value in strings:
		   value = value.strip() #去空格
		   value = re.sub('[!#?]', '', value) #去标点
		   value = value.title() #首字母大写
		   result.append(value)
	   return result
>>>clean_strings(states)
['Qwer', 'Asdf', 'Zxcv', 'Zxcv', 'Zxcv', 'Tyui Hjk', 'Uiop Uoqi', 'Zxcv']

很明显,上面的代码显得臃肿,且不利于后期的维护更新。python允许我们将特定的列表操作应用到某个字符串集合上,更新后代码如下:

>>>states = [' qwer', 'asdf!', 'zxcv', 'Zxcv', 'ZXCV', 'tyui hjk##', 'uIop uoqi?', 'zxc?v']
>>>import re
#定义一个去除标点的函数
>>>def remove_punctuation(value):
		   return  re.sub('[!#?]', '', value)
#定义一个操作集合
>>>clean_ops = [str.strip, remove_punctuation, str.title] #这个列表中str.strip的实现原理我也还不清楚,后面理解了会回来更新。这里strip不可以加括号,加了括号后会改变报错,是因为加括号成为了具体可执行方法?
#将列表中的操作应用于输入对象
>>>def clean_strings(strings, ops):
	   result = []
	   for value in strings: #取每个字符串
		   for function in ops: #依次执行每个处理
			   value= function(value)
		   result.append(value)
	   return result
>>>clean_strings(states, clean_ops)
['Qwer', 'Asdf', 'Zxcv', 'Zxcv', 'Zxcv', 'Tyui Hjk', 'Uiop Uoqi', 'Zxcv']

上面的函数虽然看起来并没有精简,但是当我们需要对字符串进行更多的操作时,可以通过定义新函数传入操作列表中来实现,这更方便我们维护函数。

将函数作为参数传递给其他函数的另一个例子是python中的map函数,map() 会根据提供的函数对指定序列做映射。

>>>states = [' qwer', 'asdf!', 'zxcv', 'Zxcv', 'ZXCV', 'tyui hjk##', 'uIop uoqi?', 'zxc?v']
>>>import re
>>>def remove_punctuation(value):
		   return  re.sub('[!#?]', '', value)
#map就是将提供的函数作用于后面的序列,返回一个迭代器,需要实例化才能显示出来结果。 
>>>for x in map(remove_punctuation, states):
	   print(x)
 qwer
asdf
zxcv
...
zxcv
#当然,我们可以在输出的时候再进行一些处理,达到最后的结果,但这同样不利于后期的维护更新
>>>for x in map(remove_punctuation, states):
	   print(x.strip().title())
Qwer
Asdf
Zxcv
...
Zxcv

微生物基因组

1, 通过扫描基因组和分析序列的统计学特征,可以快速准确的发现原核生物基因组中的基因,通过这种方法可以发现99%以上的基因。而从真核生物中寻找基因目前还是个难题,因为真核生物的基因组中含有大量内含子。
2, 细菌的基因组布满了基因,其中90%的序列为编码蛋白质序列,它们被较短的间隔序列分开,这些短的间隔序列含有其他调控序列,而且细菌的编码蛋白序列很少被内含子打断。
3,即使两个基因的编码区有重叠也不要过多担心,因为寻找基因的相关的算法已经考虑到了这一点,且这些算法充分考虑了各种情况,因此基因预测的准确率相当高,如果你的基因还是没找到,我觉得可以先考虑基因组组装的是否足够完整再认那不到1%内的倒霉。
4,全基因组比较是将一种生物与另一种生物的DNA序列进行比较,以揭示它们之间的相似性和重排、缺失、插入以及多样性。常见的平均核苷酸一致性(ANI)也是一种基于全基因组的比较。


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: