在做大数据处理时,可能会涉及到大矩阵运算和并行计算,python原生对这些支持的不是太好,必须要进行优化。
大数据、大矩阵、并行计算时,可以从以下几点对python代码进行优化:
对向量、矩阵做运算(拼接)时,使用numpy,效率会高于list。
用joblib将numpy格式存储矩阵为’.jl’格式,读入asm opcode 1,2,3,4-gram(8G)数据(格式化为矩阵),只需要20s。改进前数据均存储为.csv格式,读入8G的csv并解析为list of list,需要1122s。
list of list的矩阵,做merge要借助for循环(python原生不支持并行操作),需要120s。改进后,用numpy矩阵,merge时只需要做np.hstack操作,5s就搞定。
Cython 是包含 C 数据类型的 Python。Cython让你拥有C的数据类型(比py的轻量级)和python的代码结构。
下面是一个普通的python函数。
def fun(r):
x = 3.1415926*r*r
y = 2*3.14*r
return x-y
在正常的python代码中调用它
import calc
import time
start_time = time.time()
for i in range(10000000):
calc.fun(i)
print('costed {} seconds'.format(time.time() - start_time))
执行main函数耗时4.44s
下面是用Cython改写的代码,注意只是增加了类C的变量声明。
from libc.stdint cimport float
cimport cython
def fun(r):
cdef float x
cdef float y
x = 3.1415926*r*r
y = 2*3.14*r
return x-y
在python代码中,调用这个Cython函数。
import time
import pyximport
pyximport.install(
reload_support=True)
import calc
start_time = time.time()
for i in range(10000000):
calc.fun(i)
print('costed {} seconds'.format(time.time() - start_time))
用掉3.70s。
一些大数据处理操作,比如对10W个文件提feature,就可以用多进程,利用多CPU并行操作加速。
from multiprocessing import Pool
P = Pool(processes=2)
P.apply_async(fun1, (para11, para12))
P.apply_async(fun2, (para21, para22))
P.close()
P.join()
压缩存储能节省磁盘空间,但文件读写会耗费更多时间,属于用时间换空间的思路。
joblib提供了直接存取numpy矩阵数据的接口。
下面做一个简单的实验
import joblib as jl
import numpy as np
matrix = np.zeros((10000,10000))
jl.dump(matrix, 'x.jl')#非压缩存储,耗时1.34s,存储763M
jl.dump(matrix, 'x.jl.z')#压缩存储,耗时3.19s,存储3.4M
jl.load('x.jl')#536ms
jl.load('x.jl.z')#1.36s
用del可以将对象占用内存空间的引用计数值置零(Deletion of a name removes the binding of that name from the local or global namespace)。它并不能让对象占用的内存被回收,但一段内存的引用计数变为零,就说明它可以再次被重新使用了(所以del后,不必要GC介入)。
如果不用del,下面这段代码就可能MemoryError
import numpy as np
matrix1 = np.zeros((60000,100000))
matrix2 = np.zeros((60000,100000))
# using matrix1
# using matrix2
利用del,可以将用完后没必要占用内存的对象删掉,下面的代码对内存耗费就没上面的大。
import numpy as np
matrix1 = np.zeros((60000,100000))
# using matrix1
del matrix1
matrix2 = np.zeros((60000,100000))
# using matrix2
del matrix2