各种py库的api中文帮助文档:文档1 文档2
使用help、dir函数,可以实时帮助。
各种py第三方库都能下载到本地:地址
内容包括:type、isinstance的使用
参考来源
1、使用type模板
import types
type('abc')==types.StringType #输出:True
type(u'abc')==types.UnicodeType #输出True
type([])==types.ListType #输出:True
2、isinstance能够解决class的继承关系判断问题
a = Animal()
d = Dog()
h = Husky()# 狗的名字。
isinstance(h, Husky)# 自己找自己的类。 # 输出True
isinstance(h, Animal)#从子类实例找父类对象也是可以的。 # 输出True
isinstance(d, Husky) #从父类实例往子类对象就不行。 # 输出False
3、判断变量的数据类型的两种方法。isinstance(变量名,类型) 、type() 参考
# 方法1
a = 1.23
isinstance(a, float)
# 方法2
type(a) == type(3.21)
4、仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:
class MyObject(object):
def __init__(self):
self.x = 9
def power(self):
return self.x * self.x
obj = MyObject()
hasattr(obj, 'x') # 有属性'x'吗? # 输出:True
obj.x # 输出:9
hasattr(obj, 'y') # 有属性'y'吗? #输出:False
setattr(obj, 'y', 19) # 设置一个属性'y'
hasattr(obj, 'y') # 有属性'y'吗? # 输出True
getattr(obj, 'y') # 获取属性'y' # 输出19
obj.y # 获取属性'y' # 输出19
hasattr(obj, 'power') # 有属性'power'吗? # 输出True
getattr(obj, 'power') # 获取属性'power' # 输出>
fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
fn # fn指向obj.power #输出:>
fn() # 调用fn()与调用obj.power()是一样的。 #输出:81
5、只有在不知道对象信息的时候,我们才会去获取对象信息。如果可以直接写:
sum = obj.x + obj.y
sum = getattr(obj, 'x') + getattr(obj, 'y') # 不要这么写。推荐上面。
参考来源
@log(‘execute’) # log 函数先接收 ‘execute’ 然后再接收被装饰的函数。
@functools.wraps(func) # 解决 >>> now.name 输出 ‘wrapper’。用于属性在装饰前后保持一致,直接认为写装饰器必须要用的就行了。
例子:
def log(func):
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
@log
def now():
print '2013-12-25'
此时now = log(now)。所以调用now()函数,相当于把now函数传入log函数里面执行。
运行:now()
输出:
call now():
2013-12-25
一个完整的decorator的写法如下:
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
或者针对带参数的decorator【此时log函数还能传入除now函数外的其它参数】:
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return wrapper
return decorator
1、decode后返回的是一个unicode码字符,这样就能与u"xxx"拼接了。
head_path = os.getcwd().decode(“gbk”)+"\"+u"权重_词林符号_义原数目"
2、unicode编码的字符串,汉字的大小是1.
print u"义原数目".len() # 输出 4
3、os.listdir()返回的字符串列表却是unicode型的。对这实验结果我比较奇怪。
print " “.join([v for v in os.listdir(head_path) if v[-4:] == u"义原数目”]) # 输出 实验2-result-义原数目; 实验3-result-义原数目
4、参考1 参考2
待精简参考地址里面的知识点。
5、二进制文件与普通文本文件的差别。
读取时的区别:二进制可以每个字符为一位,不会出现中文字符需要占据多位问题,但是需要进行encode才能知道具体的字符串。
在python的load_word2vec_format函数里面有具体区别的代码:
gensim.models.KeyedVectors.load_word2vec_format(‘vectors.bin’, binary=True)
注:c语言的fgetc函数,暂时我觉得它不能够直接读取中文字符,不过可以读取中文字符的二进制格式。具体的我要实践后再确定。
可以把一组迭代对象串联起来,形成一个更大的迭代器。
例子1:
for c in itertools.chain('ABC', 'XYZ'):
print c # 迭代效果:'A' 'B' 'C' 'X' 'Y' 'Z'
例子2:
其中 ngrams: [[(0, 0, 0, 0, 0, 0, 0, 81), (0, 0, 0, 0, 0, 0, 81, 68), …],[…],……] 因此下面行将得到[(0, 0, 0, 0, 0, 0, 0, 81), (0, 0, 0, 0, 0, 0, 81, 68),…]
ngrams = np.array(list(chain(*ngrams))) # 注:在函数调用中使用*list/tuple的方式表示将list/tuple分开,作为位置参数传递给对应函数(前提是对应函数支持不定个数的位置参数)
1、把两个list 打包在以前然后顺序放下遍历。
for id_, text in zip(trainSentenceId, trainContent):
print "id_ 为"+id_+"的内容是:"+text
2、迭代在中途暂停了,再次启动的时候依旧是从开头迭代,可以多次迭代,中途改变也是可以的。
a = [124,5,7]
for idx,v in enumerate(a):
if idx == 0:
a[idx] = 1
break
for v in a:
print v # 输出 1 5 7
views_idx = [[1,3,5],[2,3,6],[4,5,10,123,999]]# views_idx是一个二维数组来的。lambda你可以认为它是一个函数来的,输入x,y,把x y都转化为set后取并集。reduce 意思就是把当前与下一个 作运算,得到的结果成为新一轮的当前。
print reduce(lambda x, y: set(x) | set(y), views_idx)# set([1, 2, 3, 4, 5, 6, 999, 10, 123])
1、doc
def func():
"""Here's a doc string"""
pass
print func.__doc__# 输出 "Here's a doc string"
2、name
if __name__=='__main__':
print "haha" # 当程序执行到这里的时候,就会自动运行了。
try:
g = group.get_group(fid)
except Exception,e:
continue
主动抛出错误的语句:
raise Exception("抛出一个异常")
用于一旦条件不满足就报错,其实也就是exit了。一行替代2行。
参考来源
用法:assert 表达式 [,异常参数](异常参数可有可无)
>>> assert 1 == 0,'one does not equal zero' # 逗号后面的内容有没有都可以。
Traceback (most recent call last):
File "" , line 1, in <module>
AssertionError: one does not equal zero
在try-except语句中使用assert:
>>> try:
... assert 1 == 0,'one does not equal zero'
... except AssertionError,args:
... print '%s:%s' % (args.__class__.__name__,args)
...
AssertionError:one does not equal zero #输出
import os
os.mkdir(u"D:/ha")# 创建文件夹
file = open(u"D:/ha.txt",'w')# 创建普通文件,如txt
1、is 判断变量指向是否同一对象 【P核心 62】
a = 1.5
b = a
a is b 为 True,等价于id(a) == id(b)
2、cmp 如果obj1 小于 obj2 返回一个负整数。
a, b = "abc", "xyz"
print cmp(a,b) # 输出
3、repr、str、eval
print repr([0,1,2])
print "[0,1,2]"
print str([0,1,2]) # 三者输出一样。
repr等价于"",都是字符串输出。可用eval()重新得到该对象,对python友好。
str无法用eval获取回原对象,对用户友好。
4、type、isinstance # 推荐使用 isinstance
a = 123
if isinstance(a, (int, long, float, complex)):
print "a 是一个数学的数值",type(a).__name__ # 后者输出 int
import types
if type(a) == types.IntType:
print "是整型"
学习廖雪峰面向对象的笔记,到时需要把很容易的知识点剔除掉。
1、类名通常是大写开头的单词。
2、bart = Student(‘Bart Simpson’, 59)。创建实例的时候,括号的作用是联系init的。 class Dog(Animal):编写对象时,括号内容代表父类。
3、和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:
>>> bart = Student('Bart Simpson', 59)
>>> lisa = Student('Lisa Simpson', 87)
>>> bart.age = 8
>>> bart.age # 输出:8
>>> lisa.age # 输出:Traceback (most recent call last):
4、变量下划线的特殊意义。
①单下划线开头:比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
②双下划线开头:私有变量,外面访问不到。但其实,__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量。
③双下划线开头并结尾:特殊变量,特殊变量是可以直接访问的,不是私有变量。
5、继承与多态的好处:
def run_twice(animal):# 能够接受animal类、以及继承它的所有子类,都能顺利执行完。(这是因为最高父类animal肯定有run这个函数,那么子类必须也有,所以肯定没错。)
animal.run()
animal.run()
class Dog(Animal): # 随意一个继承animal的类,并且可以选择性的该与不该原父类的函数。
def run(self):
print 'Dog is running...'
def eat(self):
print 'Eating meat...'
run_twice(Dog()) # 输出:2次的 Dog is running...
6、init.py 的作用
当你使用import 时,如果你新建的包没有这个东西,该包就不能被识别到。
7、如何调用另一个包中的类
from data_processing.data_util import DataUtil # data_processing是py包、data_util是py格式的文件、DataUtil 是类class
data_util = DataUtil() #新建一个实例
8、为实例添加新的属性
>>> class Student(object):
... pass
然后,尝试给实例绑定一个属性:
>>> s = Student()
>>> s.name = 'Michael' # 动态给实例绑定一个属性
>>> print s.name # 输出 Michael
还可以尝试给实例绑定一个方法:
>>> def set_age(self, age): # 定义一个函数作为实例方法
... self.age = age
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s, Student) # 给实例绑定一个方法
>>> s.set_age(25) # 调用实例方法
>>> s.age # 测试结果 25
但是,给一个实例绑定的方法,对另一个实例是不起作用的:
>>> s2 = Student() # 创建新的实例
>>> s2.set_age(25) # 尝试调用方法
Traceback (most recent call last):
File "" , line 1, in <module>
AttributeError: 'Student' object has no attribute 'set_age'
为了给所有实例都绑定方法,可以给class绑定方法:
>>> def set_score(self, score):
... self.score = score
>>> Student.set_score = MethodType(set_score, None, Student)
9、super(B, self)表示找到B的父类(class B(A): 就是类A)
10、参数带 * 、**
* 用来传递任意个无名字参数,这些参数会一个Tuple的形式访问。
**用来处理传递任意个有名字的参数,这些参数用dict来访问
11、@staticmethod 、 @classmethod 参考来源
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
12、类的实例属性,是实例对象的独有属性,是动态的。不需要预先声明。
one_class.none_def = 1
13、类的self会自动传入,不需要人工显式传入,不过继承父类时,就需要把子类实例传过去,不然那边不知道。
class Son(Father):
"这时一个儿子类" # 通过Son.__doc__ 可以获得这类定义
def __init__(self, one_attr):
Father.__init__(self, one_attr) # 这时才需要显式传self
14、命名规则
类名开头大写,其余用骆驼记法,如 updateEmail、update_email
15、___name__用在type中
print type("one_string!!").__name__ # 原输出 加name限制后输出 'string'
16、module_ 获取类在哪个模板(py文件中)
from main import Son
print Son.__module___ # 输出main
1、open、io.open、codecs.open之间的区别?
参考来源
最早的时候,只有open。
你知道的,Python 2的编码多么蛋疼,所以,就有了codecs.open.
至于io.open,其实是因为Python 2的open实际上是file模块提供的,而Python 3的open是io模块提供的。然后,Python 2.6引入了这个Python 3的特性,叫做io.open,以便和原来的open相区分。
个人建议:
Python3直接用open。
Python2.x下用codecs.open,特别是有中文的情况,然后也可以避免踩到2.6下面io.open的坑。
如果希望代码同时兼容Python2和Python3,那么推荐用codecs.open。
个人经验:在py2.7中,codecs.open可以直接调encoding,如果你写得此处正确,len函数得到的结果就正确。
2、自动关闭文件的机制。
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
3、常用参数 参考
mode:r 读取。 w 写入。 a 追加。辅助:b 是二进制模式。
encoding:一般使用utf8。
errors:解码的时候报错,可以 ignore。默认是strict。
4、指针操作:seek()和tell()函数 基础解释的博客、利用指针切分语料并多线程读取的例子
(1)fileObject.seek(offset[, whence]) 方法用于移动文件读取指针到指定位置。 参考菜鸟
参数解析:
offset:开始的偏移量,也就是代表需要移动偏移的字节数
whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。
fo = open("runoob.txt", "rw+")
print "文件名为: ", fo.name
line = fo.readline()
print "读取的数据为: %s" % (line)
fo.seek(0, 0) # 重新设置文件读取指针到开头
line = fo.readline()
print "读取的数据为: %s" % (line)
fo.close()
(2)fileObject.tell() 方法返回文件的当前位置,即文件指针当前位置。 参考菜鸟
fo = open("runoob.txt", "r+")
print ("文件名为: ", fo.name)
line = fo.readline()
print ("读取的数据为: %s" % (line))
pos = fo.tell() # 获取当前文件位置
print ("当前位置: %d" % (pos))
fo.close()
参考来源
向上取整 math.ceil
>>> math.ceil(3.25)
4.0
四舍五入 round
>>> a=3.25;b=3.75
>>> round(a);round(b)
3.0
4.0
向下取整 math.floor
print "math.floor(2.3) => ", math.floor(2.3) # 输出 2
print "math.floor(2.6) => ", math.floor(2.6) # 2
保留小数点后5位
print "%.5f" % ans
注意 int 是直接忽略小数部分。
例子:int(-2.3)时它依旧是-2。而不是-3。
1、raw_input:读取一行,当做一个字符串读取进来。只识别换行符。
2、格式化输出 如%s等等 参考来源
def print_word_vectors(word_vectors, write_path):
"""
This function prints the collection of word vectors to file, in a plain textual format.
"""
print "Saving the counter-fitted word vectors to", write_path, "\n"
with open(write_path, "wb") as f_write:
for key in word_vectors:
print >>f_write, key, " ".join(map(str, numpy.round(word_vectors[key], decimals=6)))
def print_word_vecs(wordVectors, outFileName):
outFile = open(outFileName, 'w')
for word, values in wordVectors.iteritems():
outFile.write(word+' ')
for val in wordVectors[word]:
outFile.write('%.4f' %(val)+' ')
outFile.write('\n')
outFile.close()
参考
1、使用 math 模块的 math.isinf 和 math.isnan 函数:
>>> inf = float("inf") # 正无穷
>>> ninf = float("-inf") # 负无穷
>>> nan = float("nan")
>>> import math
>>> math.isinf(inf)
True
>>> math.isinf(ninf)
True
>>> math.isnan(nan)
True
2、用 numpy 模块的函数
>>> import numpy as np
>>> np.isnan(np.nan)
True
>>> np.isnan(float("nan"))
True
>>> np.isinf(np.inf)
True
>>> np.isinf(np.NINF)
True
>>> np.isinf([np.inf, -np.inf, 1.0, np.nan])
array([ True, True, False, False])
>>> x = np.array([-np.inf, 0., np.inf])
>>> y = np.array([2, 3, 4])
>>> np.isinf(x, y) # 判断x数组,并把结果写到y数组中。
array([1, 0, 1])
>>> y
array([1, 0, 1])
参考
(1)位置参数:直接按照位置映射参数具体数值,可以不写参数名。
(2)默认参数: 形如 def power(x, n=2) 带有默认值的
(3)可变参数:形如 def calc(*numbers) ,意思是传入进来的多个参数,会被认为是一个,用元组格式合并起来,如 calc(1, 2) 。所以调用时,如果参数本来就是一个元组或list,就需要用*把它解开元组,如 calc(*nums)。
(4)关键字参数:形如 def person(name, age, **kw),意思是kw是一个dict结构,传入一个多个参数时需要写等号 city=“eee”,这样他们就能在kw中获取了。如果本来就是字典格式,就需要加 ** 符号来解开dict结构【就是用符号对应起来的意思】。
(5)命名关键字参数:形如 def person(name, age, *, city, job)。加个*符号作为分隔符(它自身无用),后面的就是命名关键字参数 。必须传入参数名,位置参数。如果没有传入参数名,调用将报错。
(1)如果是字符串[ 0号 : 1号 : 2号]。0、1号控制起始终止下标位置。2号控制步长,负数代表反向。
one_str = "123456"
print(one_str[::-1]) # 输出 '654321'
print(one_str[::-2]) # 输出 '642'
(2)如果是一个多维的表,涉及到逗号。[ 0号, 1号, 2号, 3号]。如果是pd的二维表,0号代表行号,1号代表列号。
view.iloc[0, 5] # 获取第一行、第六列的数据。详细见表格专题的另一份博客。
使得更加简洁。
f = 5 if 2 == 2 else 6 # 判断结果为True,此时f为5
f = 5 if 2 == 3 else 6 # 判断结果为False,此时f为6
参考
一个带有 yield 的函数就是一个 generator 生成器。
(1)用next函数执行:直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。
(2)中断时返回及接受数值:每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。每次中断都会通过 yield 返回当前的迭代值。此外,Python的yield不但可以返回一个值,它还可以 接收调用者发出的参数。
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b
# print b
a, b = b, a + b
n = n + 1
>>> for n in fab(5):
... print n
1、如何不换行
参考1 参考2
print(*objects, sep=' ', end='\n', file=sys.stdout)
参数:
end -- 用来设定以什么结尾。默认值是换行符 \n 表示换行,我们可以换成其他字符串。
例子:给end赋值为空,就不会换行了。
print (123,end='')
print (456,end='') # 输出:123456
我重写双边滤波时遇到一次内存不断增加,不能释放的情况:
如果把一张图片numpy矩阵从uint8 转为 float 格式,多次取元素相减。内存释放不了。当我转为把矩阵 int16,就解决该问题了。其中,我转矩阵是因为相减操作,数值大小会溢出。
temp = cv2.copyMakeBorder(raw, radius, radius, radius, radius, borderType).astype(float)
color_weight[int(np.abs(val - val0))]
改为-->
temp = cv2.copyMakeBorder(raw, radius, radius, radius, radius, borderType).astype(np.int16)
color_weight[abs(val - val0)]
解决办法:我网上查到的是del 、 gc.collect 等办法,但是对于我来说没有用。最终还是通过逐步debug定位到这个减法出现的问题。因为同事也说python会自动内存管理的。当我觉得有必要时再学习这节内容。
1、浮点数与整数的等号判断,可以不必像C语言那样加一个极小的阈值。
print float(1) == int(1) # 输出True
2、向上向下取值 参考来源
round(3.25) # 四舍五入取整
int(1.923) # 向下取整
math.ceil(3.25) # 向上取整
1、给元素的数值获取对应的下标
(1)适用于字符串或数字,但是只会输出第一个匹对的下标
aa = ["ee", "yy", "tt", "yy"]
aa.index("tt") # 输出2
aa.index("yy") # 输出1
(2)取出一个list最大元素的索引(下标)
aa = [5,2,16,4,8]
print aa.index(max(aa))# 输出2
2、list的合并
方法 1:相加
list1 += list2
方法2:用list的extend方法,L1.extend(L2),该方法将参数L2的全部元素添加到L1的尾部,例如:
L1 = [1, 2, 3, 4, 5]
L2 = [20, 30, 40]
L1.extend(L2) # 输出 L1[1, 2, 3, 4, 5, 20, 30, 40]
方法3:用切片(slice)操作,L1[len(L1):len(L1)] = L2和上面的方法等价,例如:
L1 = [1, 2, 3, 4, 5]
L2 = [20, 30, 40]
L1[len(L1):len(L1)] = L2
L1 # 输出 [1, 2, 3, 4, 5, 20, 30, 40]
但切片方法用起来更灵活,可以插入到头部,或其他任意部位,例如:
加到开头:
L1[0:0] = L2
L1[20, 30, 40, 1, 2, 3, 4, 5]
加到中间:
L1[1:1] = L2
L1[1, 20, 30, 40, 2, 3, 4, 5]
3、定义的多维数组,大小是逆着的。
a = [[0]*3]*5 # 5行3列
print a[4][2] # 输出0,但是a[2][4]就会超出范围。
4、矩阵的浅复制、深复制。
正确:matrix= [ [ -1 for i in range(3) ] for j in range(4) ]
然而:matrix = [[-1]*3]*4,这是浅复制,比如:matrix[0][0] 与 matrix[1][0] 是同步的。
5、排序。三大参数:cmp、key、reverse
cmp(x,y):函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。
key:在sort()函数中的作用,key和cmp参数一样,使用时都需要提供可以做为排序依据的函数
reverse:控制是否逆序,这样就不用在cmp中控制了。
print ['aa','zxczxc','a'].sort(key=len,reverse=False)# 结果 ['a', 'aa', 'zxczxc']。这是简写形式,实际用要拆分:a = ['aa','zxczxc','a']然后a.sort().
print [('b',6),('aggg',1),('c',3),('sd',4)].sort(cmp=lambda x,y:cmp(len(x[0]),len(y[0]))) # 结果[('b', 6), ('c', 3), ('sd', 4), ('aggg', 1)]
6、它是无shape的,只有np.array有。而且它无 .array() 这样的转换。只能:
list_1 = np.array(list_1)
7、pop 直接改变原数组地弹出一个元素出来。
file_list = ["dfg","hh","jjj","ttt"]
for i in xrange(4):
tmp =file_list.pop(0)# 依次输出 dfg hh jjj ttt
8、使用map。它可以用于自定义函数,也能int等转换格式。
def f(x):
return x * x
map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) # 输出[1, 4, 9, 16, 25, 36, 49, 64, 81]
map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
9、使用reduce。使用目前的结果继续与往下一个元素做同样的运算。可自定义运算方式。
def add(x, y):
return x + y
reduce(add, [1, 3, 5, 7, 9]) # 输出 25
def fn(x, y):
return x * 10 + y
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
reduce(fn, map(char2num, '13579')) # 输出 13579
10、使用匿名函数
通过对比可以看出,匿名函数lambda x: x * x实际上就是:
def f(x):
return x * x
关键字lambda表示匿名函数,冒号前面的x表示函数参数。
f(5)# 输出 25
map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])# 输出 [1, 4, 9, 16, 25, 36, 49, 64, 81]
11、sort排序
x = [4, 6, 2, 1, 7, 9]
x.sort()# 或者 x = sorted(x) 注意着两个是有区别的,list.sort直接在原序列中改变,sorted(x)可以赋值 但不改变原序列。
print x
12、append是返回值是None。
print a = [v for v in one_list].append(a) # 输出 None
print [v for v in one_list].append(a) # 得到想要的值。
13、使用pop函数,实现stack栈的功能。
stack = [23,547,5]
top = stack.pop()
14、使用heapq 模板 很容易list转化成堆排序的list。
heapq.heapify(one_list) # 处理后one_list 就有堆排序的功能了,使用heappush 进行添加元素,详情见该模板。
15、[:]作为深度复制
a= [1,5,7]
b=a[:] , b=a#这两种方式是不同的,前一种是深度复制,后一种是b指向a的意思。
16、逆序
a = [1,3,6,8,9]
for i in a[::-1]:
print(i, end=" ") # 输出 9 8 6 3 1
1、是否以某字符结尾。
if(v.endswith(u'车')):
print "该字符串以‘车’字结尾"
2、对于unicode字符串,想要改变特定字符,只能是复制一遍。不能指定某个下标进行修改。
text_lower_tmp = text_lower_tmp[:idx] + u'#' * len(view) + text_lower_tmp[idx+len(view):]
3、使用% 进行格式化参考来源
print("I'm %s. I'm %d year old" % ('Vamei', 99))# %x 十六进制整数。%s 字符串。%d 十进制整数。%e 指数 (基底写为e)。
print("I'm %(name)s. I'm %(age)d year old" % {'name':'Vamei', 'age':99})# 使用字典,结果与上面一样的。
print("%+10x" % 23)# +表示右对齐。-表示左对齐。' '表示在正数的左侧填充一个空格,从而与负数对齐。0表示使用0填充。
4、format输出。它 与% 格式化,有异曲同工的作用。它是更高级的,以后直接用它就行了。 参考1 参考2 参考3
for i in range(1, 6):
print 'split_{}.csv'.format(i)# 结果split_1、split_2等。
【等等其他……(待摘录网址中有用的)】
使用 :. 符号控制输出浮点的数位。
3.1415926 {:.2f} 3.14 保留小数点后两位
5、其他的字符串处理函数 参考1 参考2
str.strip() # 去两边空格
cmp(sStr1,sStr2) # 比较字符串
【等等其他……(待摘录网址中有用的)】
6、find函数,返回第一次发现的下标。
idx = v_lower.find(text_one_view)
while idx != -1:
idx = v_lower.find(text_one_view)
7、字符串的替换 参考1 参考2
例子1 使用replace(old, new[, max])。max是最大替换次数:
one = ur"F:\workbench_chj\aa".replace("\\",r"\\") # 里面使用了两种转义ur、r来取消转义。不过r"\"你应该要 "\\" 。 其实如果只是为了写地址,只需要使用r取消转义就好了
例子2:使用正则替换。
strinfo = re.compile('word') # import re
a = "hello word"
b = strinfo.sub('python',a) # 输出 hello python
8、判断字母、数字等。下面的全部判断正确。
print "1".isdigit()# 判断是否只有数字。
print "a".isalpha()# 判断是否只有字母。
print "1".isalnum()# 合并上面两种,判断是否只有字母或数字。
print "a".islower()# 判断是否只有小写字母。
print "ABC".isupper()# 判断是否只有大写字母。
print "AB1".isupper()# 也是判断正确的。但是“11”就判断是错了。
9、str.startwith()、str.endwith() 直接匹配字符串前面后面,返回True or False。支持多匹配模式。
10、str.replace(“待替代”, “新的”)
11、split函数 参考
string.split(str="", num=string.count(str))
参数
str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num – 分割次数。
12、rsplit函数。与split相似,只不过它是从后往前切分 参考
str.rsplit([sep=None][,count=str.count(sep)])
参数
sep -- 可选参数,指定的分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
count -- 可选参数,分割次数,默认为分隔符在字符串中出现的总次数。
In[2]: "ff.f.ee.r".split(".",1)
Out[2]: ['ff', 'f.ee.r']
In[3]: "ff.f.ee.r".rsplit(".",1)
Out[3]: ['ff.f.ee', 'r']
1、分类器使用的都是array、list格式,你可以.toarray()或者np.array(list_xx)、list(xx)或xx.tolist()进行格式的转化。
2、dict转化为list
params={'subsample':0.7, 'min_child_weight':3,'eta': 0.007}
print list(params.items())# 输出[('subsample', 0.7), ('eta', 0.007), ('min_child_weight', 3)]
print list(params)# 输出['subsample', 'eta', 'min_child_weight']
3、dict字典是否含有某个键,使用:had_key()
注:py3里面没有这函数,只能用 in 来判断。
a = {1:'aaa',2:'bbb','abc':'ccc','3':'ddd'}
print a.has_key(1) #返回True
print 1 in a #返回True
4、dict.keys()、dict.values() 分别返回所有的关键字、所有的值
print type(dict.keys()),type(dict.values())# 两个都是list。分别是关键字、值。他们的顺序是一一对应的。
5、使用dict关键字可以实现等号起到冒号的作用
print params = dict(dim_n=[2, 5, 10],clf_C=[0.1, 10, 100])# 输出{'dim_n': [2, 5, 10], 'clf_C': [0.1, 10, 100]}
6、加 for 迭代。items()返回一个列表。iteritems()返回生成器,在py3中不可使用。
for k,v in dict.items():
print "dict[%s]=" % k,v
7、利用zip建立dict字典
feed_dict = dict(zip(holder_list, feed_list))
8、defaultdict 初始化 参考来源
from collections import defaultdict
>>> s = 'mississippi'
>>> d = defaultdict(int) #另一种常用 d = defaultdict(list)
>>> for k in s:
... d[k] += 1
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
9、调用函数的作用
map(lambda y: np_utils.to_categorical(y, 4), ner_target) # ner_target是一个(19L, 100L)的矩阵。返回ner_target被处理后的值 (19L, 100L, 4L)。
10、字典排序参考来源
按照key进行排序
print sorted(dict1.items(), key=lambda d: d[0])
按照value进行排序
print sorted(dict1.items(), key=lambda d: d[1])
11、利用两个list转为dict参考来源
>>>list1 = ['key1','key2','key3']
>>>list2 = ['1','2','3']
>>>dict(zip(list1,list2)) 结果得到:{'key1':'1','key2':'2','key3':'3'}
12、合并两个字典 参考
d = {"o":2,"i":88}
d2 = {"e":2,"r":88}
d.update(d2) # 内部更新的。
len(d)
Out[5]: 4
13、dict.get(key, default=None) 输入键值,获取对应的数值。
key:字典中要查找的键。
default:如果指定键的值不存在时,返回该默认值值。
dict = {'Name': 'Zara', 'Age': 27}
print "Value : %s" % dict.get('Age') #输出 Value : 27
print "Value : %s" % dict.get('Sex', "Never") # 输出 Value : Never
参考
1、元素去重。并转回list。
real_list = list(set(tmp_list)) #list的元素去重
2、增加一个元素。字符串应该先放入list中,再放入set中才能保持整体。否则将会被拆成多个单字符。
s1 = [u"分数分数我是"]
tmp_set1 = set(s1) #只有1个元素
s2 = u"分数分数我是"
tmp_set2 = set(s2) # 有4个元素
tmp_set2 |= set([s2]) # 并集
tmp_set2 &= set([s2]) # 交集
tmp_set2.add(s2) # 增加一项
tmp_set2.update([s2]) # 增加多项
3、删除一项 remove()。
tmp_set2.remove('H')
4、set的无序性。
因为对同一个list,每次执行的set,得到的结果不一样。需要转list后用sort进行规范。
1、基本用法 参考来源
x = [1, 2, 3]
y = [4, 5, 6, 7]
xy = zip(x, y)
print xy # 输出 [(1, 4), (2, 5), (3, 6)]
2、与dict结果快速建立字典【结合下面的只是可以知道它的原理:zip会从x取一个元素、y取一个元素,组成新元素。这个新元素恰好符合字典映射的需求。】 参考来源
>>> x=['bob','tom','kitty']
>>> y=[80,90,95]
>>>d=dict(zip(x,y)) # 输出 [('bob', 80), ('tom', 90), ('kitty', 95)]
3、自己的实践,* 有解压的意思。总体意思就是,zip函数中外围肯定是[],然后不断选择元素组加(),它会每个list参数选择一个元素进行组合 参考来源
x = [1, 2, 3]
print [x] * 3 # 输出 [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
r = zip( [x] * 3)
print r# 输出 [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
r = zip( [x,x,x] ,[1,9,8])
print r# 输出 [([1, 2, 3], 1), ([1, 2, 3], 9), ([1, 2, 3], 8)]
print ""
r = zip(* [x] * 3)# 解压的意思。
print r# 输出 [(1, 1, 1), (2, 2, 2), (3, 3, 3)]
r = zip( *[x,x,x] )
print r# [(1, 1, 1), (2, 2, 2), (3, 3, 3)]
print ""
r = zip( [x],[x],[x] )
print r# [([1, 2, 3], [1, 2, 3], [1, 2, 3])]
r = zip( x,x,x )
print r # [(1, 1, 1), (2, 2, 2), (3, 3, 3)]
4、*号的作用:在函数调用中使用 * list/tuple的方式表示将list/tuple分开,作为位置参数传递给对应函数(前提是对应函数支持不定个数的位置参数)
5、如果进行zip时,数组大小不统一,将会只保留大家都有的。
print zip([[1,2,3],[4,5],[6]]) # 输出 [([1, 2, 3],), ([4, 5],), ([6],)]
print zip(*[[1,2,3],[4,5],[6]])# 输出 [(1, 4, 6)]
1、获取第三方库的版本号:print(numpy.__version__)
2、获取第三方库的安装地址:print(numpu.__file__)
3、打印全部库的版本:pip list
1、axis的值,最小的0代表最小的粒子的意思,数值越大越往上推。
np.array([[0, 2, 1], [4, 5, 6]]).sum(axis=0) # np最小的粒子是单个元素(逐列)。所以axis=0表示逐列,axis=1表示逐行。 # 输出 [4 7 7]。 而axis=1时,输出[ 3 15]
data_df.drop('col_2', axis=1) # df最小的粒子是一行数据。因此axis=0表示找行编号为"two",而axis=1表示找列编号。这是与np的不同。
2、在numpy类型的数据中,寻找一个恰好大于某特定整数的下标。
ndarray.searchsorted(model.random.randint(INF))
3、argmax 取元素的最大值的下标 参考官方
numpy.argmax(a, axis=None, out=None) 根据轴线返回的最大值的下标。
参数
a : 输入的np数组
axis : int, optional 如果不指定轴线,就会平铺数据后,返回最大值的下标。(c0, c1, c2, c3) 直接 .shape 获取的顺序,就是轴线的顺序。
>>> a = np.arange(6).reshape(2,3) + 10
>>> a
array([[10, 11, 12],
[13, 14, 15]])
>>> np.argmax(a)
5
>>> np.argmax(a, axis=0)
array([1, 1, 1])
>>> np.argmax(a, axis=1)
array([2, 2])
4、只有numpy才能使用numpy格式的一组下标,获取特定的一组元素。比如一个矩阵跳着挖元素。list是不可行的。
5、矩阵的拼接。concatenate。 参考来源
>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6]])
>>> np.concatenate((a, b), axis=0) # 上下拼接
array([[1, 2],
[3, 4],
[5, 6]])
>>> np.concatenate((a, b.T), axis=1) # 左右拼接
array([[1, 2, 5],
[3, 4, 6]])
6、np.expand_dims(a, axis) 参考1 参考2
说明:增加一个维度,但是不改变数值的个数。就是在axis的那一个轴上把数据加上去。
例1:原本为一维的2个数据,axis=0,则shape变为(1,2)。axis=1则shape变为(2,1)
例2:原本为 (2,3),axis=0,则shape变为(1,2,3),axis=1则shape变为(2,1,3)
7、np.reshape(a, newshape, order=‘C’) 参考
newshape:允许一个维度为-1,它会自动推测这一维度。
8、np.unique(a) 参考1 参考2
unique函数去除其中重复的元素,并返回排序过的array数组。
>>> a = np.array([[1, 1], [2, 3]])
>>> np.unique(a)
array([1, 2, 3])
9、PI 数学的π
scipy.pi, numpy.pi, math.pi 是相同的。 参考
PI = np.pi 这是一个常数来的。
10、np.full_like(a,val) 根据数组a的形状生成一个数组,每个元素值都是val。通常用于创建背景图。
参考博客 参考官方
>>> x = np.arange(6, dtype=int)
>>> np.full_like(x, 1)
array([1, 1, 1, 1, 1, 1])
>>> np.full_like(x, 0.1)
array([0, 0, 0, 0, 0, 0])
>>> np.full_like(x, 0.1, dtype=np.double)
array([ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1])
11、np.abs()
我实验是对一个常数调用这个函数的,发现直接py内置的abs函数会更加快。可能矩阵用这个函数才比较快吧。
12、np.where() 获取所有满足条件的元素下标
参考博客、参考官方
import numpy as np
arr = np.array([[1, 1, 1, 134, 45, 3, 46, 45, 65],[ 3, 23424, 234, 12, 12, 3, 546, 1, 2]])
np.where(arr==3) # 输出 (array([0, 1, 1]), array([5, 0, 5])) 分别代表行号,列号。一共三个元素满足条件。
arr[np.where(arr!=3)] = 0 # 此时 arr 只有0、3两种数值。
13、numpy中的ndarray与array的区别、不同
参考1、参考2、参考3
np.array只是一个便捷的函数,用来创建一个ndarray,它本身不是一个类。即,两者几乎是一样的。
14、array 转 str字符串:numpy.array2string()
参考官方
常用参数:
a : ndarray 输入的数组。
precision : int, optional 浮点的精确度。通常的打印print函数是8位,我通常设为6位。
suppress_small : bool, optional 是否把非常小的数值设为0。我通常设为 True。
separator : str, optional 元素之间的分割符号。通常是空格,或者逗号。
formatter : dict of callables, optional 自定义一些输出的格式。
x = np.array([1e-16,1,2,3])
print(np.array2string(x, precision=2, separator=',', suppress_small=True)) # 输出 [ 0., 1., 2., 3.]
x = np.arange(3.)
np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x}) # 输出 '[0.00 1.00 2.00]'
np.array2string(one_array, precision=6, suppress_small=True, separator=" ") # 我用过的一个例子
【本节下面还没有精简】
2、格式函数 astype()、dtype、type# np的astype()来调整dtype【数据格式】会更加好
b = np.array([1., 2., 3., 4.])
print b.dtype # dtype("float64")
print c = b.astype(int)# 用 astype(int) 得到整数,并且不改变数组长度 # 输出 array([1, 2, 3, 4]) 长度为4
print c.dtype # 输出 dtype('int32')
b.dtype = 'int'# 直接控制dtype.如果直接改变b的dtype的话,b的长度翻倍了,这不是我们想要的(当然如果你想的话)
print b.dtype # 输出 dtype('int32')
print b # 输出 array([0, 1072693248, 0, 1073741824, 0, 1074266112, 0, 1074790400]) 长度为8
(插多一个知识点)、shape reshape 使用后者转变矩阵大小 参考来源
arr=array(range(5))
print shape(arr) # 输出 (5,)
a=array([[1,2,3],[4,5,6]])
reshape(a, 6) # 输出 [1,2,3,4,5,6]
reshape(a, (3, -1)) #为指定的值将被推断出为2 。输出 [[1,2],[3,4],[5,6]
image = np.array([[1,2,3], [4,5,6]])
print image.shape(2L, 3L)
print image.reshape(-1, 6)# 行数为-1代表它自动计算,列数为6,得 [[1 2 3 4 5 6]]
Xtr, Ytr, Xte, Yte = load_CIFAR10('data/cifar10/') # 加载图像分类的数据集,此时Xtr为50000(张图片) x 32(长) x 32(宽) x 3(红绿蓝三色)
Xtr_rows = Xtr.reshape(Xtr.shape[0], 32 * 32 * 3) # Xtr_rows 变成 50000 x 3072
3、concatenate 联结不同np.array
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
print np.concatenate((a, b), axis=0)# array([[1, 2],[3, 4],[5, 6]])
print np.concatenate((a, b.T), axis=1)# array([[1, 2, 5],[3, 4, 6]])
4、计算平均值
Yte_predict、Yte 分别是一个list。
print 'accuracy: %f' % ( np.mean(Yte_predict == Yte))
5、nditer 可以逐个元素进行迭代
x =np.array([[1.0,5,2],[6,3,9]])
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
ix = it.multi_index
old_value = x[ix]
print old_value# 输出:1.0 , 5.0 , 2.0 , 6.0 , 3.0 , 9.0
it.iternext() # 下一个元素
6、randint 可以生成固定大小,固定取值范围的np数组。random 生成 [0, 1) 范围的值。
data = np.random.random((1000, 784))
labels = np.random.randint(2, size=(1000, 1))
7、计算两向量的欧式距离
dist = numpy.sqrt(numpy.sum(numpy.square(vec1 - vec2)))
dist = numpy.linalg.norm(vec1 - vec2) # 结果也是欧式距离。同上。
8、矩阵乘法。 dot才是矩阵相乘。* 没有使用到矩阵思想。你只需要记得:点积有累加的过程,叉积只有两数两数的相乘。
例一:
a = np.array([[1,4,5,7]])
b = np.array([[4],[6],[3],[0]])
print a.shape,b.shape # 输出 (1L, 4L) (4L, 1L)
print a.dot(b) # 矩阵乘法 输出(1L, 1L)的矩阵 即[[43]]
print b.dot(a) # 矩阵乘法 输出(4L, 4L)的矩阵
print a * b # 每个元素依次相乘 输出(4L, 4L)的矩阵
例二:(只有dot)
a = np.array([[1,4,7],[1,2,0]])
b = np.array([[4,1],[6,2],[3,1]])
print a.shape,b.shape # 输出 (2L, 3L) (3L, 2L)
print a.dot(b) #输出 [[49 16] [16 5]]
print b.dot(a) #输出 [[ 5 18 28] [ 8 28 42] [ 4 14 21]]
例三:(只有*)
a = np.array([[1,4],[2,0]])
b = np.array([[4,1],[6,2]])
print a * b #输出 [[ 4 4] [12 0]]
9、空。
10、dtype 可以把一字符串的list转化为浮点型,如[“1.55”,“6457”]->array([1.55, 6457])
print (dfsd)
coefs = np.asarray(values[1:], dtype='float32')
11、 numpy.random.choice 用于随机选样本。 参考来源
参数 replace = False 表示无放回抽样。重置的意思。参考来源
12、argsort函数:返回的是数组值从小到大的索引值
x = np.array([3, 1, 2])
np.argsort(x) #按升序排列
array([1, 2, 0])
np.argsort(-x) #按降序排列
array([0, 2, 1])
13、numpy.zeros与zeros_like的区别就是,Return a new array 是否返回新的数组,内存还是操作系统。你别管就行。 参考来源
np.zeros(5)
array([ 0., 0., 0., 0., 0.])
14、array、asarray的区别是前者可以选择是深复制,而后者限定是浅复制。参考1 参考2
arr1=np.ones((3,3))
arr2=np.array(arr1)
arr3=np.asarray(arr1)
arr1[1]=2
print 'arr1:\n',arr1 # [[ 1. 1. 1.] [ 2. 2. 2.] [ 1. 1. 1.]]
print 'arr2:\n',arr2 # [[ 1. 1. 1.] [ 1. 1. 1.] [ 1. 1. 1.]] 深复制,不与arr1一致。
print 'arr3:\n',arr3 # [[ 1. 1. 1.] [ 2. 2. 2.] [ 1. 1. 1.]] 因为是浅复制,所以与arr1一致。
15、shape 如果np.array中,内部(某个维度)长度大小不一致,array.shape 将忽略该维度。 参考来源
print np.array([[3, 1, 2],[8, 9]]).shape # 输出 (2L,)
print np.array([[3, 1, 2],[8, 9, 5]]).shape # 输出 (2L, 3L)
16、mean的使用
print np.mean([1,5,3]) # 输出 3.0
17、高斯分布 参考来源
tmp = np.random.normal(loc=0.0, scale=1.0, size=None)
loc:float 此概率分布的均值(对应着整个分布的中心centre)
scale:float 此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
size:int or tuple of ints 输出的shape,默认为None,只输出一个值
18、连续array,并保存。
np.save(filename, np.ascontiguousarray(array_data))
data = np.load(filename)
参考博客、官方path里面的更多函数
python文件和目录操作方法大全,推荐看网址
1、os.getcwd():得到当前工作目录,即当前Python脚本工作的目录路径。
2、os.listdir(“d:\aa”):返回指定目录下的所有文件和目录名。
3、os.chdir(“c:\qtest”):改变当前工作目录 参考来源
4、os.path.abspath(path) 返回绝对路径
5、os.path.relpath(path):返回相对路径,如…\MyFile.txt
6、os.getcwd():输出当前路径 参考来源
7、os.path.isfile(“名称”) :返回T/F,判断是否是文件还是文件夹。
8、os.path.dirname(“路径名”):调用一个该函数,返回上一层目录一次。参考来源
9、assert os.path.exists(path), path:判断是否存在路径
10、os.system(‘ls’): 调用ubuntu的shell或者win的dos,它不返回字符串的。它暂时够用了。更高级的调用终端的方法 见参考 参考1 参考2
11、os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]]) 参考1 参考2
topdown 参数:默认为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录(默认为开启)。
注意:如果一个目录下有多个文件,大约10万。它有可能会判断每个文件能否进去,所以就非常慢。我改为os.path.listdir()就一下子完成了。当遇到它非常慢的时候,可以自己手写一个实现。
for root, dirs, files in os.walk(".", topdown=False):
for name in files:
print(os.path.join(root, name))
for name in dirs:
print(os.path.join(root, name))
12、删除文件:
os.remove()
13、删除目录:
(1) os.rmdir()
用于删除指定路径的目录。仅当这文件夹是空的才可以, 否则, 抛出OSError。
(2) os.removedirs()
用于递归删除目录。像rmdir(), 如果子文件夹成功删除, removedirs()才尝试它们的父文件夹。
14、剪切文件
os.rename(src, dst)
15、os.path.relpath(path, start=os.curdir) 相对地址
start默认是当前地址,也可以自己选一个地址。返回的是不含有/开头的相对地址。
16、判断是否是绝对路径
os.path.isabs(path)
17、判断是否是软链接
os.path.islink(path)
18、os.path.basename(path)
只看/来划分的,返回最后一个/往后的部分。
19、os.path.dirname(path)
只看/来划分的,返回最后一个/往前的部分。
参考来源
import chardet
chardet.detect("abc")
{'confidence': 0.98999999999999999, 'encoding': 'GB2312'}#confidence是检测精确度,encoding是编码形式
1、《多线程基础》参考1 参考2
如果你的代码是IO密集型,多线程可以明显提高效率。例如制作爬虫
Python的多线程是有compromise的,在任意时间只有一个Python解释器在解释Python bytecode。
如果你不知道你的代码到底算CPU密集型还是IO密集型,教你个方法:
假设你使用的是multiprocessing的Pool,是使用多进程实现了concurrency
from multiprocessing import Pool
如果把这个代码改成下面这样,就变成多线程实现concurrency
from multiprocessing.dummy import Pool
两种方式都跑一下,哪个速度快用哪个就行了。
参考
1、获取当前时间
import datetime
d1 = datetime.datetime.now()
print d1
2、当前时间加上半小时。可以使用不断加1天,进行全年日期的迭代
d2 = d1 + datetime.timedelta(hours=0.5)
3、格式化字符串输出
d3 = d2.strftime('%Y-%m-%d %H:%M:%S')
4、将字符串转化为时间类型
d4 = datetime.datetime.strptime(date,'%Y-%m-%d %H:%M:%S.%f') # date为自己写的字符串
5、使用time库,输出程序运行耗时、当前日期 时间等。
import time
t1 = time.time()
print "%f" % time.time()# 1484742867.036000 秒
print "耗时(分钟)", (time.time() - t1) / 60
print time.localtime(time.time())# time.struct_time(tm_year=2017, tm_mon=1, tm_mday=18, tm_hour=20, tm_min=34, tm_sec=27, tm_wday=2, tm_yday=18, tm_isdst=0)
print time.asctime(time.localtime(time.time()))# Wed Jan 18 20:34:27 2017
6、线程睡眠 参考
推迟调用线程的运行,表示进程挂起的时间。我可以用来测试多线程的效率。
time.sleep(t)
参数
t -- 推迟执行的秒数。
1、np.random模块
(1)划分测试集、训练集 - shuffle函数
np.random.seed(1)
ratio = 0.8
size = int(len(data)*ratio) # 训练集长度
shuffle = range(len(data)) # 训练集索引
np.random.shuffle(shuffle) # 随机打乱索引。函数返回值是None,它是直接对shuffle内部改变的。
train = data.iloc[shuffle[:size]]
test = data.iloc[shuffle[size:]]
print np.random.randint(100) # 随机得到一个整数。
(2)随机抽取子样本 - choice函数
参考
numpy.random.choice(a, size=None, replace=True, p=None)
说明:
a 是可以是一维的list
size 代表要取多少个
replace 代表是否替换a数组
p 是每个元素被取的概率,可以不设置。
(3)打乱排列顺序 - permutation函数 参考官方、参考博客
numpy.random.permutation(x)
x如果是多维,至会打乱第一维。return : ndarray。
>>> np.random.permutation(10)
array([1, 7, 4, 3, 0, 9, 2, 5, 8, 6])
>>> np.random.permutation([1, 4, 9, 12, 15])
array([15, 1, 9, 4, 12])
>>> arr = np.arange(9).reshape((3, 3))
>>> np.random.permutation(arr)
array([[6, 7, 8],
[0, 1, 2],
[3, 4, 5]])
2、random模块
import random
random.seed(123456)
print random.randint(0,99) # 随机得到一个整数。
print random.uniform(10, 20)# 随机得到一个浮点数。
python random 从集合中随机选择元素 参考
import random
list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
slice = random.sample(list, 5) #从list中随机获取5个元素,作为一个片断返回
myqueue = Queue.Queue(maxsize = 10) 队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。
myqueue.put(10) 方法在队尾插入一个项目
myqueue.get() 从队头删除并返回一个项目
堆排序。堆顶是最小元素。 参考来源
《汇总全部常用参数解析的工具函数》:
(1)如果是想直接在代码中写参数,就用namedtuple,它既有元组的优势,也有字典的优势,它相当于是建立了一个类。参考
参考来源
argparse模块的作用是用于解析命令行参数.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument()
parser.parse_args()
解释:首先导入该模块;然后创建一个解析对象;然后向该对象中添加你要关注的命令行参数和选项,每一个add_argument方法对应一个你要关注的参数或选项;最后调用parse_args()方法进行解析;解析成功之后即可使用,下面简单说明一下步骤2和3。
下面拓展一个 ConfigParser 也能解析命令行。argparse的更多内容。
import argparse # 参数解析库。
parser = argparse.ArgumentParser() # 创建分析器,下面几行是设置分析器的参数有哪些。
parser.add_argument("-i", "--input", type=str, default=None, help="Input word vecs")
parser.add_argument("-l", "--lexicon", type=str, default=None, help="Lexicon file name")
parser.add_argument("-o", "--output", type=str, help="Output word vecs")
parser.add_argument("-n", "--numiter", type=int, default=10, help="Num iterations")
args = parser.parse_args() # 获取参数
wordVecs = read_word_vecs(args.input)# 获取分析器的具体设置过的参数
lexicon = read_lexicon(args.lexicon, wordVecs)
numIter = int(args.numiter)
outFileName = args.output
# 运行。retrofit.py 是上面的代码文件名。
python retrofit.py -i word_vec_file -l lexicon_file -n num_iter -o out_vec_file
拓展:argparse 还可以设置 action 参数。其中一个选项是store_true:代表着一旦有这个参数,做出动作“将其值标为True”,不需要设定具体数值。 也就是没有时,默认状态下其值为False。
下面这个 argparse 是我写项目时的重要参考,是精华版。可能与上面的有重复。
import argparse # 参数解析库。
parser = argparse.ArgumentParser(description='test model') # 创建一个解析器。里面的参数可以全部不设置。
parser.add_argument("-n", "--numiter", type=int, default=10, help="Num iterations")
parser.add_argument('--network_dir', type=str, help='the network dir')
parser.add_argument('--test', action='store_true', help='test network')
args = parser.parse_args() # 调用函数,进行解析参数。
numIter = args.numiter # 获取解析器里面的参数
# bash使用下面语句进行输入参数
python train_model.py -n 56 --enetwork_dir sdf --test
ArgumentParser.add_argument(name or flags…[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
注意点:
(1)一个参数的别名可以多个。没有-符号开头的参数是位置参数,直接按位置对应输入,调用时不能写参数名字。而有-符号,调用时就需要写参数名字。
(2)action的意思是,该参数是动作参数。不能输入数值。如上面的例子,只要调用是有–test,就会认为test变量是True。
import ConfigParser # 配置解析库。需要多生成一份文件,作为配置文件。
class ExperimentRun:
def __init__(self, config_filepath):
self.config = ConfigParser.RawConfigParser() # 初始化,返回类的实例。逐行读取配置文件。
try:
self.config.read(config_filepath) # 开始读取配置文件。
except:
print "Couldn't read config file from", config_filepath
return None
vocabulary_filepath = self.config.get("data", "vocabulary_filepath") # get是返回字符串、getfloat是返回浮点数。
synonym_list = self.config.get("data", "synonyms").replace("[","").replace("]", "").replace(" ", "").split(",")
self.load_experiment_hyperparameters() # 调用下面的函数。
def load_experiment_hyperparameters(self):
self.hyper_k1 = self.config.getfloat("hyperparameters", "hyper_k1")
config_filepath = sys.argv[1] # 读取第2个参数,也就是执行命令的 experiment_parameters.cfg
current_experiment = ExperimentRun(config_filepath)
;TIP: 这份是配置文件。分号开头行会被注释掉的。
[data]
pretrained_vectors_filepath = word_vectors/glove.txt
;pretrained_vectors_filepath = word_vectors/paragram.txt
vocabulary_filepath = linguistic_constraints/vocabulary.txt
synonyms = [linguistic_constraints/ppdb_synonyms .txt, linguistic_constraints/wordnet_synonyms .txt]
[hyperparameters]
hyper_k1 = 0.1
# 运行代码
python counterfitting.py experiment_parameters.cfg # 后面一个是配置文件名,名字后缀是任意的。
参考来源
解压gzip文件示例:
import gzip
f = gzip.open('file.txt.gz', 'rb')
file_content = f.read()
f.close()
创建gzip文件:
import gzip
content = "Lots of content here"
f = gzip.open('file.txt.gz', 'wb')
f.write(content)
f.close()
gzip压缩现有文件:
import gzip
f_in = open('file.txt', 'rb')
f_out = gzip.open('file.txt.gz', 'wb')
f_out.writelines(f_in)
f_out.close()
f_in.close()
使用追加的模式,可以实现创建、追加两种功能。
f = open("filename.txt","a")
f.write("GGG")
f.close()
参考1 参考2
sub 部分替代
\W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。 ^ 这是否定 非的意思。 _ 是下划线字符,普通用的。
1、split 原字符串对象的split不支持多个分隔符,所以要用正则的split
re.split(r"[0-9]",one_str)
注:使用括号匹配(即捕获组)的split,如(0-9) 而如(?:…)就取消括号是捕获组。捕获组不会删除分隔符,捕获的内容会保留下来。
\d 可以匹配一个数字,\w 可以匹配一个字母或数字
[\u4e00-\u9fa5]是匹配一个汉字的意思。在范围前面加个^ 意思是取反,而不是限制开头。 + 意思是连在一起的会当做一个。
p = re.compile(ur'[^\u4e00-\u9fa5]+')#先进行编译,然后得到的p就能在很多地方使用了。 r 是为了避免不用\\ 表示一个\。
text = p.sub(u' ', text).strip()
text = re.split(ur'!|,|。|?|;', text) # 遇到这些东西都会被舍弃而切分成一个个地小段
[]的作用 :[]内的字符可以以任意次序出现。
[]后有了+,[]内的字符可以取任意多个。于是[]内的字符可以以任意次序出现任意多次,直到遇到第一个非[]内的字符。
如[AB]+ 既可以匹配AAABBB又可以匹配BBBAAA BABAAABA等,不是一定要A…B…的次序。
2、加?变非贪婪模式。
例如:正则表达式"ab*“如果用于查找"abbbc”,将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。
3、使用r处理反斜杠。
这样你才能用如\w去匹配,不然你要\w。
4、re.compile(strPattern[, flag]) # strPattern是匹配模式串。flag是可选的模式,如re.X是详细模式。以下两个等价
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""", re.X)
a = re.compile(r"\d+\.\d*")
5、match与search都是为了返回一个match对象,match只能固定位置开始,而search如果当前位置开始匹配不成功,它会找下一个下标。
match对象:里面有分组,其实就是切分后的模式串。当然还有其他子函数。
例子:
pattern = re.compile(r'hello')
match = pattern.match('hello world!')
if match:
print match.group() # 输出 hello
例子2:此例使用match()无法成功匹配
pattern = re.compile(r'world')
match = pattern.search('hello world!')
if match:
print match.group() # 输出 world
6、findall才能返回全部匹配的子串。
p = re.compile(r'\d+')
print p.findall('one1two2three3four4') # 输出 ['1', '2', '3', '4']
7、sub或subn进行替换字符串。
直观的能够被电脑识别的的数据序列化格式,容易被人类阅读。它会比xml、josn更好。
假设已有一个.yaml格式的文件,就能load进来了。
one_dict = yaml.load(file('one_file.yaml')) # 得到dict格式的。也就是一个参数配置文档。
参考1 参考2 参考3
《四步》:创建logger->创建格式formatter->创建并设置handler->logger全部添加handler
《概念》:
Logger 记录器,里面可以装任意多个Handle,它们是并行工作的。
Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地。
Formatter 格式化器,指明了最终输出中日志记录的布局。具体的可以查参考3。
Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。暂时不用学它。
《注意》:
1、如果不使用logger,就仅能输出到控制台、或者文件中。不能兼顾输出到两者。
规范:全部情况都使用logger。
2、logger以及handler都可以setLevel的。logger是全局性的,帮所有handler都设置level,但是handler设置的才是最终的。
规范:logger不设置level,仅对handler设置level。
3、StreamHandler、FileHandler两者的区别
前者是导出到流(如控制台),不需要任何参数。后者是导出到文件,必须要定义文件名。
即:StreamHandler用于输出到控制台,FileHandler用于输出到文件。
logging.FileHandler("./log.txt", mode='w', encoding=None, delay=False)
4、logger 可以通过字符串的name来使得不同模块之间使用写到相同的文件中。
name默认None,因为它会返回root logger。它是logging内部全局性的,所以你为它改动的,后续只要用到getLogger()函数,都会受前者影响。尽量给name名字。
logger = logging.getLogger(name="my_logger_1")
非常齐全的实践例子:
def run():
# 第一步:创建logger
logger = logging.getLogger("my_logger_1")
# 第二步:创建格式formatter-
formatter = logging.Formatter('%(asctime)-15s filename %(filename)s funcName %(funcName)s message %(message)s')
# 第三步:创建并设置handler。下面是两个不同的handler。
hander1 = logging.StreamHandler()
hander1.setFormatter(formatter)
hander1.setLevel(logging.INFO)
hander2 = logging.FileHandler("./log.txt", mode='w', encoding=None, delay=False)
hander2.setFormatter(formatter)
hander2.setLevel(logging.INFO)
# 第四步:logger全部添加handler
logger.addHandler(hander1)
logger.addHandler(hander2)
# 一些测试输出
logger.debug('this is a loggging debug message') # 最低等级
logger.info('this is a loggging info message')
logger.warning('this is loggging a warning message')
logger.error('this is an loggging error message')
logger.critical('this is a loggging critical message') # 最高等级
# 验证不同模块中写到同一份log文件。
import wuyong1
wuyong1.run() # 该函数只有一个getLogger函数,以及logger.info()测试输出函数。
# 验证一个模块中输出多份log文件。
for name in ["hh1", "hh2", "hh3"]:
logger = logging.getLogger(name=name)
formatter = logging.Formatter('asctime %(asctime) filename %(filename)s funcName %(funcName)s message %(message)s')
hander = logging.FileHandler(filename=name+".txt", mode="w")
hander.setFormatter(formatter)
hander.setLevel(logging.INFO)
logger.addHandler(hander)
logger.debug('this is a loggging debug message') # 最低等级
logger.info('this is a loggging info message')
logger.warning('this is loggging a warning message')
logger.error('this is an loggging error message')
logger.critical('this is a loggging critical message') # 最高等级
run()
1、获取当前路径
print __file__ # 输出 D:/aa/untitled6/main.py
print sys.argv[0] #网上说,比__file__更稳定些。 # 输出D:/aa/untitled6/main.py
print os.path.dirname(__file__) # dirname返回文件名前面的目录名 # 输出D:/aa/untitled6
2、sys.stdout 重定向输出
重定向的意义就是输入或者输出不是控制台,而是从文件。初始时 sys.stdout指向控制台。参考来源
使用本方法后,控制台打印的东西将会是空值,除非你自己写一个buff(见总启)就能够既在控制台有东西输出,又在文件中有输出。
此外也可以选择性地,在控制台输出一部分,在文档中输出一部分,我觉得这个才是你最需要的。(保留下一stdout的原指向,然后恢复就能输出到控制台了,见总启)。
3、增加环境变量(即引用模块的路径)参考来源
当我们导入一个模块时:import xxx,默认情况下python解析器会搜索当前目录、已安装的内置模块和第三方模块,搜索路径存放在sys模块的path中。
但是从实践中发现,只能import 才有用,如果想直接 word2vec.load(“文件名称”) 依旧要当前工作环境下才可行。
>>> print(sys.path) # 输出所有会被搜索的路径名称列表。
>>> sys.path.append("引用模块的路径") # 增加新的作为环境变量的作用。程序运行结束后失效。
4、sys.argv 获取运行python文件的时候命令行参数,返回一个list。
例如,第一个是py文件,后面的是输入py文件的参数:
['/media/private/fg_ConvNet_s0.5_16_24_48/../train_model.py', '/media/private/fg_ConvNet_s0.5_16_24_48']
提供了打印出任何Python数据结构类和方法,输出时比较整齐。 参考来源
data = [(1,{'a':'A','b':'B','c':'C','d':'D'}),
(2,{'e':'E','f':'F','g':'G','h':'H',
'i':'I','j':'J','k':'K','l':'L'
}),
]
from pprint import pprint
print 'PRINT:'
print data
print
print 'PPRINT:'
pprint(data)
输出:
PRINT:
[(1, {'a': 'A', 'c': 'C', 'b': 'B', 'd': 'D'}), (2, {'e': 'E', 'g': 'G', 'f': 'F', 'i': 'I', 'h': 'H', 'k': 'K', 'j': 'J', 'l': 'L'})]
PPRINT:
[(1, {'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D'}),
(2,
{'e': 'E',
'f': 'F',
'k': 'K',
'l': 'L'})]
1、假如在同一项目主目录下,假设名为A.py的文件需要调用B.py文件内的C(x,y)函数则只需
# 方法1
import B
if __name__ == "__main__":
B.C(x,y)
# 方法2
from B import C
if __name__ == "__main__":
C(x,y)
2、假如在同一项目主目录下,假设有 E:/myproject/son_folder/A.py 的文件只需
import son_folder.A # 因为你当前运行环境就在E:/myproject 下,所以不需要写这一块,而且也不能写。
3、若A.py和B.py位于不同的目录下,可以用以下方法(假设B.py位于D盘的根目录下)
引用所在路径
import sys
sys.path.append('D:/')
import B
if __name__=="__main__":
print B.pr(x,y)
1、安装库并且虚拟出环境 参考
-m 意思是将库中的python模块用作脚本去运行。参考
python3 -m pip3 install virtualenv # 安装库
virtualenv --no-site-packages venv # venv 是虚拟环境的名字。所有第三方的包都会被pip安装到site-packages目录下,所以no-site-packages 的意思是该目录下的不要复制过来的,想要一个干净的环境。
source venv/bin/activate # source 是mac系统运行脚本的命令,win直接用脚本名字运行。active在win下是放在venv/Scripts文件下
pip install jinja2 # 在该虚拟环境下安装某些库。
deactivate # 推出虚拟环境。
2、导出、导入环境。参考 参考2
pip freeze --all > f:\requirements.txt # 1、>是导出文件的意思,缺了就会在显示屏中打印。参考中有一个tee的linux命令,它与>一样是输出到文件用的。2、--all 是全体导出的意思,缺了就会少几个包,如pip , wheel , setuptools 等包,是自带的而无法(un)install的。3、f:\ 是win系统的f盘路径。
pip install -r f:\requirements.txt # -r 是从文件中加载需要安装库的名字。
1、groupby 在统计区间频数的应用 参考
from itertools import groupby
lst= [2648, 2648, 2648, 63370, 63370, 425, 425, 120]
for k, g in groupby(sorted(lst), key=lambda x: x//50):
print('{}-{}: {}'.format(k*50, (k+1)*50-1, len(list(g))))
(1)namedtuple
参考
常用在参数定义中,它既有元组的优势,也有字典的优势,它相当于是建立了一个类。
from collections import namedtuple
args = namedtuple('args', ['video_path', 'output_dir', 'step', 'begin_frame'])
return args(
video_path='/home/like_videos/video20181202',
output_dir='/home//like_videos/video20181202-frames',
step=1,
begin_frame=0
)
下面是可能会使用到的功能:
# ===== 导入模块、以及判断模块是否有某属性 ======
sys.path.insert(0, args.network_dir) # 临时改变系统变量,增加运行的主路径进去,这样才方便导入模块。 '/media/xxxxxxx'
train_info = importlib.import_module('train_info') # train_info是一个py脚本。
print(hasattr(train_info, 'gpus')) # 返回True或者False,判断是否有某变量,该变量需要是全局变量。
参考
(1)最基本的用法,将tqdm() 直接包装在任意迭代器上。
from tqdm import tqdm
import time
text = ""
for char in tqdm(["a", "b", "c", "d"]):
text = text + char
time.sleep(0.5)
参考
import time
import progressbar
p = progressbar.ProgressBar()
N = 1000
for i in p(range(N)):
time.sleep(0.01)
参考1 参考2
copy库:浅拷贝和深拷贝的操作都可以在copy模块中找到,其实copy模块中只有两个函数可用,copy()进行浅拷贝操作,而deepcopy()进行深拷贝操作。
赋值、浅拷贝、深拷贝的区别
(1)先决知识:浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。
(2)赋值:拷贝了这个对象的引用,即id与原始变量相同。原始变量或者赋值产生的变量,是完全同步一致的。
(3)浅拷贝:id不同,但里面元素id相同。如果修改字符串等“原子”类型,因为这些类型没有拷贝而言,所以与原始变量尽管id相同也不会同步。但是会与原始变量的列表、类实例等同步。
(4)深拷贝:id不同,里面元素id也不同。同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。
(5)同样 numpy 下的数据结构与数据类型的转换(np.array vs. np.asarray)
np.array() 是深拷贝,np.asarray() 是浅拷贝
>>> import copy
>>> a = ["fff", [1,2]]
>>> b = a
>>> c = a[:]
>>> d = copy.deepcopy(a)
>>> id(a)
139955451108168
>>> id(b)
139955451108168
>>> id(c)
139955451224648
>>> id(d)
139955451224864
>>> a[0] = "eee"
>>> a[1][1] = 33
>>> a
['eee', [1, 33]]
>>> b
['eee', [1, 33]]
>>> c
['fff', [1, 33]]
>>> d
['fff', [1, 2]]
1、绘制直方图 参考1 参考2 参考3
因为通常用excel来解决了,所以暂时还没实践。
2、多线程关闭matplotlib的窗口参考来源
3、matplotlib绘制表格参考来源
参考1、参考2
# 当前目录就会被共享出去,别人可以用wget对url下载。
python -m SimpleHTTPServer 8000
多个python版本时的调用:
python3 -m jupyter notebook
参考
个人认为它就是更加方便处理list、dict这两个数据结构了。
import json
jsonData = '[{"a":1,"b":2,"c":3,"d":4,"e":5}, {"aa": "bb"}]'
text = json.loads(jsonData)
print(text) # 此时test就是一个list,里面有dict结构。相当于快速解析字符串。
1、获取网页源码 参考
import urllib
content = urllib.request.urlopen('http://www.baidu.com/').read()
print(content.decode('gb2312')) # 或者utf8。它会从bytes类型装为str类型,但是它对结果没什么影响。
2、网址里面含有中文 参考
import urllib
url = ‘含中文的网址’
url = urllib.parse.quote(url)
result = urllib.request.urlopen(url)
API文档一览
(1)Image转numpy:
from PIL import Image
im = Image.open('lena.png') # 打开图片
im_array = np.array(im) # 也可以用 np.asarray(im) 区别是 np.array() 是深拷贝,np.asarray() 是浅拷贝
(2)numpy转Image:用Image.fromarray()函数
im = Image.fromarray(im_array)
(3)保存图片:.save()函数
im.save('new_lena.png')
(4)获取大小、模式、格式
print img.size #图片的尺寸
print img.mode #图片的模式,如RGBA
print img.format #图片的格式,如PNG
(5)把Image对象序列化,用.getdata()
np.array(im.getdata())
from sklearn import svm
from sklearn import datasets
clf = svm.SVC()
iris = datasets.load_iris()
X, y = iris.data, iris.target
clf.fit(X, y)
import pickle
s = pickle.dumps(clf) # 返回字符串名称,如果是dump方法就能指定路径了。
clf2 = pickle.loads(s)
print clf2.predict(X[0:1]) # 输出 array([0]),即预测为 0
有可能代替上面的pickle。它除了实现转储、还能压缩。还能处理numpy格式,处理普通文件格式,只要你想存的都行。不止是预测模型clf,而且不难的,所以目前我很多时候都用它。
from sklearn.externals import joblib # 注意:你不能直接import joblib。否则导入导出格式不一致的。当然你全部统一 import joblib也是可以的。
joblib.dump(clf, 'filename.pkl')# 转储到磁盘。
clf = joblib.load('filename.pkl')# 加载进来。
joblib 进行存储np格式。我们可以保存处理后的向量,下次使用分类器的时候就不用从头执行,只需要读取向量出来就行了。当然,如果你想导出训练后的分类器也是可以的。
import joblib
filename = u"D:\\data\\CarEmotion\\test.pkl"# 先写入、后读出的地址。
to_persist = [('a', [1, 2, 3]), ('b', np.arange(10))]# 要写的内容
joblib.dump(to_persist, filename)# 写入数据
data = joblib.load(filename)# 读取数据
内存的读取写入用 loads()、dumps()。磁盘的读取写入用 load()、dump()。即s代表字符串。不仅 joblib 与 pickle 适用,json也适用。 廖雪峰博客的序列化、参考博客1
参考1 参考2
os.system (“cp %s %s” % (filename1, filename2)) # 调用系统终端命令。
shutil.copyfile( src, dst) 从源src复制到dst中去。这个是很慢。建议调用系统终端命令。
1、–user 参数可以不适用管理员权限,而下载库到用户目录下。 参考1
python -m pip install 包名 --user
参考
1、 -u 可以不缓存,print的时候直接打印。否则等缓冲区满了才会打印数据。
2、-V 参数,或者–version,输出Python的版本
python -V
1、numpy.fromfile(file, dtype=float, count=-1, sep=’’) 参考1 参考2
(1)如果是8bit的占用一个整型,就用dtype=uint8。
例子:
b = np.fromfile("a.bin", dtype=np.uint8)
1、linux 查看python安装路径,版本号
参考
2、获取 Python 特定模块的路径
参考
import a_module
print a_module.__file__
1、requests 模块
报错:ImportError: No module named requests
解决方案:pip install requests
2、urllib.request 或 urllib.parse 模块
报错:module ‘urllib’ has no attribute ‘request’ 或者 ‘parse’
解决:(1)因为python3.X有时候不会将子模块自动导入进去,所以改成import urllib.request问题就解决了。
(2)如果是python2,似乎它本来就导入不了的,解法是我在py2调用py3,即 os.system(“python3 code_file.py”)