Python Stack For Data Analysis


Python Stack Overview

  • Numpy
  • Pandas
  • Matplotlib
  • Scipy

Python系统自带一些数值计算的API,但它们使用起来效率不高;Numpy被设计用来专门做数值计算,底层做了大量的优化;Pandas是Numpy的封装;Matplotlib用来做数据可视化

Numpy

Numpy主要用于做矩阵的数值运算,对常用的数学操作做了封装,使用起来极为方便,而且在性能方面也比Python的list要高不少,因此在数值计算方面Numpy非常流行。

Matrix Products

我们可以来对比一下numpy和python的矩阵点积运算,假设有两个矩阵$a=[x_a,y_a]$, $b=[x_b,y_b]$,则ab点积的代数运算为 $a·b=x_ax_b+y_ay_b$,其结果为一个标量。代码如下

import numpy as np 
from datetime import datetime

a = np.random.randn(100)
b = np.random.randn(100)
T = 100000

## Python code
## use a for loop
def slow_dot_product(a,b ):
    result = 0
    for e,f in zip(a,b):
        result += e*f
    return result

dt0 = datetime.now()
for t in range(T): 
    slow_dot_product(a,b)
dt1 = datetime.now() - dt0

## numpy version 
dt0 = datetime.now()
for t in range(T):
    #numpy dot product
    a.dot(b)
dt2 = datetime.now() - dt0

print("dt1/dt2: ", dt1.total_seconds() / dt2.total_seconds()) #~40

Numpy实际上是使用vectorization取代for循环来做运算,这也是为什么numpy会特别快的原因。另一个能提高效率的场景是对每个矩阵的元素做运算:

m = np.ones([1,2]) #[1,1]
m = m*2 #[2,2]

可以看出numpy并没有使用for循环,当数组的size很大时,numpy可以极大的节约内存开销和提升开发效率。

Vectors and Matrices

向量和矩阵是最基本的数值计算单元,我们还是来对比下Python和Numpy的实现

#二维数组
# Python
L = [ [1,2], [3,4] ]
# Numpy
M = np.array([ [1,2], [3,4] ])
type(M) #<class 'numpy.ndarray'>

在定义上看,没有太大区别,但是在访问矩阵元素上,Numpy支持以tuple作为脚标进行访问

#Python
a = L[0][0] #矩阵左上角元素
#Numpy
a = M[0,0] 

Generating Matrices to Work With

除了前面提到的使用np.array创建矩阵的方法外,Numpy还提供了很多其它的API来创建特殊的矩阵

#zeors
np.zeros(4) #一维zero g数组
np.zeros((5,5)) #5x5的zero数组
#ones
np.ones(4)
np.ones((3,5))
#linspace
np.linspace(0,10,30) #start, end , 点的个数 => 产生等距的点的数组
#单位阵
np.eye(4) #4x4的单位阵
#Random number
np.random.rand(1) #按照等概率分布产生一个[0-1)之间的随机数
np.random.rand(3,3) #产生一个[0-1)之间的3x3矩阵
np.random.randn(5) #产生5个随机数,服从一维正态分布
np.random.randn(10,10) #产生10x10个随机数,服从二维正态分布
np.random.randint(1,100,10) #产生10个[1,100)之间的随机数组

Matrix Operations

除了定义矩阵之外,Numpy还内置了很多矩阵运算的API

#转置矩阵
M = np.array([ [1,2], [3,4] ])
transposM = M.T #array([[1, 3], [2, 4]])
#逆矩阵
inverseM = np.linalg.inv(M) #array([[-2. ,  1. ],[ 1.5, -0.5]])
M.dot(inverseM) #should be identity matrix
#矩阵的秩
detM = np.linalg.det(A)
#对角矩阵
diagM = np.diag(A)
#矩阵的外积 
a = np.array([1,2])
b = np.array([3,4])
outerProduct = np.outer(a,b) #array([[3, 4], [6, 8]])
#矩阵的内积
innerProduct = np.inner(a,b) #same as a.dot(b)
#矩阵的对角线求和
np.diag(A).sum() #5
np.trace(M) #5
#矩阵的协方差
X = np.random.randn(100,3)
conv = np.cov(X.T)
#特征值和特征向量
np.linalg.eig(conv)
np.linalg.eigh(conv)

Pandas

Loading in Data

Resources