612python数据分析书(2天)
第一章系统
import os
os.getcwd() ##获取当前工作目录
os.chdir('F:/Projects/python/616python_data_analysis/3358OS_06_Code/code6')#更改当前工作目录
用pkgutil和pydoc可以遍历numpy和scipy的各个子库和简单说明
import pkgutil as pu
import pydoc
#用pkgutil和pydoc可以遍历numpy和scipy的各个子库和简单说明
import numpy as np
import matplotlib as mpl
import scipy as sp
print "NumPy SciPy Matplotlib version", np.__version__ | sp.__version__ | mpl.__version__#获得版本号
def clean(astr):
s = astr
# remove multiple spaces
s = ' '.join(s.split())
s = s.replace('=','') #=换成
return s
def print_desc(prefix, pkg_path):
#利用pkgutil的iter_modules()函数遍历指定目录的子库,返回一个元组每个元祖3个元素组成,第二个元素是名称,第三个是布尔值
for pkg in pu.iter_modules(path=pkg_path):
name = prefix + "." + pkg[1]
if pkg[2] == True:
try:
docstr = pydoc.plain(pydoc.render_doc(name))#pydoc.render_doc()返回指定子程序包或者函数的文件字串,可能含有的非打印字符用pydoc.plain剔除
docstr = clean(docstr)
start = docstr.find("DESCRIPTION") #找描述
docstr = docstr[start: start + 140]
print name, docstr
except:
continue
print_desc("numpy", np.__path__)
print_desc("scipy", sp.__path__)
print_desc("pandas", pd.__path__)
print_desc("matplotlib", mpl.__path__)
import statsmodels as sm
print "statmodels version", sm.__version__#显示statsmodels的子库
print_desc("statsmodels", sm.__path__)
import sqlalchemy as sa
print "sqlalchemy version", sa.__version__
print_desc("sqlalchemy", sa.__path__)
import nltk#文本
print "nltk version", nltk.__version__
print_desc("nltk", nltk.__path__)
import sklearn
print "sklearn version", sklearn.__version__
print_desc("sklearn", sklearn.__path__)
第二章:主要,array,numpy,scipy,画图
#arrays slicing.
print "In: a = arange(9)"
a = np.arange(9)
print a[3:7] #Out: array([3, 4,5,6,7])
print a[:7:2]#Out: array([0, 2, 4, 6])
print a[::-1]
s = slice(3,7,2)
print a[s]#Out: array([3, 5])
s = slice(None, None, -1)
print a[s]#Out: array([8, 7, 6, 5, 4, 3, 2, 1, 0])
#Numpy 数组基础操作--索引、组合、分割、复制、遍历、转换、序列化(四)https://blog.csdn.net/mokeding/article/details/17476979
#splitting.py,堆叠
print "In: a = arange(9).reshape(3, 3)"
a = np.arange(9).reshape(3, 3)
print np.hsplit(a, 3)
print np.split(a, 3, axis=1) #一样的和hsplit
print np.vsplit(a, 3)#Out: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
print np.split(a, 3, axis=0) #Out: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
c = np.arange(27).reshape(3, 3, 3)
print np.dsplit(c, 3)#dsplit函数使用的是面向深度的分割
#堆叠
a = np.arange(9).reshape(3,3)
b = 2 * a
print np.hstack((a, b))
print np.concatenate((a, b), axis=1) #水平叠加
print np.vstack((a, b)) #垂直叠加
print np.concatenate((a, b), axis=0)#垂直叠加
print np.dstack((a, b))#深度叠加
oned = np.arange(2)#Out: array([0, 1])
print "In: twice_oned = 2 * oned"
twice_oned = 2 * oned
print np.column_stack((oned, twice_oned)) #列式堆叠 ,类似hstack()
print np.column_stack((a, b))
print np.column_stack((a, b)) == np.hstack((a, b))
print np.row_stack((oned, twice_oned))#行式堆叠 ,类似hstack()
print np.row_stack((a, b))
print np.row_stack((a,b)) == np.vstack((a, b))
#矩阵
a = np.arange(5)
print (a.dtype) / (a.shape) /(a)
m = np.array([np.arange(2), np.arange(2)])#print (a.dtype) / (a.shape) /(a)
import numpy as np
# ndarray .
b = np.arange(24).reshape(2, 12)
print (b.ndim) /(b.size) (b.itemsize) (b.nbytes ) ##维度、元素数量\ #各个元素占用的字节数\ #整个数组所需的字节数量\
b.resize(6,4)
b.T #转置
# 数组形状Demonstrates multi dimensional arrays slicing.
b = np.arange(24).reshape(2,3,4)
print b.ravel() #ravel()函数将多维数组变成一维数组
print b.flatten()#返回真实的数组,ravel只是数组视图
b.shape = (6,4)
print b
print b.transpose()#转置
b.resize((2,12))#调整大小
#虚数
b = np.array([1.j + 1, 2.j + 3])
print (b,b.real, b.imag , b.dtype ,b.dtype.str )
#b.flat
b = np.arange(4).reshape(2,2)
f = b.flat
for it in f:
print (it)
print( b.flat[2])
print (b.flat[[1,3]])
b.flat[[1,3]] = 1
print (b)
print np.arange(7, dtype='f') #Out: array([ 0., 1., 2., 3., 4., 5., 6.], dtype=float32)
print np.arange(7, dtype='D') #Out: array([ 0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j])
#astype数组元素转换成指定类型
import numpy as np
print np.float64(42) #Out: 42.0
print np.int8(42.0)
print np.bool(42)
print np.float(True) #Out: 1.0
print np.arange(7, dtype=np.uint16)
try:
print np.int(42.0 + 1.j)
except TypeError:
print "TypeError"
#Type error
print float(42.0 + 1.j)
#Type error
b = np.array([ 1.+1.j, 3.+2.j]) #把numpy数组 转换成python列表
print b , b.tolist() ,b.tostring()
print np.fromstring('\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x08@\x00\x00\x00\x00\x00\x00\x00@', dtype=complex)
print "In: fromstring('20:42:52',sep=':', dtype=int)"
print np.fromstring('20:42:52',sep=':', dtype=int)
#Out: array([20, 42, 52])
##dtype1.2-0611
a = np.array([[1,2],[3,4]])
print a[0,0]#Out: 1
print a.dtype.byteorder #Out: =
print a.dtype.itemsize #Out: 8
# dtype attributes
t = np.dtype('Float64')
print t.char
print t.type#Out:
print t.str#Out: '
print b.astype('complex')
'''
数组类:ndarray(数组),注意numpy.array和标准Python库类array.array并不相同,后者只处理一维数组和提供少量功能。更多重要ndarray对象属性有:
ndarray.ndim ——数组轴(秩)的个数
ndarray.shape ——数组的维度;是一个指示数组在每个维度上大小的整数元组。例如一个n排m列的矩阵,它的shape属性将是(2,3),这个元组的长度显然是秩,即维度或者ndim属性
ndarry.size——数组元素的总个数
ndarray.dtype ——用来描述数组中元素类型的对象,可以通过创造或指定dtype使用标准Python类型。另外Numpy提供它自己的数据类型。
ndarray.itemsize ——数组中每个元素的字节大小。例如,一个元素类型为float64的数组itemsiz属性值为8(=64/8),又如,一个元素类型为complex32的数组item属性为4(=32/8).
ndarray.data——包含实际数组元素的缓冲区,通常我们不需要使用这个属性,因为我们总是通过索引来使用数组中的元素
'''
#######3图像链接https://blog.csdn.net/wizardforcel/article/details/72793092
scipy.misc,画图
#####################boolean_indexing-lena
import scipy.misc #输入输出
import matplotlib.pyplot as plt
import numpy as np
# Load the Lena array
lena = scipy.misc.ascent() #ascent : ndarray convenient image to use for testing and demonstration
#在对角线上面画点,不过选择的是照片对角线上可以被4整除的点
def get_indices(size):
arr = np.arange(size)
return arr % 4 == 0
# Plot Lena
lena1 = lena.copy()
xindices = get_indices(lena.shape[0])
yindices = get_indices(lena.shape[1])
lena1[xindices, yindices] = 0
plt.subplot(211)
plt.imshow(lena1)
lena2 = lena.copy()
# Between quarter and 3 quarters of the max value
lena2[(lena > lena.max()/4) & (lena < 3 * lena.max()/4)] = 0
plt.subplot(212)
plt.imshow(lena2)
plt.show()
# fancy.py=Load the Lena array 画斜线
lena = scipy.misc.ascent()
xmax = lena.shape[0]
ymax = lena.shape[1]
lena[range(xmax), range(ymax)] = 0
lena[range(xmax-1,-1,-1), range(ymax)] = 0# Set values on other diagonal to 0# x xmax-0# y 0-ymax
# Plot Lena with diagonal lines set to 0
plt.imshow(lena)
plt.show()
#ix.py-用numpy.random子程序包中的shuffle()函数把数组中的元素按照随机的索引号重新排列,使得数组产生相应的变化
def shuffle_indices(size):
arr = np.arange(size)
np.random.shuffle(arr)
return arr
#size=lena.shape[0,1..]
xindices = shuffle_indices(xmax)
np.testing.assert_equal(len(xindices), xmax)
yindices = shuffle_indices(ymax)
np.testing.assert_equal(len(yindices), ymax)
# Plot Lena
plt.imshow(lena[np.ix_(xindices, yindices)])
plt.show()
##########3.1copyciew
lena = scipy.misc.face() #与scipy有关的资料或书籍中,很多地方都以face和ascent图像进行演示,其中face图像是个彩色图像,。ascent图像是个灰度图像,
aview = lena.view() #创建一个视图,视图不是只读的
aview.flat = 0#通过flat迭代器将视图中的所有的值全部设为0
plt.imshow(aview)
#broadcasting声音处理 scipy.io.wavfile
import scipy.io.wavfile
import matplotlib.pyplot as plt
import urllib2
import numpy as np
response = urllib2.urlopen('http://www.thesoundarchive.com/austinpowers/smashingbaby.wav')
print response.info()
WAV_FILE = 'smashingbaby.wav'
filehandle = open(WAV_FILE, 'w') #filehandle
filehandle.write(response.read())
filehandle.close()
#返回数据阵列和采样率,wavfile()函数
sample_rate, data = scipy.io.wavfile.read(WAV_FILE)
print "Data type", data.dtype, "Shape", data.shape
plt.subplot(2, 1, 1)
plt.title("Original")
plt.plot(data)
newdata = data * 0.2
newdata = newdata.astype(np.uint8)
print "Data type", newdata.dtype, "Shape", newdata.shape
scipy.io.wavfile.write("quiet.wav", sample_rate, newdata)
plt.subplot(2, 1, 2)
plt.title("Quiet")
plt.plot(newdata)
plt.show()
vectorsum:range()和np.nrange()
from datetime import datetime
import numpy as np
"""
range()返回的是range object,而np.nrange()返回的是numpy.ndarray()
range尽可用于迭代,而np.nrange作用远不止于此,它是一个序列,可被当做向量使用。
"""
def numpysum(n):
a = np.arange(n) ** 2
b = np.arange(n) ** 3
c = a + b
return c
def pythonsum(n):
a = range(n)
b = range(n)
c = []
for i in range(len(a)):
a[i] = i ** 2
b[i] = i ** 3
c.append(a[i] + b[i])
return c
size = int(800) #sys.argv[]是用来获取命令行参数的,sys.argv[0]表示代码本身文件路径,所以参数从1开始. arg[1]表示第一个命令行参数
start = datetime.now()
c = pythonsum(size)
delta = datetime.now() - start
print "The last 2 elements of the sum", c[-2:]
print "PythonSum elapsed time in microseconds", delta.microseconds
start = datetime.now()
c = numpysum(size)
delta = datetime.now() - start
print "The last 2 elements of the sum", c[-2:]
print "NumPySum elapsed time in microseconds", delta.microseconds #2000
第三章:主要numpy
基础计算
import numpy as np
from scipy.stats import scoreatpercentile
data=np.loadtxt("mdrtb_2012.csv",delimiter='',usecols=(1,),skiprows=1,unpack=True) #skiprows=1不要第一行,unpack=True??
print "Max method", data.max() | np.max(data)
print "Min method", data.min() |np.min(data)
print "Mean method", data.mean()|np.mean(data)
print "Std method", data.std()|np.std(data)
#中位数可以用numpy或者scipy得到,下列代码将计算数据第50百分数
print "Median", np.median(data)
print "Score at percentile 50", scoreatpercentile(data, 50)
1、linalg模块
'''线性代数是数学的一个重要分支。numpy.linalg模块包含线性代数的函数。使用这个模块,我们可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等'''
1.1计算逆矩阵
import numpy as np
a=np.mat('1 0;0 2')
#逆矩阵
print a.I |np.linalg.inv(a)
#原矩阵*逆矩阵=单位矩阵
print a.I*a |np.linalg.inv(a)*a
1.2求解线性方程组
A = np.mat('1 2 -1;0 2 -8;-4 5 9')
b = np.array([0, 8, -9])
x = np.linalg.solve(A, b) # (2) 调用solve函数求解线性方程组:
print "check=", np.dot(A, x)# (3) 使用dot函数检查求得的解是否正确
1.3特征值和特征向量
#矩阵计算特征值和特征向量
A = np.mat("3 -2;1 0")
print "Eigenvalues", np.linalg.eigvals(A) #计算特征值
eigenvalues, eigenvectors = np.linalg.eig(A) #计算特征值和特征向量
for i in range(len(eigenvalues)):
print "Left", np.dot(A, eigenvectors[:,i])#用dot函数验证求得的解是否正确。
print "Right", eigenvalues[i] * eigenvectors[:,i] #分别计算等式 Ax = ax 的左半部分和右半部分,检查是否相等
1.4 奇异值分解
'''
Decomposition,奇异值分解)是一种因子分解运算,将一个矩阵分解为3个矩阵的乘积。奇异值分解是前面讨论过的特征值分解的一种推广。
在numpy.linalg模块中的svd函数可以对矩阵进行奇异值分解。该函数返回3个矩阵——U、Sigma和V,其中U和V是正交矩阵,Sigma包含输入矩阵的奇异值
'''
A=np.mat('4 11 14;8 7 -2')
U,Sigma,V=np.linalg.svd(A,full_matrices=0)# (2) 使用svd函数分解矩阵
print "U=",U |Sigma|V
# (3) 不过,我们并没有真正得到中间的奇异值矩阵——得到的只是其对角线上的值,而非对角线上的值均为0。我们可以使用diag函数生成完整的奇异值矩阵。将分解出的3个矩阵相乘
print 'Produce\n',U*np.diag(Sigma)*V
1.5 广义逆矩阵
A = np.mat('4 11 14;8 7 -2')
preudoinv = np.linalg.pinv(A) # (2) 使用pinv函数计算广义逆矩阵
print 'Check=', A * preudoinv # (3) 将原矩阵和得到的广义逆矩阵相乘
1.6 行列式:print 'Determinant',np.linalg.det(A)
2、fft模块
2.1 快速傅里叶变换
'''FFT(Fast Fourier Transform,快速傅里叶变换)是一种高效的计算DFT(Discrete FourierTransform,离散傅里叶变换)的算法。
FFT算法比根据定义直接计算更快,计算复杂度为O(NlogN) 。DFT在信号处理、图像处理、求解偏微分方程等方面都有应用。
在NumPy中,有一个名为fft的模块提供了快速傅里叶变换的功能。在这个模块中,许多函数都是成对存在的,也就是说许多函数存在对应的逆操作函数。
例如,fft和ifft函数就是其中的一对。'''
import numpy as np
from matplotlib.pyplot import plot, show
# (1) 创建一个包含30个点的余弦波信号
x=np.linspace(0,2*np.pi,30)
wave=np.cos(x)
# (2) 使用fft函数对余弦波信号进行傅里叶变换。
transformed=np.fft.fft(wave)
# (3) 对变换后的结果应用ifft函数,应该可以近似地还原初始信号。
print np.all(np.abs(np.fft.ifft(transformed)-wave)<10**-9)
# (4) 使用Matplotlib绘制变换后的信号。
plot(transformed)
show()
2.2移频
import numpy as np
from matplotlib.pyplot import plot, show
# (1) 创建一个包含30个点的余弦波信号
x=np.linspace(0,2*np.pi,30)
wave=np.cos(x)
# (2) 使用fft函数对余弦波信号进行傅里叶变换。
transformed=np.fft.fft(wave)
# (3) 使用fftshift函数进行移频操作。
shifted=np.fft.fftshift(transformed)
# (4) 用ifftshift函数进行逆操作,这将还原移频操作前的信号。
print np.all((np.fft.ifftshift(shifted) - transformed) < 10 ** -9)
# print np.all((np.fft.ifftshift(shifted) - transformed) < 10 ** -9)
plot(transformed,lw=2)
plot(shifted,lw=3)
show()
3、随机数模块
3.1 随机数
import numpy as np
from matplotlib.pyplot import plot, show
# (1) 初始化一个全0的数组来存放剩余资本。以参数10000调用binomial函数,
cash=np.zeros(10000)
cash[0]=10000
outcome=np.random.binomial(9,0.5,size=len(cash))
# (2) 模拟每一轮抛硬币的结果并更新cash数组。打印出outcome的最小值和最大值,以检查输出中是否有任何异常值:
for i in range(1,len(cash)):
if outcome[i]<5:
cash[i]=cash[i-1]-1
elif outcome[i]<10:
cash[i]=cash[i-1]+1
else:
raise AssertionError('Unexpected outcome')
print outcome.min(),outcome.max()
# (3) 使用Matplotlib绘制cash数组:
plot(np.arange(len(cash)),cash)
show()
3.2 超几何分布
import numpy as np
from matplotlib.pyplot import plot, show
# (1) 使用hypergeometric函数初始化游戏的结果矩阵。该函数的第一个参数为罐中普通球的数量,第二个参数为“倒霉球”的数量,第三个参数为每次采样(摸球)的数量。
points=np.zeros(100)
outcomes=np.random.hypergeometric(25,1,3,size=len(points))
# (2) 根据上一步产生的游戏结果计算相应的得分。
for i in range(len(points)):
if outcomes[i]==3:
points[i]=points[i-1]+1
elif outcomes[i]==2:
points[i]=points[i-1]-6
else:
print outcomes[i]
(3)
# (3)使用Matplotlib绘制points数组。
plot(np.arange(len(points)),points)
show()
4、连续分布和离散分布
4.1 连续分布
import numpy as np
import matplotlib.pyplot as plt
import math
# (1) 使用NumPy random模块中的normal函数产生指定数量的随机数。
N = 10000
normal_values = np.random.normal(size=N)
# (2) 绘制分布直方图和理论上的概率密度函数(均值为0、方差为1的正态分布)曲线。我们将使用Matplotlib进行绘图。
n, bins, patches = plt.hist(normal_values, int(np.sqrt(N)), normed=1, facecolor='blue', alpha=0.5)
sigma = 1
mu = 0
plt.plot(bins, 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(- (bins - mu) ** 2 / (2 * sigma ** 2)), lw=2)
plt.show()
4.2 对数正态分布
# (1) 使用NumPy random模块中的normal函数产生随机数。
N = 10000
lognormal_values = np.random.lognormal(size=N)
# (2) 绘制分布直方图和理论上的概率密度函数(均值为0、方差为1)。我们将使用Matplotlib进行绘图。
dummy, bins, dummys = plt.hist(lognormal_values, int(np.sqrt(N)), normed=True, lw=1)
sigma = 1
mu = 0
x = np.linspace(min(bins), max(bins), len(bins))
pdf = np.exp(-(np.log(x) - mu) ** 2 / (2 * sigma ** 2)) / (x * sigma * np.sqrt(2 * np.pi))
plt.plot(x, pdf, lw=3)
plt.show()
随机掩码
#coding=utf-8
#数据常常s是凌乱的,常常有空白项或者无法处理的字符,掩码式数组可以忽略残缺或者无效的数据点
import numpy
import scipy.misc
import matplotlib.pyplot as plt
lena = scipy.misc.ascent()
#生成一个随机的掩码
random_mask = numpy.random.randint(0, 2, size=lena.shape)
plt.subplot(221)
plt.title("Original")
plt.imshow(lena)
plt.axis('off')
#创建一个掩码数组numpy.ma.array(lena, mask=random_mask)
masked_array = numpy.ma.array(lena, mask=random_mask) #
plt.imshow(masked_array)
plt.imshow(numpy.log(lena))
plt.imshow(numpy.log(masked_array))
plt.show()
忽略负值和极值
#忽略负值和极值
salary = np.loadtxt("MLB2008.csv", delimiter=',', usecols=(1,), skiprows=1, unpack=True)
triples = np.arange(0, len(salary), 3) #(0-len(salaryg隔3个取一次triples[:10]
#对负数取对数
signs = np.ones(len(salary))
signs[triples] = -1#隔3个取一次-1
ma_log = np.ma.log(salary * signs)# ma_log[:10]
#忽略极值
dev = salary.std()
avg = salary.mean()
inside = np.ma.masked_outside(salary, avg - dev, avg + dev)#inside[:10]
plt.subplot(311)
plt.title("Original") | plt.plot(np.exp(ma_log)) ("Log Masked")|plt.title("Not Extreme")plt.plot(inside)
normality_test.py
from scipy.stats import shapiro
from scipy.stats import anderson
from scipy.stats import normaltest
#清洗数据,用转换器填充空单元格为0,假定正确数值为0
flutrends = np.loadtxt("goog_flutrends.csv", delimiter=',', usecols=(1,), skiprows=1, converters = { 1: lambda s: float(s or 0)}, unpack=True)
N = len(flutrends)
normal_values = np.random.normal(size=N)
zero_values = np.zeros(N)
#scipy函数返回2一个元组,第一个元素是一个检验统计量,第二个数值是p值
print "Normal Values Shapiro,Zeroes Shapiro,Flu Shapiro", shapiro(normal_values) | shapiro(zero_values)| shapiro(flutrends)
print "Normal Values Anderson", anderson(normal_values) |anderson(zero_values)|anderson(flutrends)
print "Normal Values normaltest", normaltest(normal_values)|normaltest(zero_values)| normaltest(flutrends)
第四章:pandas
4.6利用pandas的dataframe实现数据聚合,统计计算
import pandas as pd
from numpy.random import seed
from numpy.random import rand
from numpy.random import random_integers
import numpy as np
seed(42)
df = pd.DataFrame({ 'Weather' : ['cold', 'hot', 'cold', 'hot',
'cold', 'hot', 'cold'],
'Food' : ['soup', 'soup', 'icecream', 'chocolate',
'icecream', 'icecream', 'soup'],
'Price' : 10 * rand(7), 'Number' : random_integers(1, 9, size=(7,))})
#columns告诉我们要对那些进行聚合运算
print pd.pivot_table(df, columns=['Food'], aggfunc=np.sum)
weather_group = df.groupby('Weather')
i = 0
for name, group in weather_group:
i = i + 1
print "Group", i, name
print group
print "Weather group first\n", weather_group.first()
print "Weather group last\n", weather_group.last()
print "Weather group mean\n", weather_group.mean()
wf_group = df.groupby(['Weather', 'Food'])
print "WF Groups", wf_group.groups
print "WF Aggregated\n", wf_group.agg([np.mean, np.median])
4.10处理日期数据
import pandas as pd
from pandas.tseries.offsets import DateOffset
import sys
print "Date range", pd.date_range('1/1/1900', periods=42, freq='D') #D:日历日频率
try:
print "date range" ,pd.date_range('1/1/1677',periods=4,freq='D')
except:
etype,value,_=sys.exc_info()
print "Error encountered", etype, value
offset = DateOffset(seconds=2 ** 63/10 ** 9)
mid = pd.to_datetime('1/1/1970')
print "Start valid range", mid - offset
print "End valid range", mid + offset
print pd.to_datetime(['1900/1/1', '1901.12.11'])
print "With format", pd.to_datetime(['19021112', '19031230'], format='%Y%m%d')
#不合法的
print "Illegal date", pd.to_datetime(['1902-11-12', 'not a date'])
print "Illegal date coerced", pd.to_datetime(['1902-11-12', 'not a date'], errors='coerce')
4.4利用Pandas查询数据
from pandas.io.parsers import read_csv
df = read_csv("WHO_first9cols.csv")
print "Dataframe", df #形状数据
print "Shape", df.shape
print "Length", len(df)
print "Column Headers", df.columns #标题
print "Data types", df.dtypes
print "Index", df.index
print "Values", df.values
df = pd.DataFrame({"SUNACTIVITY": df['SUNACTIVITY'].values}, index=df['YEAR'])#重新组合矩阵
4.9处理缺失数据问题
#coding=utf-8
import pandas as pd
import numpy as np
df = pd.read_csv('WHO_first9cols.csv')
# Select first 3 rows of country and Net primary school enrolment ratio male (%)
df = df[['Country', df.columns[-2]]][:2] #[:2]第几个 'Country', df.columns[-2]哪几列
print "New df\n", df
print "Null Values\n", pd.isnull(df)
print "Total Null Values\n", pd.isnull(df).sum()
print "Not Null Values\n", df.notnull()
print "Last Column Doubled\n", 2 * df[df.columns[-1]]
print "Last Column plus NaN\n", df[df.columns[-1]] + np.nan
print "Zero filled\n", df.fillna(0) #填充
4.7dataframe的串联与附加操作
import pandas as pd
from numpy.random import seed
from numpy.random import rand
from numpy.random import random_integers
import numpy as np
seed(42)
df = pd.DataFrame({ 'Weather' : ['cold', 'hot', 'cold', 'hot',
'cold', 'hot', 'cold'],
'Food' : ['soup', 'soup', 'icecream', 'chocolate',
'icecream', 'icecream', 'soup'],
'Price' : 10 * rand(7), 'Number' : random_integers(1, 9, size=(7,))})
print "df :3\n", df[:3]
print "Concat Back together\n", pd.concat([df[:3], df[5:]])
print "Appending rows\n", df[:3].append(df[5:])
dests = pd.read_csv('dest.csv')
tips = pd.read_csv('tips.csv')
print "Merge() on key\n", pd.merge(dests, tips, on='EmpNr')
print "Dests join() tips\n", dests.join(tips, lsuffix='Dest', rsuffix='Tips')#左右
print "Inner join with merge()\n", pd.merge(dests, tips, how='inner')
print "Outer join\n", pd.merge(dests, tips, how='outer')#以左为参考
4.12pandas数据结构之sereis
#coding=utf-8 得到的是一个series型的数据
from pandas.io.parsers import read_csv
import numpy as np
#选中dataframe的一列,得到的是一个series型的数据
df = read_csv("WHO_first9cols.csv")
country_col = df["Country"]
print "Type df", type(df) #Type df
print "Type country col", type(country_col)
print "Series shape", country_col.shape
print "Series index", country_col.index #RangeIndex(start=0, stop=202, step=1)
print "Series values", country_col.values
print "Series name", country_col.name #Country
print "Last 2 countries", country_col[-2:]
print "Last 2 countries type", type(country_col[-2:])
print "df signs", np.sign(df)
last_col = df.columns[-1]
print "Last df column signs", last_col, np.sign(df[last_col])
print np.sum(df[last_col] - df[last_col].values)
4.8远程数据处理quandl
远程数据访问,处理
import quandl #数据获取的库,数据集
# Data from http://www.quandl.com/SIDC/SUNSPOTS_A-Sunspot-Numbers-Annual
# PyPi url https://pypi.python.org/pypi/Quandl
sunspots = quandl.get("SIDC/SUNSPOTS_A")
import quandl
print "Describe", sunspots.describe()
print "Non NaN observations", sunspots.count()
print "MAD", sunspots.mad()
print "Median", sunspots.median()
print "Min", sunspots.min()
print "Max", sunspots.max()
print "Mode", sunspots.mode()
print "Standard Deviation", sunspots.std()
print "Variance", sunspots.var()
print "Skewness", sunspots.skew()
print "Kurtosis", sunspots.kurt()
print "Head 2", sunspots.head(2)
print "Tail 2", sunspots.tail(2)
last_date = sunspots.index[-1]
print "Last value", sunspots.loc[last_date]
print "Values slice by date", sunspots["20020101": "20131231"]
print "Slice from a list of indices", sunspots.iloc[[2, 4, -4, -2]]
print "Scalar with Iloc", sunspots.iloc[0, 0]
print "Scalar with iat", sunspots.iat[1, 0]
print "Boolean selection", sunspots[sunspots > sunspots.mean()]
print "Boolean selection with column label", sunspots[sunspots.Number > sunspots.Number.mean()]
第五章:数据的存储加工与探索:pandas,numpy,html
问题:出现 PermissionError: [Errno 13] Permission denied: 'C:\\Users\\jason\\Documents\\t2'
1利用Numpy和pandas对CSV文件进行写操作
1. 利用Numpy和pandas对CSV文件进行写操作
import numpy as np
import pandas as pd
#对CSV文件进行写操作,numpy的savetxt()函数是与loadtxt()相对应的一个函数,
# 他能以诸如CSV之类的区隔型文件格式保存数组:
np.savetxt('np.csv',a,fmt='%.2f',delimiter=',',header="#1,#2,#3,#4")
#利用随机数组来创建pandas DataFrame,如下:
df=pd.DataFrame(a)
df.to_csv('pd.csv',float_format='%.2f',na_rep="NAN!")
2.Numpy.npy与pandas DataFrame
'''2.Numpy.npy与pandas DataFrame
#就是它的存储效率不是很高,原因是CSV及其他纯文本格式中含有大量空白符'''
import numpy as np
import pandas as pd
from tempfile import NamedTemporaryFile
from os.path import getsize
np.random.seed(42)
a = np.random.randn(365, 4) #生成一个365×4d的Numpy数组
#临时文件,并检查大小
tmpf = NamedTemporaryFile() #使用Python标准的NamedTemporaryFile来存储数据,这些临时文件随后会自动删除。
np.savetxt(tmpf, a, delimiter=',')
print "Size CSV file", getsize(tmpf.name)
#用NUMPY。npy格式保存数组,只有csv的1/3,csv有大量空白符
tmpf = NamedTemporaryFile()
np.save(tmpf, a)
tmpf.seek(0)#为了模拟该临时文件的关闭与重新打开过程
loaded = np.load(tmpf)
print "Shape", loaded.shape
print "Size .npy file", getsize(tmpf.name)
#写入一个pickle对象,以序列化格式来存储pandas的DataFrame或者Series数据结构
pickle是将Python对象存储到磁盘或其他介质时采用的一种格式,这个格式化的过程叫做序列化(pickling).之后,我们可以从存储器中重建该Python对象,这个逆过程称为反序列化(unpickling).
首先用前面生成的Numpy数组创建一个DataFrame,接着用to_pickle()方法将其写入一个pickle对象中,然后用read_pickle()函数从这个pickle对象中检索该DataFrame:尺寸略大于.npy文件。
df=pd.DataFrame(a)
df.to_pickle(tmpf.name+'.csv')
print "Size pickled dataframe", getsize(tmpf.name+'.csv')
print "DF from pickle\n", pd.read_pickle(tmpf.name+'.csv')
3使用PyTables存储数据
3.使用PyTables存储数据
'''层次数据格式(HDF)是一种存储大型数值数据的技术规范,起源于超级计算社区,
目前已经成为一种开放的标准。这里用HDF5,该版本仅仅通过组(group)和数据集(dataset)这两种基本结构来组织数据。
数据集可以是同类型的多维数组,而组可以用来存放其他组或者数据集。这里的“组”跟层次式文件系统中的“目录”非常像。
HDF5最常见的两个主要Python程序库是:
1.h5y
2.PyTables
本例中使用的是PyTables。不过,这个程序库需要用到一些依赖项,比如:
1.Numpy
2.numexpr:该程序包在计算包含多种运算的数组表达式时,其速度要比Numpy快许多倍
3.HDF5:如果使用HDF5的并行版本,则还需要安装MPI.'''
import tables
# 下面创建一个HDF5文件,并把这个Numpy数组挂载到根结点上
tmpf = NamedTemporaryFile()
h5file = tables.openFile(tmpf.name, mode='w', title="NumPy Array")
root = h5file.root
h5file.createArray(root, "array", a)
h5file.close()
# 读取这个HDF5,并显示文件大小
h5file = tables.openFile(tmpf.name, "r")
print getsize(tmpf.name)
# 复制代码通过遍历取为里面的数据
for node in h5file.iterNodes(h5file.root):
b = node.read()
print type(b), b.shape
h5file.close()
4Pandas 与HDF5仓库之间的读写操作
4. Pandas DataFrame与HDF5仓库之间的读写操作
import numpy as np
import pandas as pd
from tempfile import NamedTemporaryFile
np.random.seed(42)
a = np.random.randn(365, 4)
tmpf = NamedTemporaryFile()
#'DFStore类可以看作是pandas中负责HDF5数据处理部分的一种抽象将临时文件地路径传递给HDFStore的构造函数,然后创建一个仓库:'''
store=pd.io.pytables.HDFStore(tmpf.name)
print(store)
df = pd.DataFrame(a)
store['df']=df#查询
print(store)
#我们可以用三种方式来访问DataFrame,分别是:
print("Get",store.get('df').shape)#使用get()方法访问数据
print("Lookup",store['df'].shape)#利用类似字典的查询键访问数据,
print("Dotted",store.df.shape)#或者使用点运算符号来访问数据:
del store['df'] #删除仓库中的数据用remove()方法,也可以使用del运算符
print("Before close",store.is_open)#is_open的作用是指出仓库是否处于打开状态
store.close() #关闭一个仓库
print("After close",store.is_open)
#为读写HDF数据,pandas还提供了两种方法:
df.to_hdf(tmpf.name,'data',format='table')#一种是DataFrame的to_hdf()方法;
print(pd.read_hdf(tmpf.name,'data',where=['index>363']))#另一种是顶级的read_hdf()函数。
#用于读写操作的应用程序接口的参数包括:
# 文件路径、仓库中组的标识符以及可选的格式串。这里的格式有两种:一种是固定格式;一种是表格格式。
# 固定格式的优点是速度要更快一些,缺点是无法追加数据,也不能进行搜索。表格格式相当于PyTables的Table结构,可以对数据进行搜索和选择操作
5使用pandas读写Excel文件
5.使用pandas读写Excel文件
'''模块openpyxl源于PHPExcel,它提供了针对.xlsx文件的读写功能。
模块xlsxwriter也需要读取.xlsx文件
模块xlrd能用来析取.xls和.xlsx文件中的数据。下面,我们先来生成用于填充pandas中DataFrame的随机数,
然后用这个DataFrame创建一个Excel文件,接着再用Excel文件重建DataFrame,并通过mean()方法来计算其平均值。
对于Excel文件的工作表,我们既可以为其指定一个从0开始计数的索引,也可以为其规定一个名称'''
tmpf=NamedTemporaryFile(suffix='.xlsx')
df=pd.DataFrame(a)
print(tmpf.name)
df.to_excel(tmpf.name,sheet_name='Random Data')
print("Means\n",pd.read_excel(tmpf.name,'Random Data').mean())
6使用pandas读写JSON
6. 使用pandas读写JSON
import pandas as pd
json_str='{"country":"Netherlands","dma_code":"0","timezone":"Europe\/Amsterdam","area_code":"0","ip":"46.19.37.108","asn":"AS196752","continent_code":"EU","isp":"Tilaa V.O.F.","longitude":5.75,"latitude":52.5,"country_code":"NL","country_code3":"NLD"}'
1pd.read_json
data=pd.read_json(json_str,typ='series')
print("Series\n",data)
data["country"]="Brazil"
print("New Series\n",data.to_json())
2普通读取json
data = json.loads(json_str)
print "Country", data["country"]
data["country"] = "Brazil"
print json.dumps(data)
7rss
feedparser模块,轻松地实现从任何 RSS 或 Atom 订阅源得到标题、链接和文章的条目了
import feedparser as fp
rss = fp.parse("http://www.packtpub.com/rss.xml") # 解析得到的是一个字典
one_page_dict = fp.parse("http://www.packtpub.com/rss.xml") # 解析得到的是一个字典
print one_page_dict.keys()
print "# Entries", len(rss.entries)
for i, entry in enumerate(rss.entries):
if "article" in entry.summary:
print i, entry.title
print entry.summary
8网页解析bs
from bs4 import BeautifulSoup
import re
soup = BeautifulSoup(open('loremIpsum.html'))
print "First div\n", soup.div
print "First div class", soup.div['class']
print "First dfn text:", soup.dl.dt.dfn.text
for link in soup.find_all('a'):
print "Link text:", link.string, "URL", link.get('href')
# Omitting find_all
for i, div in enumerate(soup('div')):
print i, div.contents
#Div with id=official
official_div = soup.find_all("div", id="official")
print "Official Version:", official_div[0].contents[2].strip()
print "# elements with class:", len(soup.find_all(class_=True))
tile_class = soup.find_all("div", class_="tile")
print "# Tile classes:", len(tile_class)
print "# Divs with class containing tile:", len(soup.find_all("div", class_=re.compile("tile")))
print "Using CSS selector\n", soup.select('div.notile')
print "Selecting ordered list list items\n", soup.select("ol > li")[:2]
print "Second list item in ordered list:", soup.select("ol > li:nth-of-type(2)")
print "Searching for text string", soup.find_all(text=re.compile("2014"))
第六章:数据可视化
1、matplotlib绘图入门
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 20) # linspace()函数指定横坐标范围
plt.plot(x, .5 + x)
plt.plot(x, 1 + 2 * x, '--')
plt.show()
通过show函数将图形显示在屏幕上,也可以用savefig()函数把图形保存到文件中。
2对数图
2对数图
'''对数图又分为两种不同的类型,其中一种称为双对数图,它的特点是两个坐标轴都采用对数刻度,对应的matplotlibh函数是matplotlib.pyplot..loglog()。半对数图的一个坐标轴采用线性刻度,另一个坐标轴使用对数刻度,它对应的matplotlib API是semilogx()函数和semilogy()函数,在双对数图上,幂律表现为直线;在半对数图上,直线则代表的是指数律。'''
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
df=pd.read_csv('transcount.csv')
df=df.groupby('year').aggregate(np.mean) #按年份分组,以数量均值聚合
#print grouped.mean()
years=df.index.values #得到所有年份信息
counts=df['trans_count'].values
#print counts
poly=np.polyfit(years,np.log(counts),deg=1) #线性拟合数据
print "poly:",poly
plt.semilogy(years,counts,'o')
plt.semilogy(years,np.exp(np.polyval(poly,years))) #polyval用于对多项式进行评估
plt.show()
#实线表示的是趋势线,实心圆表示的是数据点。
3、散点图
df=pd.read_csv('H:\Python\data\\transcount.csv')
df=df.groupby('year').aggregate(np.mean)
gpu=pd.read_csv('H:\Python\data\\gpu_transcount.csv')
gpu=gpu.groupby('year').aggregate(np.mean)
df=pd.merge(df,gpu,how='outer',left_index=True,right_index=True)
df=df.replace(np.nan,0)
print df
years=df.index.values
counts=df['trans_count'].values
gpu_counts=df['gpu_counts'].values
cnt_log=np.log(counts)
plt.scatter(years,cnt_log,c=200*years,s=20+200*gpu_counts/gpu_counts.max(),alpha=0.5) #表示颜色,s表示标量或数组
plt.show()
4、图例和注解
'''
用来描述图中各数据序列的图例,matplotlib提供的legend()函数可以为每个数据序列提供相应的标签。
对图中要点的注解。可以借助matplotlib提供的annotate()函数。
横轴和纵轴的标签,可以通过xlabel()和ylabel()绘制出来。
一个说明性质的标题,通常由matplotlib的title函数来提供.
网格,对于轻松定位数据点非常有帮助。grid()函数可以用来决定是否使用网格。'''
years = df.index.values
counts = df['trans_count'].values
gpu_counts = df['gpu_counts'].values
# print df
poly = np.polyfit(years, np.log(counts), deg=1)
plt.plot(years, np.polyval(poly, years), label='Fit')
gpu_start = gpu.index.values.min()
y_ann = np.log(df.at[gpu_start, 'trans_count'])
ann_str = "First GPU\n %d" % gpu_start
plt.annotate(ann_str, xy=(gpu_start, y_ann), arrowprops=dict(arrowstyle="->"), xytext=(-30, +70),
textcoords='offset points')
cnt_log = np.log(counts)
plt.scatter(years, cnt_log, c=200 * years, s=20 + 200 * gpu_counts / gpu_counts.max(), alpha=0.5,
label="Scatter") # 表示颜色,s表示标量或数组
plt.legend(loc="upper left")
plt.grid()
plt.xlabel("Year")
plt.ylabel("Log Transistor Counts", fontsize=16)
plt.title("Moore's Law & Transistor Counts")
plt.show()
5三维图
from mpl_toolkits.mplot3d.axes3d import Axes3D
fig=plt.figure()
ax=Axes3D(fig)
X=df.index.values
Y=np.log(df['trans_count'].values)
X,Y=np.meshgrid(X,Y)
Z=np.log(df['gpu_counts'].values)
ax.plot_surface(X,Y,Z)
ax.set_xlabel('Year')
ax.set_ylabel('Log CPU transistor counts')
ax.set_zlabel('Log GPU transistor counts')
ax.set_title('Moore Law & Transistor counts')
plt.show()
6pandas绘图
pandas的Series类和DataFrame类中的plot()方法都封装了相关的matplotlib函数。如果不带任何参数,使用plot方法绘制图像如
df.plot()
df.plot(logy=True) #创建半对数图
df[df['gpu_counts']>0].plot(kind='scatter',x='trans_count',y='gpu_counts',loglog=True) #loglog=True 生成双对数
plt.show()
7时滞图
'''时滞图实际上就是一个散点图,只不过把时间序列的图像及相同序列在时间轴上后延图像放一起展示而已。例如,我们可以利用这种图考察今年的CPU晶体管数量与上一年度CPU晶体管数量之间的相关性。可以利用pandas字库pandas.tools.plotting中的lag_plot()函数来绘制时滞图,滞默认为1'''
lag_plot(np.log(df['trans_count'])) #时滞图,
8 自相关图?自相关图描述的是时间序列数据在不同时间延迟情况下的自相关性。
自相关图描述的是时间序列数据在不同时间延迟情况下的自相关性。
autocorrelation_plot(np.log(df['trans_count'])) #绘制自相关图
#从图中可以看出,较之于时间上越远(即时间延迟越大)的数值,当前的数值
# 与时间上越接近(及时间延迟越小)的数值相关性越大;当时间延迟极大时,相关性为0;
9、Plot.ly
#Plot.ly实际上是一个网站,它不仅提供了许多数据可视化的在线工具,同时还提供了可在用户机器上使用的对应的python库
#以通过Web接口或以本地导入并分析数据,可以将分析结果公布到Plot.ly网站上。
#先在plotly注册一个账号,然后产生一个api_key。最后可以绘制箱形图。
import plotly.plotly as py
from plotly.graph_objs import *
from getpass import getpass
df=pd.read_csv('H:\Python\data\\transcount.csv')
df=df.groupby('year').aggregate(np.mean)
gpu=pd.read_csv('H:\Python\data\\gpu_transcount.csv')
gpu=gpu.groupby('year').aggregate(np.mean)
df=pd.merge(df,gpu,how='outer',left_index=True,right_index=True)
df=df.replace(np.nan,0)
api_key=getpass()
py.sign_in(username='dengjiaxing',api_key='qPCrc5EA7unk9PlhNwLG')
counts=np.log(df['trans_count'].values)
gpu_counts=np.log(df['gpu_counts'].values)
data=Data([Box(y=counts),Box(y=gpu_counts)])
plot_url=py.plot(data,filename='moore-law-scatter')
print plot_url
第7章:信号处理与时间序列
1移动窗口函数
为了提升数据的准确性,将某个点的取值扩大到包含这个点的一段区间,用区间均值等来进行判断
移动窗口就是窗口向一端滑行,默认是从右往左,每次滑行并不是区间整块的滑行,而是一个单位一个单位的滑行
常用到的移动窗口函数有rolling_mean,rolling_std等
'''
window=3,也就是3个数取一个均值
min_periods:每个窗口最少包含的观测值数量,小于这个值的窗口结果为NA
closed:定义区间的开闭,支持int类型的window。'''
import pandas as pd
import numpy as np
df = pd.DataFrame({ 'key1': ['a', 'a', 'b', 'b', 'a'],
'key2': ['one', 'two', 'one', 'two', 'one'],
'data1': np.nan,
'data2': np.random.randn(5)})
# 1、rolling_count 计算各个窗口中非NA观测值的数量
pd.rolling_count(df[['data1', 'data2']], window=3)
pandas.rolling_sum(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs)
pandas.rolling_mean(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs) # 3、rolling_mean均值
pandas.rolling_median(arg, window, min_periods=None, freq=None, center=False, how='median',
**kwargs) ##4、rolling_median 中位数
pandas.rolling_var(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs) ##5、rolling_var 方差
pandas.rolling_std(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs) # rolling_std 标准差
pandas.rolling_min(arg, window, min_periods=None, freq=None, center=False, how='min', **kwargs) # rolling_min 最小值,最大值
pandas.rolling_corr(arg1, arg2=None, window=None, min_periods=None, freq=None, center=False, pairwise=None,
how=None) # rolling_corr 相关系数
# 等价于: rolling_corr(…, pairwise=True)
pandas.rolling_corr_pairwise(df1, df2=None, window=None, min_periods=None, freq=None,
center=False) # rolling_corr_pairwise 配对数据的相关系数
pandas.rolling_cov(arg1, arg2=None, window=None, min_periods=None, freq=None, center=False, pairwise=None, how=None,
ddof=1) # 协方差
pandas.rolling_skew(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs) # 偏度(三阶矩
pandas.rolling_kurt(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs) # 峰度(四阶矩
pandas.rolling_apply(arg, window, func, min_periods=None, freq=None, center=False, args=(), kwargs={}) # 普通数组函数
pandas.rolling_quantile(arg, window, quantile, min_periods=None, freq=None, center=False) # 分位数
pandas.rolling_window(arg, window=None, win_type=None, min_periods=None, freq=None, center=False, mean=True, axis=0,
how=None, **kwargs) # 移动窗口
ewma
指数加权移动ewma(arg[, com, span, halflife, ...])
ewmstd
指数加权移动标准差
ewmvar
指数加权移动方差
ewmcorr
指数加权移动相关系数
ewmcov
指数加权移动协方差
2移动平均值
import matplotlib.pyplot as plt
import statsmodels.api as sm
from pandas.stats.moments import rolling_mean
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data # 加载数据
year_range = df["YEAR"].values
plt.plot(year_range, df["SUNACTIVITY"].values, label="Original")
plt.plot(year_range, rolling_mean(df, 11)["SUNACTIVITY"].values, label="SMA 11")
plt.plot(year_range, rolling_mean(df, 22)["SUNACTIVITY"].values, label="SMA 22") # rolling_mean函数方便
plt.legend()
plt.show()
# 2.2方法2
import pandas.core.generic
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
df11 = data_loader.data.rolling(window=11, center=False).mean()
df22 = data_loader.data.rolling(window=22, center=False).mean()
year_range = df['YEAR'].values
plt.plot(year_range, df["SUNACTIVITY"].values, label="Original")
plt.plot(year_range, df11["SUNACTIVITY"].values, label="SMA 11")
plt.plot(year_range, df22["SUNACTIVITY"].values, label="SMA 22")
3窗口函数
# 是定义在一个区间(窗口)上的函数,超出定义,函数值取零,可以用来分析频谱,设计滤波器
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data.tail(150) # 从尾部取150行
df = pd.DataFrame({ "SUNACTIVITY": df['SUNACTIVITY'].values}, index=df['YEAR']) # 重新组合矩阵
ax = df.plot()
def plot_window(win_type):
# df2 = rolling_window(df, 22, win_type)
df2 = df.rolling(window=22, win_type=win_type).mean()
df2.columns = [win_type]
# 显示原始数据
df2.plot(ax=ax)
plot_window("boxcar") # 矩形窗口
plot_window("triang") # 三角形窗口
plot_window("blackman") # 布莱克曼窗口
plot_window("hanning") # 汉宁窗
plot_window("bartlett") # 巴特莱特窗
# 显示网格
plt.grid()
plt.show()
4协整的定义
import statsmodels.tsa.stattools as ts
# 用来计算ADF统计量
def calc_adf(x, y):
result = sm.OLS(x, y).fit()
return ts.adfuller(result.resid)
# 太阳黑子数据载入到numpy数组
data_loader = sm.datasets.sunspots.load_pandas()
data = data_loader.data.values
N = len(data)
# 计算正弦值,求出该值与自身的协整关系
t = np.linspace(-2 * np.pi, 2 * np.pi, N)
sine = np.sin(np.sin(t))
print('Self ADF', calc_adf(sine, sine))
# 给正弦波添加噪音
noise = np.random.normal(0, .01, N)
print('ADF sine with noise', calc_adf(sine, sine + noise))
# 生成一个幅值和偏移量更大的余弦波,并混入噪音
cosine = 100 * np.cos(t) + 10
print('ADF sine vs cosine with noise', calc_adf(sine, cosine + noise))
# 正弦与太阳黑子
print('Sine vs sunspots', calc_adf(sine, data))
5自相关
from pandas.tools.plotting import autocorrelation_plot
# 读入测试数据
data_loader = sm.datasets.sunspots.load_pandas()
data = data_loader.data['SUNACTIVITY'].values
# 计算自相关值
y = data - np.mean(data)
norm = np.sum(y ** 2)
correlated = np.correlate(y, y, mode='full') / norm
res = correlated[len(correlated) / 2:]
# 关联度最高值的索引
print(np.argsort(res)[-5:])
# 结果为[ 9 11 10 1 0]
# 绘制图形
plt.plot(res)
plt.grid(True)
plt.xlabel('Lag')
plt.ylabel('Autocorrelation')
plt.show()
# 使用pandas绘制
autocorrelation_plot(data)
plt.show()
6自回归模型:可用于预测时间序列将来的值
from scipy.optimize import leastsq
# 搭建模型代码
def model(p, x1, x10):
p1, p10 = p
return p1 * x1 + p10 * x10
def error(p, data, x1, x10):
return data - model(p, x1, x10)
# 给参数表赋值
def fit(data):
p0 = [.5, 0.5]
params = leastsq(error, p0, args=(data[10:], data[9:-1], data[:-10]))[0]
return params
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
sunspots = data_loader.data['SUNACTIVITY'].values
print(sunspots)
# 训练模型
cutoff = .9 * len(sunspots)
params = fit(sunspots[:cutoff])
print('Params', params)
# 取得各个指标的值
pred = params[0] * sunspots[cutoff - 1:-1] + params[1] * sunspots[cutoff - 10:-10]
actual = sunspots[cutoff:]
print('Root mean square error', np.sqrt(np.mean(actual - pred) ** 2))
print('Mean absolute error ', np.mean(np.abs(actual - pred)))
print('Mean absolute percentage error', 100 * np.mean(np.abs(actual - pred) / actual))
mid = (actual + pred) / 2
print('Symmetric Mean absolute percentage error', 100 * np.mean(np.abs(actual - pred) / mid))
print('Cofficient of determination', 1 - ((actual - pred) ** 2).sum() / ((actual - actual.mean()) ** 2).sum())
year_range = data_loader.data['YEAR'].values[cutoff:]
# 绘制图像
# 太阳黑子活动数值
plt.plot(year_range, actual, 'o', label='Sunspots')
# 预测值
plt.plot(year_range, pred, 'x', label='Prediction')
plt.grid(True)
plt.xlabel('YEAR')
plt.ylabel('SUNACTIVITY')
plt.legend()
plt.show()
7ARMA模型
# 由自回归模型和移动平均模型结合而成,用于时间序列的预测
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
# 拟合数据
years = df['YEAR'].values.astype(int)
str(years[0])
df.index = pd.Index(sm.tsa.datetools.dates_from_range(str(years[0]), str(years[-1])))
del df['YEAR']
# 预测数据
model = sm.tsa.ARMA(df, (10, 1)).fit()
prediction = model.predict('1975', str(years[-1]), dynamic=True)
df['1975':].plot() # 绘制数据,太阳黑子活动数据
# 预测数据
prediction.plot(style='--', label='Prediction')
plt.grid(True)
plt.legend()
plt.show()
8.生成周期信号
from scipy.optimize import leastsq
# 搭建模型
def model(p, t):
C, p1, f1, phi1, p2, f2, phi2, p3, f3, phi3 = p
return C + p1 * np.sin(f1 * t + phi1) + p2 * np.sin(f2 * t + phi2) + p3 * np.sin(f3 * t + phi3)
def error(p, y, t):
return y - model(p, t)
# 给参数表赋值
def fit(y, t):
p0 = [y.mean(), 0, 2 * np.pi / 11, 0, 0, 2 * np.pi / 22, 0, 0, 2 * np.pi / 100, 0]
params = leastsq(error, p0, args=(y, t))[0]
return params
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
sunspots = data_loader.data["SUNACTIVITY"].values
years = data_loader.data["YEAR"].values
# 训练模型
cutoff = .9 * len(sunspots)
params = fit(sunspots[:cutoff], years[:cutoff])
print("Params", params)
# 取得各个指标的值
pred = model(params, years[cutoff:])
actual = sunspots[cutoff:]
print("Root mean square error", np.sqrt(np.mean((actual - pred) ** 2)))
print("Mean absolute error", np.mean(np.abs(actual - pred)))
print("Mean absolute percentage error", 100 * np.mean(np.abs(actual - pred) / actual))
mid = (actual + pred) / 2
print("Symmetric Mean absolute percentage error", 100 * np.mean(np.abs(actual - pred) / mid))
print("Coefficient of determination", 1 - ((actual - pred) ** 2).sum() / ((actual - actual.mean()) ** 2).sum())
year_range = data_loader.data["YEAR"].values[cutoff:]
# 绘制图形
plt.plot(year_range, actual, 'o', label="Sunspots")
plt.plot(year_range, pred, 'x', label="Prediction")
plt.grid(True)
plt.xlabel("YEAR")
plt.ylabel("SUNACTIVITY")
plt.legend()
plt.show()
9傅里叶分析
# FFT (fast fourier transform)快速傅里叶变换
from scipy.fftpack import rfft
from scipy.fftpack import fftshift
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
sunspots = data_loader.data["SUNACTIVITY"].values
# 创建一个正弦波
t = np.linspace(-2 * np.pi, 2 * np.pi, len(sunspots))
mid = np.ptp(sunspots) / 2
sine = mid + mid * np.sin(np.sin(t))
sine_fft = np.abs(fftshift(rfft(sine)))
# 最大振幅的相应索引
print("Index of max sine FFT", np.argsort(sine_fft)[-5:])
# 对太阳黑子进行 fft
transformed = np.abs(fftshift(rfft(sunspots)))
print("Indices of max sunspots FFT", np.argsort(transformed)[-5:])
# 太阳黑子活动数据和sine函数
plt.subplot(311)
plt.plot(sunspots, label="Sunspots")
plt.plot(sine, lw=2, label="Sine")
plt.grid(True)
plt.legend()
# 傅里叶变换后的太阳黑子活动数据
plt.subplot(312)
plt.plot(transformed, label="Transformed Sunspots")
plt.grid(True)
plt.legend()
# 傅里叶变换后的sine函数
plt.subplot(313)
plt.plot(sine_fft, lw=2, label="Transformed Sine")
plt.grid(True)
plt.legend()
plt.show()
10谱分析:功率频谱
from scipy.fftpack import rfft
from scipy.fftpack import fftshift
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
sunspots = data_loader.data["SUNACTIVITY"].values
# 创建一个正弦波
t = np.linspace(-2 * np.pi, 2 * np.pi, len(sunspots))
mid = np.ptp(sunspots) / 2
sine = mid + mid * np.sin(np.sin(t))
# 对正弦波进行FFT
sine_fft = np.abs(fftshift(rfft(sine)))
# 最大振幅的相应索引
print("Index of max sine FFT", np.argsort(sine_fft)[-5:])
# 对太阳黑子进行 fft
transformed = fftshift(rfft(sunspots))
print("Indices of max sunspots FFT", np.argsort(transformed)[-5:])
# 太阳黑子活动数据和sine函数
plt.subplot(311)
plt.plot(sunspots, label="Sunspots")
plt.plot(sine, lw=2, label="Sine")
plt.grid(True)
plt.legend()
# 绘制功率频谱
plt.subplot(312)
plt.plot(transformed ** 2, label="Power Spectrum")
plt.grid(True)
plt.legend()
# 相位谱,正弦函数的起始角
plt.subplot(313)
plt.plot(np.angle(transformed), label="Phase Spectrum")
plt.grid(True)
plt.legend()
plt.show()
11滤波:是一种信号处理技术
可以对信号的某些部分进行删减或抑制,可以对高频或是低频进行滤波
中值滤波\Wiener滤波\Detrend滤波
from scipy.signal import medfilt
from scipy.signal import wiener
from scipy.signal import detrend
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
sunspots = data_loader.data['SUNACTIVITY'].values
years = data_loader.data['YEAR'].values
# 绘制图像
# 原始数据
plt.plot(years, sunspots, label='SUNATCIVITY')
# 中值滤波
plt.plot(years, medfilt(sunspots, 11), lw=2, label='Meadian')
# wiener滤波
plt.plot(years, wiener(sunspots, 11), '--', lw=2, label='Wiener')
# detrend滤波
plt.plot(years, detrend(sunspots), lw=3, label='Detrend')
plt.xlabel('YEAR')
plt.grid(True)
plt.legend()
plt.show()
第8章:应用数据库
1 基于sqlite3的轻量级访问:轻盈的关系型数据库
import sqlite3
# 创建数据库联接
# 有两种方式,但是后面一种只存在在内存中,对于频繁访问的话比较快1#conn=sqlite3.connect('urls.db')
# 2、conn=sqlite3 . connect ( ":memory:" )#使用特定的文件名‘:memory:’来在内存中创建一个数据
with sqlite3.connect(":memory:") as con:
# 取得游标
c = con.cursor()
# 创建数据库表
c.execute('''
CREATE TABLE sensors(
data text,
city text,
code text,
sensor_id real,
temperature real)
''')
# 查询数据库表
for table in c.execute("SELECT name FROM sqlite_master WHERE type='table'"):
print('Table', table)
# 添加记录
c.execute("INSERT INTO sensors VALUES('2016-02-27','uTRECHT','Red',42,15.14)")
# 查询所有记录
c.execute("SELECT * FROM sensors")
print(c.fetchone()) #fetchone
# 删除表
con.execute("DROP TABLE sensors")
# 查询数据库表
print("#of table", c.execute("SELECT COUNT (*) FROM sqlite_master WHERE type='table'").fetchone()[0])
# 关闭联接
con.close()
2 通过pandas访问数据库
import statsmodels.api as sm
from pandas.io.sql import read_sql
import sqlite3
# 创建数据库联接
with sqlite3.connect(":memory:") as con:
# 取得游标
c = con.cursor()
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
# 创建元组列表
rows = [tuple(x) for x in df.values]
# 创建一个未规定数据类型的数据表
con.execute("CREATE TABLE sunspots (year,sunactivity)")
# 添加多条记录
con.executemany("INSERT INTO sunspots(year,sunactivity) VALUES (?,?)", rows)
# 查询总记录数
c.execute("SELECT COUNT(*) FROM sunspots")
print(c.fetchone())
# 删除表中记录,并显示受影响行数
print("Deleted", con.execute("DELETE FROM sunspots where sunactivity >20").rowcount, "row")
# 使用read_sql执行查询并返回dataFrame结果
print(read_sql("SELECT * FROM sunspots where year <1732", con))
# 删除数据表
con.execute("DROP TABLE sunspots")
c.close()
3 SQLAlchemy
3.1不是主程序用于调用
#可以把python中的类映射为数据库中的表,类以于java中的hibernate
from sqlalchemy import Column, ForeignKey, Integer, Float, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
from sqlalchemy import UniqueConstraint
# 超类
Base = declarative_base()
# 观测站表
class Station(Base):
__tablename__ = 'station' # 表名
id = Column(Integer, primary_key=True) # id
name = Column(String(14), nullable=False, unique=True) # 观测站名称
def __repr__(self):
return "Id=%d name=%s" % (self.id, self.name)
# 传感器表
class Sensor(Base):
__tablename__ = 'sensor' # 表名
id = Column(Integer, primary_key=True) # id
last = Column(Integer)
multiplier = Column(Float)
station_id = Column(Integer, ForeignKey('station.id')) # 外键
station = relationship(Station)
def __repr__(self):
return "Id=%d last=%d multiplier=%.1f station_id=%d" % (self.id, self.last, self.multiplier, self.station_id)
if __name__ == "__main__":
print("This script is used by another script. Run python alchemy_query.py")
3.2主程序:Populate_db.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from .alchemy_entities import Base, Sensor, Station
def populate(engine):
# 创建DBSession对象
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
# 创建两个观测站
de_bilt = Station(name='De Bilt')
session.add(de_bilt)
session.add(Station(name='Utrecht'))
session.commit()
print('Station', de_bilt)
# 添加传感器记录
temp_sesor = Sensor(last=20, multiplier=.1, station=de_bilt)
session.add(temp_sesor)
session.commit()
print("Sensor", temp_sesor)
if __name__ == "__main__":
print("This script is used by another script. Run python alchemy_query.py")
3.3Alchemy_query.py
from Eight.alchemy_entities import Base, Station, Sensor
from Eight.populate_db import populate
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import os
from pandas.io.sql import read_sql
# 创建引擎
engine = create_engine('sqlite:///demo.db')
# 删除数据表
Base.metadata.drop_all(engine)
# 创建数据表
Base.metadata.create_all(engine)
populate(engine)
Base.metadata.bind = engine
DBSession = sessionmaker()
DBSession.bind = engine
session = DBSession()
# 查询station表中的第一行记录
station = session.query(Station).first()
# 查询所有station
print('all station', session.query(Station).all())
# 查询所有sensor
print('all sensor', session.query(Sensor).all())
# 查询第一个station的第一个sensor
print('query sensor by station', session.query(Sensor).filter(Sensor.station == station).one())
# 使用pandas的read_sql查询
print('read_sql all station', read_sql("SELECT * FROM station", engine.raw_connection()))
# 删除数据库,没有执行
try:
os.remove('demo.db')
print('Delete demo.db')
except OSError as e:
# [WinError 32] 另一个程序正在使用此文件,进程无法访问。: 'demo.db'
print(e)
pass
4 Pony ORM
from pony.orm import Database, db_session
from pandas.io.sql import to_sql
import statsmodels.api as sm
# 创建sqlite数据库
db = Database('sqlite', ':memory:')
# 加载数据并写入数据库
with db_session:
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
to_sql(df, "sunspots", db.get_connection())
print(db.select("count(*) FROM sunspots"))
5Dataset 懒人数据库:是sqlalchemy的一个包装器
import dataset
from pandas.io.sql import read_sql
from pandas.io.sql import to_sql
import statsmodels.api as sm
# 创建数据库连接
db = dataset.connect('sqlite:///:memory:')
# 创建books表
table = db["books"]
# 添加数据,在调用insert时会自动添加表模式
table.insert(dict(title="Numpy Beginner's guide", author='Ivan Idris'))
table.insert(dict(title="Numpy Cookbook", author='Ivan Idris'))
table.insert(dict(title="Learning Numpy", author='Ivan Idris'))
# 使用pandas的read_sql查询数据
print(read_sql('SELECT * FROM books', db.executable.raw_connection()))
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
to_sql(df, "sunspots", db.executable.raw_connection())
table = db['sunspots']
# 查询前5条数据
for row in table.find(_limit=5):
print(row)
print("Table", db.tables)
6 pymongo与mongodb
'''指定数据存储的目录
Mkdir h: / data / db
Mongod - -dbpath h: / data / db
安装pymongo:pip install pymongo
查看当前驱动版本号:C:\Users\Administrator > python - m pipfreeze | grep pymongo
与mongodb的测试数据库进行联接:'''
from pymongo import MongoClient
import statsmodels.api as sm
import json
import pandas as pd
# 创建数据库连接
client = MongoClient()
db = client.test_database
# 创建json并保存到数据库中
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
rows = json.loads(df.T.to_json()).values()
db.sunspots.insert(rows)
#查询所有内容
cursor = db['sunspots'].find({})
df = pd.DataFrame(list(cursor))
print(df)
db.drop_collection('sunspots')
7 利用redis存储数据
#是一个in-memory型的键值数据库,是c写
import redis
import statsmodels.api as sm
import pandas as pd
# 与redis建立连接
r = redis.StrictRedis()
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
# 通过json字符串创建记录
data = df.T.to_json()
r.set('sunspots', data)
# 检索记录
blob = r.get('sunspots')
print(pd.read_json(blob))
8 Apache Cassandra
#是结合了键值 和传统关系型数据库特性的混合型数据库,是面向列的数据库
'''Cassandra安装
1下载apache-cassandra-3.10-bin.tar.gz
2 修改cassandra.bat,添加JAVA_HOME变量:set JAVA_HOME=C:\Java\jdk1.8.0_71,如果本机内存不够大,可以将虚拟机内存调小.默认为2G: -Xms512m^:-Xmx512m^
3 python已安装略
4 修改cqlsh.bat.,设置python路径:set path =D:\Python35
5 添加环境变量:Path=F:\apache-cassandra-3.10\bin;
6 cmd执行cassandra,启动数据库
学习本章时未找到支持python3.5的驱动,所以使用ptyhon2.7'''
from cassandra import ConsistencyLevel
from cassandra.cluster import Cluster
from cassandra.query import SimpleStatement
import statsmodels.api as sm
# 与集群建立联接,并创建一个会话
cluster = Cluster()
session = cluster.connect()
# keyspace用来存储数据表的容器.
session.execute(
"CREATE KEYSPACE IF NOT EXISTS mykeyspace WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };")
session.set_keyspace('mykeyspace')
# 创建数据表
session.execute("CREATE TABLE IF NOT EXISTS sunspots (year decimal PRIMARY KEY, sunactivity decimal);")
# 添加数据操作
query = SimpleStatement(
"INSERT INTO sunspots (year, sunactivity) VALUES (%s, %s)",
consistency_level=ConsistencyLevel.QUORUM)
# 加载数据
data_loader = sm.datasets.sunspots.load_pandas()
df = data_loader.data
rows = [tuple(x) for x in df.values]
# 添加数据
for row in rows:
session.execute(query, row)
# 输出总记录数
print(session.execute("SELECT COUNT(*) FROM sunspots")._current_rows[0])
session.execute('DROP KEYSPACE mykeyspace')
cluster.shutdown()
第9章:分析文本数据和社交媒体
1下载安装
1.1基础
nltk.download()
from nltk.book import *
text1.concordance("monstrous") ###搜索文本
text1.similar("monstrous") #搜索相似词
text2.common_contexts(["monstrous", "very"]) #搜索共同上下文
text4.dispersion_plot(["citizens", "democracy", "freedom", "duties", "America"])#词汇分布图
text1.generate() #自动生成文章
len(text3) ###计数词汇
sorted(set(text3))
len(set(text3))#有几个不同的词语
#重复词密度
from __future__ import division#有小数的除法
len(text3) / len(set(text3))
#关键词密度
text3.count("smote") #计算一个特定的词次数
100 * text4.count('a') / len(text4)#计算一个特定的词在文本中占据的百分比。
def lexical_diversity(text): #设计函数来计算
return len(text) / len(set(text))
def percentage(count, total):
return 100 * count / total
lexical_diversity(text3)
lexical_diversity(text5)
percentage(4, 5)
percentage(text4.count('a'), len(text4))
1.2频率freqdist
import nltk
import string
#freqdist用来将单词封装成字典,计算给定单词列表中单词出现的次数
gb = nltk.corpus.gutenberg
words = gb.words("shakespeare-caesar.txt")
#去掉标点和停用词
sw = set(nltk.corpus.stopwords.words('english'))
punctuation = set(string.punctuation)
filtered = [w.lower() for w in words if w.lower() not in sw and w.lower() not in punctuation]
#创建FreqDist对象,输出频率最高的键值
fd = nltk.FreqDist(filtered)
print "Words", fd.keys()[:5]
print "Counts", fd.values()[:5]
print "Max", fd.max()
print "Count", fd['d']
#将分析扩展到含有2-3个单词的词汇上
fd = nltk.FreqDist(nltk.bigrams(filtered))
print "Bigrams", fd.keys()[:5]
print "Counts", fd.values()[:5]
print "Bigram Max", fd.max()
print "Bigram count", fd[('let', 'vs')]
fdist1.plot(50, cumulative=True)#最常用词的累积频率图
fdist1.hapaxes()#只出现了一次的词
#细粒度的选择词
V = set(text4)
long_words = [w for w in V if len(w) > 15]
sorted(long_words)
fdist5 = FreqDist(text5)
sorted([w for w in set(text5) if len(w) > 7 and fdist5[w] > 7])
#词语搭配
from nltk.util import bigrams
list(bigrams(['more', 'is', 'said', 'than', 'done']))
text4.collocations()
###其他统计结果
[len(w) for w in text1]
fdist = FreqDist([len(w) for w in text1])
fdist.keys()#有由 1 个字符,2 个字符,...,20 个字符组成的词,而没有由 21 个或更多字符组成的词。
fdist.items()
fdist.max()
fdist[3]
fdist.freq(3)
#fdist = FreqDist(samples) 创建包含给定样本的频率分布
#fdist.inc(sample) 增加样本
#fdist['monstrous'] 计数给定样本出现的次数
#fdist.freq('monstrous') 给定样本的频率
#fdist.N() 样本总数
#fdist.keys() 以频率递减顺序排序的样本链表
#for sample in fdist: 以频率递减的顺序遍历样本
#fdist.max() 数值最大的样本
#fdist.tabulate() 绘制频率分布表
#fdist.plot() 绘制频率分布图
#fdist.plot(cumulative=True) 绘制累积频率分布图
#fdist1 < fdist2 测试样本在 fdist1 中出现的频率是否小于 fdist2
2 滤除停用字
2.1姓名和数字
import nltk
# 加载英语停用字语料
sw = set(nltk.corpus.stopwords.words('english'))#获得英语中的停用词
print('Stop words', list(sw)[:7])# [u'all', u'just', u'being', u'over', u'both', u'through', u'yourselve
# 取得gutenberg语料库中的部分文件
gb = nltk.corpus.gutenberg#Gutenberg语料库。是一个数字图书馆计划,旨在收集大量版权已经过期的图书
print('Gutenberg files', gb.fileids()[-5:])
# 取milton-paradise.txt文件中的前两句,作为下面所用的过滤语句
text_sent = gb.sents("milton-paradise.txt")[:2]
print('Unfiltered', text_sent)
# 过滤停用字
for sent in text_sent:
filtered = [w for w in sent if w.lower() not in sw]#不在停用词中
print('Filtered', filtered)
# 取得文本内所含的标签
tagged = nltk.pos_tag(filtered)
print("Tagged", tagged)
words = []
for word in tagged:
if word[1] != 'NNP' and word[1] != 'CD':
words.append(word[0])
print(words)
# 词性标注集
# print(nltk.tag.tagset_mapping('ru-rnc', 'universal'))
2.2停用词,数据清洗,词干
词干
from nltk.stem.snowball import SnowballStemmer
stemmer = SnowballStemmer("english")
停用词
s
topwords = nltk.corpus
stopwords = nltk.corpus.stopwords.words('english')
数据清洗
synopses_clean_wiki = []
for text in synopses_wiki:
text = BeautifulSoup(text, "html.parser").getText()
# text = BeautifulSoup(text, 'lxml').getText()
# strips html formatting and converts to unicode
synopses_clean_wiki.append(text)
frame
vocab_frame = pd.DataFrame({ 'words': totalvocab_tokenized}, index=totalvocab_stemmed)
Tfidf: tfidf_vectorizer = TfidfVectorizer(max_df=0.8, max_features=200000, min_df=0.2, stop_words='english',
use_idf=True, tokenizer=tokenize_and_stem, ngram_range=(1, 3))
# 在80%文档出现过max_df最高频率,的出现太多没用
# max_df最小,太小没用,在n个以上文档中出现
3 词袋模型//:安装scikit-learn略
import nltk
from sklearn.feature_extraction.text import CountVectorizer
# 从gutenberg语料库中加载以下两个文件
gb = nltk.corpus.gutenberg
hamlet = gb.raw('shakespeare-hamlet.txt')
macbeth = gb.raw("shakespeare-macbeth.txt")
# 去掉英语停用词
cv = CountVectorizer(stop_words='english')
# 输出部分特征值
print("Feature vector", cv.fit_transform([hamlet, macbeth]).toarray())
# 特征值是按字母顺序排序
print('Features', cv.get_feature_names()[:5])
4 词频分析
def printLine(values, num, keyOrValue, tag):#:param keyOrValue: 输出元素的键还是值 0表示键,1表示值
tmpValue = []
for key in sorted(values.items(), key=lambda d: d[1], reverse=True)[:num]:
tmpValue.append(key[keyOrValue])
print(tag, ":", tmpValue)
# 加载文档
gb = nltk.corpus.gutenberg
words = gb.words("shakespeare-caesar.txt")
# 支除停用词和标点符号
sw = set(nltk.corpus.stopwords.words('english'))
punctuation = set(string.punctuation)
filtered = [w.lower() for w in words if w.lower() not in sw and w.lower() not in punctuation]
# 创建freqDist对象,输出频率最高的键和值
fd = nltk.FreqDist(filtered)
printLine(fd, 5, 0, "Wrods")
printLine(fd, 5, 1, "Counts")
# 最常出现的单词和次数
print('Max', fd.max())
print('Count', fd['caesar'])
# 最常出现的双字词和词数
fd = nltk.FreqDist(nltk.bigrams(filtered))
printLine(fd, 5, 0, "Bigrams")
printLine(fd, 5, 1, "Counts")
print('Bigram Max', fd.max())
print('Bigram count', fd[('let', 'vs')])
# 最常出现的三字词和词数
fd = nltk.FreqDist(nltk.trigrams(filtered))
printLine(fd, 5, 0, "Trigrams")
printLine(fd, 5, 1, "Counts")
print('Bigram Max', fd.max())
print('Bigram count', fd[('enter', 'lucius', 'luc')])
5 朴素贝叶斯分类
import nltk
import string
import random
# 停用词和标点符号集合
sw = set(nltk.corpus.stopwords.words('english'))
punctuation = set(string.punctuation)
# 将字长作为一个特征
def word_features(word):
return { 'len': len(word)}
# 是否为停用词或是标点符号
def isStopword(word):
return word in sw or word in punctuation
# 加载文件
gb = nltk.corpus.gutenberg
words = gb.words("shakespeare-caesar.txt")
# 对单词进行标注,区分是否为停用词
labeled_words = ([(word.lower(), isStopword(word.lower())) for word in words])
random.seed(42)
random.shuffle(labeled_words)
print(labeled_words[:5])
featuresets = [(word_features(n), word) for (n, word) in labeled_words]# 求出每个单词的长度,作为特征值
cutoff = int(.9 * len(featuresets))# 训练一个朴素贝叶斯分类器
train_set, test_set = featuresets[:cutoff], featuresets[cutoff:]# 创建训练数据集和测试数据集
# 检查分类器效果
classifier = nltk.NaiveBayesClassifier.train(train_set)
print("'behold' class", classifier.classify(word_features('behold')))
print("'the' class", classifier.classify(word_features('the')))
print("Accuracy", nltk.classify.accuracy(classifier, test_set))# 根据测试数据集来计算分类器的准确性
print(classifier.show_most_informative_features(5))# 贡献度最大的特征
6 情感分析
import random
from nltk.corpus import movie_reviews
from nltk.corpus import stopwords
from nltk import FreqDist
from nltk import NaiveBayesClassifier
from nltk.classify import accuracy
import string
#情感分析,编制情感单词列表,每个单词赋予一个情感分,从而给文本打分
#用categories对影评文档进行标注
# 加载数据
labeled_docs = [(list(movie_reviews.words(fid)), cat)
for cat in movie_reviews.categories()
for fid in movie_reviews.fileids(cat)]
random.seed(42)
random.shuffle(labeled_docs)
review_words = movie_reviews.words()
print("#Review Words", len(review_words))
# 设置停用词和标点符号
sw = set(stopwords.words('english'))
punctuation = set(string.punctuation)
# 检查是否为停用词
def isStopWord(word):
return word in sw or word in punctuation
# 过滤停用词和标点符号
filtered = [w.lower() for w in review_words if not isStopWord(w.lower())]
# print("# After filter", len(filtered))
# 选用词频最高的前5%作为特征
words = FreqDist(filtered)
N = int(.05 * len(words.keys()))
# word_features = words.keys()[:N]
word_features = getElementsByNum(words, N, 0)
print('word_features', word_features)
# 使用原始单词计数来作为度量指标
def doc_features(doc):
doc_words = FreqDist(w for w in doc if not isStopWord(w))
features = {}
for word in word_features:
features['count (%s)' % word] = (doc_words.get(word, 0))
return features
# 使用原始单词计数,来作为特征值
featuresets = [(doc_features(d), c) for (d, c) in labeled_docs]
# 创建训练数据集和测试数据集
train_set, test_set = featuresets[200:], featuresets[:200]
# 检查分类器效果
classifier = NaiveBayesClassifier.train(train_set)
# 根据测试数据集来计算分类器的准确性
print("Accuracy", accuracy(classifier, test_set))
# 贡献度最大的特征
print(classifier.show_most_informative_features())
7 创建词云
review_words = movie_reviews.words()# 取得原始文档
# 选用词频最高的前1%作为特征
words = FreqDist(filtered)
N = int(.01 * len(words.keys()))
tags = getElementsByNum(words, N, 0)
# tags = words.keys()[:N]
for tag in tags:
print(tag, ":", words[tag])
# 将输出结果粘粘到wordle页
7.2进一步的过滤TFIDF
from nltk.corpus import names
from sklearn.feature_extraction.text import TfidfVectorizer
import itertools
# 设置停用词 标点符号和姓名
sw = set(stopwords.words('english'))
punctuation = set(string.punctuation)
all_names = set([name.lower() for name in names.words()])
# 过滤单词(停用词,标点符号,姓名,数字)
def isStopWord(word):
return (word in sw or word in punctuation) or not word.isalpha() or word in all_names
# 取得影评文档
review_words = movie_reviews.words()
# 过滤停用词
filtered = [w.lower() for w in review_words if not isStopWord(w.lower())]
words = FreqDist(filtered)
# 创建TfidfVectorizer所需要的字符串列表(过滤掉停用词和只出现一次的单词 )
texts = []
for fid in movie_reviews.fileids():
texts.append(" ".join([w.lower()
for w in movie_reviews.words(fid)
if not isStopWord(w.lower()) and words[w.lower()] > 1]))
# 创建向量化程序
vectorizer = TfidfVectorizer(stop_words='english')
matrix = vectorizer.fit_transform(texts)
# 求单词的TF-IDF的和
sums = np.array(matrix.sum(axis=0)).ravel()
# 通过单词的排名权值
ranks = []
# 不可用
# for word, val in itertools.izip(vectorizer.get_feature_names(), sums):
for word, val in zip(vectorizer.get_feature_names(), sums):
ranks.append((word, val))
# 创建DataFrame
df = pd.DataFrame(ranks, columns=['term', 'tfidf'])
# 并排序
# df = df.sort(columns='tfidf')
df = df.sort_values(by='tfidf')
# 输出排名字低的值
print(df.head())
N = int(.01 * len(df))
df = df.tail(N)
# 不可用
# for term, tfidf in itertools.izip(df['term'].values, df['tfidf'].values):
for term, tfidf in zip(df['term'].values, df['tfidf'].values):
print(term, ":", tfidf)
8 社交网络分析networkx
#安装networdX 略利用网络理论来研究社会关系
import matplotlib.pyplot as plt
import networkx as nx
# NetwordX所的供的示例图
print([s for s in dir(nx) if s.endswith("graph")])
G = nx.davis_southern_women_graph()
plt.figure(1)
plt.hist(list(nx.degree(G).values()))
plt.figure(2)
pos = nx.spring_layout(G)
nx.draw(G, node_size=9)
nx.draw_networkx_labels(G, pos)
plt.show()
第10章:预测性分析与机器学习
2 预处理
import numpy as np
from sklearn import preprocessing
from scipy.stats import anderson
# 加载数据
rain = np.load('rain.npy')
rain = .1 * rain
rain[rain < 0] = .05 / 2
# 期望值 标准差和安德森
print("Rain mean", rain.mean())
print("Rain Variance", rain.var())
print("Anderson Rain", anderson(rain))
scaled = preprocessing.scale(rain)
print("Scaled mean", scaled.mean())
print("Scaled Variance", scaled.var())
print("Anderson Scaled", anderson(scaled))
# 把特征值从数值型转换布尔型
binarized = preprocessing.binarize(rain)
print("binarized", np.unique(binarized), binarized.sum())
# 分类标准类别,输出0-62之间的整数
lb = preprocessing.LabelBinarizer()
lb.fit(rain.astype(int))
print(lb.classes_)
3 基于逻辑回归的分类
from sklearn.linear_model import LogisticRegression
from sklearn.cross_validation import KFold
from sklearn import datasets
import numpy as np
def classify(x, y):
# 使用逻辑回归进行分类
clf = LogisticRegression(random_state=12)
scores = []
# k-折交叉验证
kf = KFold(len(y), n_folds=10)
# 检查分类的状确性
for train, test in kf:
clf.fit(x[train], y[train])
scores.append(clf.score(x[test], y[test]))
print(np.mean(scores))
# 加载数据信息
rain = np.load('rain.npy')
dates = np.load('doy.npy')
# 使用日期和降雨量来构建数组
x = np.vstack((dates[:-1], rain[:-1]))
# 无雨,小雨,雨
y = np.sign(rain[1:])
classify(x.T, y)
iris = datasets.load_iris()
x = iris.data[:, :2]
y = iris.target
classify(x, y)
4 基于支持向量机的分类svm
'''支持向量机 Support vector machines SVM
支持向量回归 Support vector Regression SVR
用于回归或者分类'''
from sklearn.svm import SVC
from sklearn.grid_search import GridSearchCV
from sklearn import datasets
import numpy as np
from pprint import PrettyPrinter
def classify(x, y):
# 进行网格搜索
clf = GridSearchCV(SVC(random_state=42, max_iter=100), { 'kernel': ['linear', 'poly', 'rbf'], 'C': [1, 10]})
clf.fit(x, y)
print("Score", clf.score(x, y))
PrettyPrinter().pprint(clf.grid_scores_)
rain = np.load('rain.npy')
dates = np.load('doy.npy')
x = np.vstack((dates[:-1], rain[:-1]))
y = np.sign(rain[1:])
classify(x.T, y)
iris = datasets.load_iris()
x = iris.data[:, :2]
y = iris.target
classify(x, y)
5 基于elasticNetCV的回归分类
'''弹性网格正则化 Elasic net Regularization 降低回归分析的过拟合风险
实际上是LASSO(The Least Absolute Shrikage and Selection Operator)算法和岭回归方法的线性组合'''
from sklearn.linear_model import ElasticNetCV
import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt
def regress(x, y, title):
clf = ElasticNetCV(max_iter=200, # 最大迭代次数
cv=10, # 包总量
l1_ratio=[.1, .5, .7, .9, .95, .99, 1] # 0表示只使用岭回归,1表示只使用 LASSO回归,否则使用混合算法
)
clf.fit(x, y)
print("Score", clf.score(x, y))
pred = clf.predict(x)
plt.title("Scatter plot of prediction and " + title)
plt.xlabel("Prediction")
plt.ylabel("Target")
plt.scatter(y, pred)
if "Boston" in title:
plt.plot(y, y, label="Perfect Fit")
plt.legend()
plt.grid = True
plt.show()
rain = .1 * np.load('rain.npy')
rain[rain < 0] = .05 / 2
dates = np.load("doy.npy")
x = np.vstack((dates[:-1], rain[:-1]))
y = rain[1:]
regress(x.T, y, "rain data")
boston = datasets.load_boston()
x = boston.data
y = boston.target
regress(x, y, "Boston house prices")
6 支持向量回归
import numpy as np
from sklearn import datasets
from sklearn.model_selection import learning_curve
from sklearn.svm import SVR
from sklearn import preprocessing
import multiprocessing
import matplotlib.pyplot as plt
# 错误信息
# D:\Python35\lib\site-packages\sklearn\svm\base.py:220: ConvergenceWarning: Solver terminated early (max_iter=800). Consider pre-processing your data with StandardScaler or MinMaxScaler.
# % self.max_iter, ConvergenceWarning)
def regress(x, y, ncpus, title):
X = preprocessing.scale(x)
Y = preprocessing.scale(y)
clf = SVR(max_iter=ncpus * 200)
# 根据cpu数量创建作业数
train_sizes, train_scores, test_scores = learning_curve(clf, X, Y, n_jobs=ncpus)
# 求平均数,然后画出得分
plt.figure()
plt.title(title)
plt.plot(train_sizes, train_scores.mean(axis=1), label="Train score")
plt.plot(train_sizes, test_scores.mean(axis=1), '--', label="Test score")
print("Max test score " + title, test_scores.max())
plt.grid(True)
plt.legend(loc='best')
plt.show()
def main():
rain = .1 * np.load('rain.npy')
rain[rain < 0] = .05 / 2
dates = np.load('doy.npy')
x = np.vstack((dates[:-1], rain[:-1]))
y = rain[1:]
ncpus = multiprocessing.cpu_count()
regress(x.T, y, ncpus, "Rain")
boston = datasets.load_boston()
x = boston.data
y = boston.target
regress(x, y, ncpus, "Boston")
if __name__ == '__main__':
main()
7 基于相似性传播算法的聚类分析
# 生成三个数据块
x, _ = datasets.make_blobs(n_samples=100, centers=3, n_features=2, random_state=10)
# 创建矩阵
S = euclidean_distances(x)
# print(S)
# 根据矩阵,给数据标注其所属聚类
aff_pro = cluster.AffinityPropagation().fit(S)
labels = aff_pro.labels_
# 绘制图形
styles = ['o', 'x', '^']
for style, label in zip(styles, np.unique(labels)):
print(label)
plt.plot(x[labels == label], style, label=label)
plt.title("Clustering Blobs")
plt.grid(True)
plt.legend(loc='best')
plt.show()
8 均值漂移算法
#一种不需要估算聚类数的聚类算法(可以应用于图像处理,是不是等同于中值滤波)
import numpy as np
from sklearn import cluster
import matplotlib.pyplot as plt
import pandas as pd
# 加载数据
rain = .1 * np.load('rain.npy')
rain[rain < 0] = .05 / 2
dates = np.load('doy.npy')
x = np.vstack((dates, rain))
# 创建dataFrame,并计算平均值
df = pd.DataFrame.from_records(x.T, columns=['dates', 'rain'])
df = df.groupby('dates').mean()
df.plot()
# 均值漂移算法
x = np.vstack((np.arange(1, len(df) + 1), df.as_matrix().ravel()))
x = x.T
ms = cluster.MeanShift()
ms.fit(x)
labels = ms.predict(x)
# 绘制图形
plt.figure()
grays = ['0', '0.5', '0.75']
for gray, label in zip(grays, np.unique(labels)):
match = labels == label
x0 = x[:, 0]
x1 = x[:, 1]
plt.plot(x0[match], x1[match], lw=label + 1, label=label)
plt.fill_between(x0, x1, where=match, color=gray)
plt.grid(True)
plt.legend()
plt.show()
9 遗传算法,#可用于搜索和优化方面?
import array
import random
import numpy as np
from deap import algorithms
from deap import base
from deap import creator
from deap import tools
from scipy.stats import shapiro
import matplotlib.pyplot as plt
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", array.array, typecode='d', fitness=creator.FitnessMax)
toolbox = base.Toolbox()
toolbox.register("attr_float", random.random)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, 200)
toolbox.register("populate", tools.initRepeat, list, toolbox.individual)
def eval(individual):
return shapiro(individual)[1],
toolbox.register("evaluate", eval)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.1)
toolbox.register("select", tools.selTournament, tournsize=4)
random.seed(42)
pop = toolbox.populate(n=400)
hof = tools.HallOfFame(1)
stats = tools.Statistics(key=lambda ind: ind.fitness.values)
stats.register("max", np.max)
algorithms.eaSimple(pop, toolbox, cxpb=0.5, mutpb=0.2, ngen=80, stats=stats, halloffame=hof)
print shapiro(hof[0])[1]
plt.hist(hof[0])
plt.grid(True)
plt.show()
10 神经网络
# 所属模块发生变化
# from sklearn.cross_validation import train_test_split
# from sklearn.grid_search import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from sklearn import tree
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint as sp_randint
import pydot
# import StringIO
from io import StringIO
import numpy as np
from tempfile import NamedTemporaryFile
# 加载数据信息
rain = .1 * np.load('rain.npy')
rain[rain < 0] = .05 / 2
dates = np.load('doy.npy').astype(int)
x = np.vstack((dates[:-1], np.sign(rain[:-1])))
x = x.T
y = np.sign(rain[1:])
# 创建测试集和训练集数据
x_tain, x_test, y_train, y_test = train_test_split(x, y, random_state=37)
# 验证各参数的取值范围
clf = tree.DecisionTreeClassifier(random_state=37)
params = { "max_depth": [2, None],
"min_samples_leaf": sp_randint(1, 5),
"criterion": ["gini", "entropy"]}
rscv = RandomizedSearchCV(clf, params)
rscv.fit(x_tain, y_train)
# 绘制决策树的对象
sio = StringIO()
tree.export_graphviz(rscv.best_estimator_, out_file=sio, feature_names=['day-of-year', 'yest'])
dec_tree = pydot.graph_from_dot_data(sio.getvalue())
with NamedTemporaryFile(prefix='rain', suffix='.png', delete=False) as f:
# dec_tree.write_png(f.name)
dec_tree[0].write_png(f.name)
print("Written figure to", f.name)
print('Best Train Score', rscv.best_score_)
print('Test Score', rscv.score(x_test, y_test))
print("Best params", rscv.best_params_)
11决策树
from sklearn.cross_validation import train_test_split
from sklearn import tree
from sklearn.grid_search import RandomizedSearchCV
from scipy.stats import randint as sp_randint
import pydot
import StringIO
import numpy as np
from tempfile import NamedTemporaryFile
rain = .1 * np.load('rain.npy')
rain[rain < 0] = .05/2
dates = np.load('doy.npy').astype(int)
x = np.vstack((dates[:-1], np.sign(rain[:-1])))
x = x.T
y = np.sign(rain[1:])
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=37)
clf = tree.DecisionTreeClassifier(random_state=37)
params = { "max_depth": [2, None],
"min_samples_leaf": sp_randint(1, 5),
"criterion": ["gini", "entropy"]}
rscv = RandomizedSearchCV(clf, params)
rscv.fit(x_train,y_train)
sio = StringIO.StringIO()
tree.export_graphviz(rscv.best_estimator_, out_file=sio, feature_names=['day-of-year','yest'])
dec_tree = pydot.graph_from_dot_data(sio.getvalue())
with NamedTemporaryFile(prefix='rain', suffix='.png', delete=False) as f:
dec_tree.write_png(f.name)
print "Written figure to", f.name
print "Best Train Score", rscv.best_score_
print "Test Score", rscv.score(x_test, y_test)
print "Best params", rscv.best_params_
12网络
import numpy as np
import theanets
import multiprocessing
from sklearn import datasets
from sklearn.metrics import accuracy_score
rain = .1 * np.load('rain.npy')
rain[rain < 0] = .05/2
dates = np.load('doy.npy')
x = np.vstack((dates[:-1], np.sign(rain[:-1])))
x = x.T
y = np.vstack(np.sign(rain[1:]),)
N = int(.9 * len(x))
e = theanets.Experiment(theanets.Regressor,
layers=(2, 3, 1),
learning_rate=0.1,
momentum=0.5,
patience=300,
train_batches=multiprocessing.cpu_count(),
num_updates=500)
train = [x[:N], y[:N]]
valid = [x[N:], y[N:]]
e.run(train, valid)
pred = e.network(x[N:]).ravel()
print "Pred Min", pred.min(), "Max", pred.max()
print "Y Min", y.min(), "Max", y.max()
print "Accuracy", accuracy_score(y[N:], pred >= .5)
第11章:python生态系统的外部环境和云计算
第12章:性能优化,性能分析与并发性
613
时间
1、日期和时间数据类型及工具
'''Python标准库中包含用于日期(date)、时间(time)数据的数据类型。而且还有日历方面的功能。主要会用到datetime、time、calendar模块'''
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt #date,time,datetime,timedelta
from datetime import datetime
now = datetime.now()
#datetime以毫秒形式储存时间
print now,now.year,now.month,now.day,now.microsecond,'\n'
#datetime.timedelta表示两个datetime对象之间的时间差,换句话说,datetime格式可以相相减
delta = datetime(2011,1,7) - datetime(2008,6,24,8,15)
print delta
#把注意下面是days And seconds
print dt.timedelta(926,56700)
print delta.days
print delta.seconds
#print delta.minutes #是错误的
start = datetime(2011,1,7)
#参数分别为days,seconds,microseconds(微秒),milliseconds(毫秒),minutes,hours,weeks,除了微秒小数自动四舍五入之外,其他的都能自动转换为其他度量
print start + dt.timedelta(1,20,0.5,5,10,10,0)
##字符串和datetime的相互转换
'''利用str或者strftime方法(传入一个格式化字符串),datetime对象和pandas中timestamp对象就可以转换为字符串'''
from dateutil.parser import parse
stamp = datetime(2011,1,3)
print str(stamp),'\n'
#看一下下面的字符,很有意思,自己不小心打错了,运行仍然是正确的
print stamp.strftime('&Y-%m-%d')
print stamp.strftime('%Y-%m-%d'),'\n'
value = '2011-01-03'
print datetime.strptime(value,'%Y-%m-%d') #注意这是datetime函数的函数,不是模块的函数
datestrs = ['7/6/2011','8/6/2011']
print [datetime.strptime(x,'%m/%d/%Y') for x in datestrs]
#上面将字符串转化为最常用的格式,但是米次都自己写出来有点麻烦,可以用dateutil这个第三方包中的parser.parse方法
print parse('2011-01-03')
#dateutil可以几乎解析所有能够理解的日期表示形式(很可惜中文不行),这个应该是很实用的
print parse('2011/01/03')
print parse('Jan 31,1997 10:45 PM')
print parse('6/12/2011',dayfirst = True),'\n'#国际通用格式中,日出现在月的前面,传入dayfirst = True即可
#pandas通常是用于处理成组日期的,不管这些日期是DataFrame的行还是列。
print pd.to_datetime(datestrs),'\n'
idx = pd.to_datetime(datestrs + [None])
print idx
print idx[2] #这里应该是NaT(Not a Time)
print pd.isnull(idx)
#parse是一个不完美的工具,比如下面
print parse('42')
##日期的一些格式
%Y:4位数的年/%y:2位数的年 /%m:2位数的月 /%d:2位数的日/%H%I(12小时制)/%M%S%w用整数表示的星期几
2、时间序列基础
'''pandas最基本的时间序列类型就是以时间戳(通常用Python字符串或datatime对象表示)为索引的Series。'''
from pandas import Series,DataFrame
dates = [datetime(2011,1,2),datetime(2011,1,5),datetime(2011,1,7),
datetime(2011,1,8),datetime(2011,1,10),datetime(2011,1,12)]
#print dates
ts = Series(np.random.randn(6),index = dates)
print ts,'\n'
#这些datetime对象实际上是被放在一个DatetimeIndex中的。现在,变量ts就成为了TimeSeries了。
print type(ts)
print ts.index,'\n'
#没必要显示使用TimeSeries的构造函数。当创建一个带有DatetimeIndex的Series时,pandas就会知道该对象是一个时间序列
print ts + ts[::2]
#pandas用NumPy的datetime64数据类型以纳秒形式存储时间戳:
print ts.index.dtype
#DatetimeIndex中的各个标量值是pandas的Timestamp
stamp = ts.index[0]
print stamp
#只要有需要,TimeStamp可以随时自动转换为datetime对象。此外,还可以存储频率信息,且知道如何执行时区转换以及其他操作
2.2索引、选取、
子集构造,TimeSeries是Series的一个子类,所以在索引以及数据选取方面跟Series一样。
stamp = ts.index[2]
print ts[stamp],'\n'
#还有更方便的用法,传入可以被解释为日期的字符串
print ts['1/10/2011']
print ts['20110110'],'\n'
#对于较长的时间序列,只需传入“年”或“年月”即可轻松选取数据切片
long_ts = Series(np.random.randn(1000),
index = pd.date_range('1/1/2000',periods = 1000))
#-*- coding:utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
from pandas import Series,DataFrame
from datetime import datetime
from dateutil.parser import parse
import time
print long_ts,'\n'
print long_ts['2001'],'\n'
print long_ts['2001-05'],'\n'
#通过日期进行切片的方式只对规则Series有效:
print ts[datetime(2011,1,7):],'\n'
#由于大部分时间序列数据都是按照时间先后排序的,因此你可以用不存在于该时间序列中的时间戳对其进行切片(即范围查询)
#就是说,本来1/6/2011不在index中,却可以用来当作范围
print ts['1/6/2011':'1/11/2011'],'\n' #这里可以传入字符串日期、datetime或者Timestamp
print 'This is time and localtime'
print "time.time(): %f " % time.time()
print time.localtime( time.time() )
print time.asctime( time.localtime(time.time()) )
ltime=time.localtime(int(time.time())) #time.time()不能直接运用strftime进行转换
print time.strftime("%Y-%m-%d %H:%M:%S", ltime)
#time asctime() 函数接受时间元组并返回一个可读的形式为"Tue Dec 11 18:07:14 2008"
print 'over','\n'
#还有一个等价方法截取两个日期之间的TimeSeries.
print ts.truncate(after = '1/9/2011'),'\n'
#上面这些对DataFrame也有效
dates = pd.date_range('1/1/2000',periods = 100,freq = 'W-WED') #这里的freq是按照星期进行增加
long_df = DataFrame(np.random.randn(100,4),index = dates,columns = ['Colorado','Texas','New York','Ohio'])
print long_df.ix['2001-05']
2.3带有重复索引的时间序列
import time
#注意下面的DatetimeIndex生成方式
dates = pd.DatetimeIndex(['1/1/2000','1/2/2000','1/2/2000','1/2/2000','1/3/2000'])
dup_ts = Series(np.arange(5),index = dates)
print dup_ts,'\n'
#通过检唯一的测is_unique属性,我们就可以知道它不是
print dup_ts.index.is_unique,'\n'
#此时若索引,得到的可能是标量值,也可能是切片
print dup_ts['1/2/2000'],'\n'
print dup_ts['1/3/2000']
#假如你想要对具有非
#唯一时间戳的数据进行聚合一个办法是使用groupby,并传入level = 0
grouped = dup_ts.groupby(level = 0)
print grouped.mean(),'\n'
print grouped.count()
3、日期的范围、频率以及移动
#定义列表
dates = [datetime(2011,1,2),datetime(2011,1,5),datetime(2011,1,7),
datetime(2011,1,8),datetime(2011,1,10),datetime(2011,1,12)]
#print dates
ts = Series(np.random.randn(6),index = dates)
#print ts
#下面进行重采样,得到具有固定时间频率(每天)的时间序列,当让这样的话就会产生缺失值
print ts.resample('D')#-*- coding:utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
from pandas import Series,DataFrame
from datetime import datetime
from dateutil.parser import parse
import time
#定义列表
dates = [datetime(2011,1,2),datetime(2011,1,5),datetime(2011,1,7),
datetime(2011,1,8),datetime(2011,1,10),datetime(2011,1,12)]
#print dates
ts = Series(np.random.randn(6),index = dates)
#print ts
#下面进行重采样,得到具有固定时间频率(每天)的时间序列,当让这样的话就会产生缺失值
print ts.resample('D') #频率的转换(或重采样)主题较大,后面再说
3.2 生成日期范围
#pandas.date_range会生成指定长度的DatetimeIndex
index = pd.date_range('4/1/2015','6/1/2015')
print index,'\n'
#默认情况下,date_range产生按天计算的时间点,当然可以传入开始或结束日期,还得传入一个表示一段时间的数字
print pd.date_range('1/1/2016',periods = 31),'\n'
#开始和结束定义了日期索引的严格边界,如果你想要生成一个由每月最后一个工作日组成的日期索引,可以传入‘BM’(business end of month)
#这样就只会包含时间间隔内(或者放好在时间边界上)符合频率要求的日期:
print pd.date_range('12/18/2015','1/1/2016',freq = 'BM'),'\n'
#date_range默认保留起始和结束时间戳信息
print pd.date_range('5/2/2015 12:12:12',periods = 5)
#有时,虽然起始和结束带有时间信息,但是可以用normalize = True把它们吧变为00:00:00
print pd.date_range('5/2/2015 12:12:12',periods = 5,normalize = True)
3.3频率和日期偏移量
from pandas.tseries.offsets import Hour,Minute
#pandas中的频率是由一个基础频率和一个乘数组成的。基础的频率由字符串表示,比如‘M’表示月,‘H’表示小时
#对于每个基础频率,都有一个被称为日期偏移量(date offset)的对象与之对应。
hour = Hour()
print hour #感觉这个形式比较霸气
#传入整数可以自定义偏移量倍数
four_hours = Hour(4)
print four_hours
#一般而言,并不需要显示创建偏移量,只需创建时间序列时传入'H'或者'4h'即可
print pd.date_range('1/1/2016','1/2/2016',freq = '4h'),'\n'
#偏移量可以拼接
print Hour(1) + Minute(30)
#传入频率字符串('2h30min'),这种字符串可以被高效地解析为等效的表达式
print pd.date_range('1/1/2016',periods = 10,freq = '1h30min'),'\n'
#有些频率所描述的时间点并不是均匀分隔的。例如'M'和'BM'就取决于每月的天数,对于后者,还要考虑月末是不是周末,将这些成为锚点偏移量(anchored offset)
#WOM(Week Of Month)日期是一个非常常用的频率,以WOM开头,能产生诸如“每月第三个星期五”之类的信息
rng = pd.date_range('1/1/2016','9/1/2016',freq = 'WOM-3FRI')
print rng
#3.3移动(超前和滞后)数据
from pandas.tseries.offsets import Hour,Minute
ts = Series(np.random.randn(4),index = pd.date_range('1/1/2016',periods = 4,freq = 'M'))
print ts
print ts.shift(2)
print ts.shift(-2),'\n'
#可以看到,shift通常用于计算一个时间序列或多个时间序列(如DataFrame列)中的百分比变化。
print ts / ts.shift(1) - 1
#单纯的移位操作不会修改索引,所以部分数据会被丢弃,如果频率已知,则可以将其传给shift以实现对时间戳进行位移而不是只对数据移位
print ts.shift(2,freq = 'M') #时间戳移动,而数据不动
#当然也可以自己定义移动的频率
print ts.shift(3,freq = 'D'),'\n' #时间的移动不是上下移动,而是将时间列的每个值进行移动
print ts.shift(1,freq = '3D')
print ts.shift(1,freq = '90T')
3.5 通过偏移量对日期进行位移
from pandas.tseries.offsets import Hour,Minute,Day,MonthEnd
now = datetime(2011,11,29)
print type(now)
print now + Day(3),'\n'
#如果加的是锚点偏移量,第一次增量会将原日期向前滚动到符合频率规则的下一个日期
#如果本来就是锚点,那么下一个就是下一个锚点
print now + MonthEnd(),'\n'
print now + MonthEnd(2),'\n'
#通过锚点偏移量的rollforward和rollback方法,可显示地将日期向前或向后“滚动”
offset = MonthEnd()
print offset.rollforward(now),'\n'
print offset.rollback(now),'\n'
#日期偏移量还有一个巧妙的用法,即结合groupby使用这两个“滚动”方法
ts = Series(np.random.randn(20),index = pd.date_range('1/15/2000',periods = 20,freq = '4d'))
print ts,'\n'
#注意下面的方式,很隐晦
print ts.groupby(offset.rollforward).mean(),'\n'
#当然,更简单快速的方式是使用resample
print ts.resample('M',how = 'mean')
4、时区处理
from pandas.tseries.offsets import Hour,Minute,Day,MonthEnd
import pytz
print pytz.common_timezones[-5:]
#要从pytz中获取时区对象,使用pytz.timezone即可
tz = pytz.timezone('US/Eastern')
print tz #这里的输出已经和课本上不一样,估计是进行了简化,使得更方便了
#4.2本地化和转换:默认情况下,pandas中的序列是单纯的(naive[too young too simple!navie!])时区。
rng = pd.date_range('3/9/2012 9:30',periods = 6,freq = 'D')
ts = Series(np.random.randn(len(rng)),index = rng)
print ts,'\n'
print ts.index.tz,'\n' #默认的时区字段为None
#在生成日期范围的时候还可以加上一个时区集
print pd.date_range('3/9/2012',periods = 10,freq = 'D',tz = 'UTC'),'\n'
#从单纯到本地化的转换是通过tz_localize方法处理的:
ts_utc = ts.tz_localize('US/Pacific') #转换为美国太平洋时间
print ts_utc,'\n'
print ts_utc.index,'\n'
#一旦被转换为某个特定时期,就可以用tz_convert将其转换到其他时区了
print ts_utc.tz_convert('US/Eastern'),'\n'
#tz_localize和tz_convert是DatetimeIndex的实例方法,可以把一个DatetimeIndex转化为特定时区
print ts.index.tz_localize('Asia/Shanghai')
4.3操作时区意识型(time zone-aware)
Timestamp对象:跟时间序列和日期序列差不多,Timestamp对象也能被从单纯型(navie)本地化为time zone-aware,并从一个时区转换为另一个时区。
stamp = pd.Timestamp('2011-03-12 04:00')
print type(stamp),'\n'
stamp_utc = stamp.tz_localize('UTC')
print stamp_utc,'\n'
print stamp_utc.tz_convert('US/Eastern'),'\n'
stamp_moscow = pd.Timestamp('2011-03-12 04:00',tz = 'Europe/Moscow')
print stamp_moscow
#时区意识型Timestamp对象在内部保存了一个UTC时间戳值(自1970年1月1日起的纳秒数),这个UTC值在时区转换过程中是不会变化的
print stamp_utc.value
print stamp_utc.tz_convert('US/Eastern').value,'\n'
#当使用pandas的DataOffset对象执行运算时,会自动关注“夏时令”…………
4.4 不同时区之间的运算
rng = pd.date_range('3/7/2012',periods = 10,freq = 'B')
ts = Series(np.random.randn(len(rng)),index = rng)
print ts
ts1 = ts[:7].tz_localize('Europe/London')
#注意naive是不能直接转换为时区的,必须先转换为localize再进行转换
ts2 = ts1[2:].tz_convert('Europe/Moscow')
result = ts1 + ts2
#转换为UTC
print result.index