相信很多人都想过让人工智能来帮你赚钱,但到底该如何做呢?瑞士日内瓦的一位金融数据顾问 Gaëtan Rickter 近日发表文章介绍了他利用 Python 和机器学习来帮助炒股的经验,其最终成果的收益率跑赢了长期处于牛市的标准普尔 500 指数。虽然这篇文章并没有将他的方法完全彻底公开,但已公开的内容或许能给我们带来如何用人工智能炒股的启迪。
创新互联公司是一家专注于成都做网站、网站制作与策划设计,甘德网站建设哪家好?创新互联公司做网站,专注于网站建设十载,网设计领域的专业建站公司;建站业务涵盖:甘德等地区。甘德做网站价格咨询:18982081108
我终于跑赢了标准普尔 500 指数 10 个百分点!听起来可能不是很多,但是当我们处理的是大量流动性很高的资本时,对冲基金的利润就相当可观。更激进的做法还能得到更高的回报。
这一切都始于我阅读了 Gur Huberman 的一篇题为《Contagious Speculation and a Cure for Cancer: A Non-Event that Made Stock Prices Soar》的论文。该研究描述了一件发生在 1998 年的涉及到一家上市公司 EntreMed(当时股票代码是 ENMD)的事件:
「星期天《纽约时报》上发表的一篇关于癌症治疗新药开发潜力的文章导致 EntreMed 的股价从周五收盘时的 12.063 飙升至 85,在周一收盘时接近 52。在接下来的三周,它的收盘价都在 30 以上。这股投资热情也让其它生物科技股得到了溢价。但是,这个癌症研究方面的可能突破在至少五个月前就已经被 Nature 期刊和各种流行的报纸报道过了,其中甚至包括《泰晤士报》!因此,仅仅是热情的公众关注就能引发股价的持续上涨,即便实际上并没有出现真正的新信息。」
在研究者给出的许多有见地的观察中,其中有一个总结很突出:
「(股价)运动可能会集中于有一些共同之处的股票上,但这些共同之处不一定要是经济基础。」
我就想,能不能基于通常所用的指标之外的其它指标来划分股票。我开始在数据库里面挖掘,几周之后我发现了一个,其包含了一个分数,描述了股票和元素周期表中的元素之间的「已知和隐藏关系」的强度。
我有计算基因组学的背景,这让我想起了基因和它们的细胞信号网络之间的关系是如何地不为人所知。但是,当我们分析数据时,我们又会开始看到我们之前可能无法预测的新关系和相关性。
选择出的涉及细胞可塑性、生长和分化的信号通路的基因的表达模式
和基因一样,股票也会受到一个巨型网络的影响,其中各个因素之间都有或强或弱的隐藏关系。其中一些影响和关系是可以预测的。
我的一个目标是创建长的和短的股票聚类,我称之为「篮子聚类(basket clusters)」,我可以将其用于对冲或单纯地从中获利。这需要使用一个无监督机器学习方法来创建股票的聚类,从而使这些聚类之间有或强或弱的关系。这些聚类将会翻倍作为我的公司可以交易的股票的「篮子(basket)」。
首先我下载了一个数据集:Public Company Hidden Relationship Discovery,这个数据集基于元素周期表中的元素和上市公司之间的关系。
然后我使用了 Python 和一些常用的机器学习工具——scikit-learn、numpy、pandas、matplotlib 和 seaborn,我开始了解我正在处理的数据集的分布形状。为此我参考了一个题为《Principal Component Analysis with KMeans visuals》的 Kaggle Kernel:Principal Component Analysis with KMeans visuals
import numpy as npimport pandas as pdfrom sklearn.decomposition import PCAfrom sklearn.cluster import KMeansimport matplotlib.pyplot as pltimport seaborn as sbnp.seterr(divide='ignore', invalid='ignore')# Quick way to test just a few column features# stocks = pd.read_csv('supercolumns-elements-nasdaq-nyse-otcbb-general-UPDATE-2017-03-01.csv', usecols=range(1,16))stocks = pd.read_csv('supercolumns-elements-nasdaq-nyse-otcbb-general-UPDATE-2017-03-01.csv')print(stocks.head())str_list = []for colname, colvalue in stocks.iteritems(): if type(colvalue[1]) == str:
str_list.append(colname)# Get to the numeric columns by inversionnum_list = stocks.columns.difference(str_list)stocks_num = stocks[num_list]print(stocks_num.head())
输出:简单看看前面 5 行:
zack@twosigma-Dell-Precision-M3800:/home/zack/hedge_pool/baskets/hcluster$ ./hidden_relationships.py
Symbol_update-2017-04-01 Hydrogen Helium Lithium Beryllium Boron \
0 A 0.0 0.00000 0.0 0.0 0.0
1 AA 0.0 0.00000 0.0 0.0 0.0
2 AAAP 0.0 0.00461 0.0 0.0 0.0
3 AAC 0.0 0.00081 0.0 0.0 0.0
4 AACAY 0.0 0.00000 0.0 0.0 0.0
Carbon Nitrogen Oxygen Fluorine ... Fermium Mendelevium \
0 0.006632 0.0 0.007576 0.0 ... 0.000000 0.079188
1 0.000000 0.0 0.000000 0.0 ... 0.000000 0.000000
2 0.000000 0.0 0.000000 0.0 ... 0.135962 0.098090
3 0.000000 0.0 0.018409 0.0 ... 0.000000 0.000000
4 0.000000 0.0 0.000000 0.0 ... 0.000000 0.000000
Nobelium Lawrencium Rutherfordium Dubnium Seaborgium Bohrium Hassium \
0 0.197030 0.1990 0.1990 0.0 0.0 0.0 0.0
1 0.000000 0.0000 0.0000 0.0 0.0 0.0 0.0
2 0.244059 0.2465 0.2465 0.0 0.0 0.0 0.0
3 0.000000 0.0000 0.0000 0.0 0.0 0.0 0.0
4 0.000000 0.0000 0.0000 0.0 0.0 0.0 0.0
Meitnerium
0 0.0
1 0.0
2 0.0
3 0.0
4 0.0
[5 rows x 110 columns]
Actinium Aluminum Americium Antimony Argon Arsenic Astatine \
0 0.000000 0.0 0.0 0.002379 0.047402 0.018913 0.0
1 0.000000 0.0 0.0 0.000000 0.000000 0.000000 0.0
2 0.004242 0.0 0.0 0.001299 0.000000 0.000000 0.0
3 0.000986 0.0 0.0 0.003378 0.000000 0.000000 0.0
4 0.000000 0.0 0.0 0.000000 0.000000 0.000000 0.0
Barium Berkelium Beryllium ... Tin Titanium Tungsten Uranium \
0 0.0 0.000000 0.0 ... 0.0 0.002676 0.0 0.000000
1 0.0 0.000000 0.0 ... 0.0 0.000000 0.0 0.000000
2 0.0 0.141018 0.0 ... 0.0 0.000000 0.0 0.004226
3 0.0 0.000000 0.0 ... 0.0 0.000000 0.0 0.004086
4 0.0 0.000000 0.0 ... 0.0 0.000000 0.0 0.000000
Vanadium Xenon Ytterbium Yttrium Zinc Zirconium
0 0.000000 0.0 0.0 0.000000 0.000000 0.0
1 0.000000 0.0 0.0 0.000000 0.000000 0.0
2 0.002448 0.0 0.0 0.018806 0.008758 0.0
3 0.001019 0.0 0.0 0.000000 0.007933 0.0
4 0.000000 0.0 0.0 0.000000 0.000000 0.0
[5 rows x 109 columns]
zack@twosigma-Dell-Precision-M3800:/home/zack/hedge_pool/baskets/hcluster$
概念特征的皮尔逊相关性(Pearson Correlation)。在这里案例中,是指来自元素周期表的矿物和元素:
stocks_num = stocks_num.fillna(value=0, axis=1)X = stocks_num.valuesfrom sklearn.preprocessing import StandardScalerX_std = StandardScaler().fit_transform(X)f, ax = plt.subplots(figsize=(12, 10))plt.title('Pearson Correlation of Concept Features (Elements Minerals)')# Draw the heatmap using seabornsb.heatmap(stocks_num.astype(float).corr(),linewidths=0.25,vmax=1.0, square=True, cmap="YlGnBu", linecolor='black', annot=True)sb.plt.show()
输出:(这个可视化例子是在前 16 个样本上运行得到的)。看到元素周期表中的元素和上市公司关联起来真的很有意思。在某种程度时,我想使用这些数据基于公司与相关元素或材料的相关性来预测其可能做出的突破。
测量「已解释方差(Explained Variance)」和主成分分析(PCA)
已解释方差=总方差-残差方差(explained variance = total variance - residual variance)。应该值得关注的 PCA 投射组件的数量可以通过已解释方差度量(Explained Variance Measure)来引导。Sebastian Raschka 的关于 PCA 的文章对此进行了很好的描述,参阅:Principal Component Analysis
# Calculating Eigenvectors and eigenvalues of Cov matirxmean_vec = np.mean(X_std, axis=0)cov_mat = np.cov(X_std.T)eig_vals, eig_vecs = np.linalg.eig(cov_mat)# Create a list of (eigenvalue, eigenvector) tupleseig_pairs = [ (np.abs(eig_vals[i]),eig_vecs[:,i]) for i in range(len(eig_vals))]# Sort from high to loweig_pairs.sort(key = lambda x: x[0], reverse= True)# Calculation of Explained Variance from the eigenvaluestot = sum(eig_vals)var_exp = [(i/tot)*100 for i in sorted(eig_vals, reverse=True)] cum_var_exp = np.cumsum(var_exp) # Cumulative explained variance# Variances plotmax_cols = len(stocks.columns) - 1plt.figure(figsize=(10, 5))plt.bar(range(max_cols), var_exp, alpha=0.3333, align='center', label='individual explained variance', color = 'g')plt.step(range(max_cols), cum_var_exp, where='mid',label='cumulative explained variance')plt.ylabel('Explained variance ratio')plt.xlabel('Principal components')plt.legend(loc='best')plt.show()
输出:
从这个图表中我们可以看到大量方差都来自于预测主成分的前 85%。这是个很高的数字,所以让我们从低端的开始,先只建模少数几个主成分。更多有关分析主成分合理数量的信息可参阅:Principal Component Analysis explained visually
使用 scikit-learn 的 PCA 模块,让我们设 n_components = 9。代码的第二行调用了 fit_transform 方法,其可以使用标准化的电影数据 X_std 来拟合 PCA 模型并在该数据集上应用降维(dimensionality reduction)。
pca = PCA(n_components=9)
x_9d = pca.fit_transform(X_std)
plt.figure(figsize = (9,7))
plt.scatter(x_9d[:,0],x_9d[:,1], c='goldenrod',alpha=0.5)
plt.ylim(-10,30)
plt.show()
输出:
这里我们甚至没有真正观察到聚类的些微轮廓,所以我们很可能应该继续调节 n_component 的值直到我们得到我们想要的结果。这就是数据科学与艺术(data science and art)中的「艺术」部分。
现在,我们来试试 K-均值,看看我们能不能在下一章节可视化任何明显的聚类。
K-均值聚类(K-Means Clustering)
我们将使用 PCA 投射数据来实现一个简单的 K-均值。
使用 scikit-learn 的 KMeans() 调用和 fit_predict 方法,我们可以计算聚类中心并为第一和第三个 PCA 投射预测聚类索引(以便了解我们是否可以观察到任何合适的聚类)。然后我们可以定义我们自己的配色方案并绘制散点图,代码如下所示:
# Set a 3 KMeans clustering
kmeans = KMeans(n_clusters=3)
# Compute cluster centers and predict cluster indices
X_clustered = kmeans.fit_predict(x_9d)# Define our own color map
LABEL_COLOR_MAP = {0 : 'r',1 : 'g',2 : 'b'}
label_color = [LABEL_COLOR_MAP[l] for l in X_clustered]
# Plot the scatter digram
plt.figure(figsize = (7,7))
plt.scatter(x_9d[:,0],x_9d[:,2], c= label_color, alpha=0.5)
plt.show()
输出:
这个 K-均值散点图看起来更有希望,好像我们简单的聚类模型假设就是正确的一样。我们可以通过这种颜色可视化方案观察到 3 个可区分开的聚类。
使用 seaborn 方便的 pairplot 函数,我可以以成对的方式在数据框中自动绘制所有的特征。我们可以一个对一个地 pairplot 前面 3 个投射并可视化:
# Create a temp dataframe from our PCA projection data "x_9d"
df = pd.DataFrame(x_9d)
df = df[[0,1,2]]
df['X_cluster'] = X_clustered
# Call Seaborn's pairplot to visualize our KMeans clustering on the PCA projected data
sb.pairplot(df, hue='X_cluster', palette='Dark2', diag_kind='kde', size=1.85)
sb.plt.show()
输出:
构建篮子聚类(Basket Clusters)
你应该自己决定如何微调你的聚类。这方面没有什么万灵药,具体的方法取决于你操作的环境。在这个案例中是由隐藏关系所定义的股票和金融市场。
一旦你的聚类使你满意了,你就可以设置分数阈值来控制特定的股票是否有资格进入一个聚类,然后你可以为一个给定的聚类提取股票,将它们作为篮子进行交易或使用这些篮子作为信号。你可以使用这种方法做的事情很大程度就看你自己的创造力以及你在使用深度学习变体来进行优化的水平,从而基于聚类或数据点的概念优化每个聚类的回报,比如 short interest 或 short float(公开市场中的可用股份)。
你可以注意到了这些聚类被用作篮子交易的方式一些有趣特征。有时候标准普尔和一般市场会存在差异。这可以提供本质上基于「信息套利(information arbitrage)」的套利机会。一些聚类则和谷歌搜索趋势相关。
看到聚类和材料及它们的供应链相关确实很有意思,正如这篇文章说的一样:Zooming in on 10 materials and their supply chains - Fairphone
我仅仅使用该数据集操作了 Cobalt(钴)、Copper(铜)、Gallium(镓)和 Graphene(石墨烯)这几个列标签,只是为了看我是否可能发现从事这一领域或受到这一领域的风险的上市公司之间是否有任何隐藏的联系。这些篮子和标准普尔的回报进行了比较。
通过使用历史价格数据(可直接在 Quantopian、Numerai、Quandl 或 Yahoo Finance 使用),然后你可以汇总价格数据来生成预计收益,其可使用 HighCharts 进行可视化:
我从该聚类中获得的回报超过了标准普尔相当一部分,这意味着你每年的收益可以比标准普尔还多 10%(标准普尔近一年来的涨幅为 16%)。我还见过更加激进的方法可以净挣超过 70%。现在我必须承认我还做了一些其它的事情,但因为我工作的本质,我必须将那些事情保持黑箱。但从我目前观察到的情况来看,至少围绕这种方法探索和包装新的量化模型可以证明是非常值得的,而其唯一的缺点是它是一种不同类型的信号,你可以将其输入其它系统的流程中。
生成卖空篮子聚类(short basket clusters)可能比生成买空篮子聚类(long basket clusters)更有利可图。这种方法值得再写一篇文章,最好是在下一个黑天鹅事件之前。
如果你使用机器学习,就可能在具有已知和隐藏关系的上市公司的寄生、共生和共情关系之上抢占先机,这是很有趣而且可以盈利的。最后,一个人的盈利能力似乎完全关乎他在生成这些类别的数据时想出特征标签(即概念(concept))的强大组合的能力。
我在这类模型上的下一次迭代应该会包含一个用于自动生成特征组合或独特列表的单独算法。也许会基于近乎实时的事件,这可能会影响那些具有只有配备了无监督学习算法的人类才能预测的隐藏关系的股票组。
1.常用内置函数:(不用import就可以直接使用)
help(obj) 在线帮助, obj可是任何类型
callable(obj) 查看一个obj是不是可以像函数一样调用
repr(obj) 得到obj的表示字符串,可以利用这个字符串eval重建该对象的一个拷贝
eval_r(str) 表示合法的python表达式,返回这个表达式
dir(obj) 查看obj的name space中可见的name
hasattr(obj,name) 查看一个obj的name space中是否有name
getattr(obj,name) 得到一个obj的name space中的一个name
setattr(obj,name,value) 为一个obj的name space中的一个name指向vale这个object
delattr(obj,name) 从obj的name space中删除一个name
vars(obj) 返回一个object的name space。用dictionary表示
locals() 返回一个局部name space,用dictionary表示
globals() 返回一个全局name space,用dictionary表示
type(obj) 查看一个obj的类型
isinstance(obj,cls) 查看obj是不是cls的instance
issubclass(subcls,supcls) 查看subcls是不是supcls的子类
类型转换函数
chr(i) 把一个ASCII数值,变成字符
ord(i) 把一个字符或者unicode字符,变成ASCII数值
oct(x) 把整数x变成八进制表示的字符串
hex(x) 把整数x变成十六进制表示的字符串
str(obj) 得到obj的字符串描述
list(seq) 把一个sequence转换成一个list
tuple(seq) 把一个sequence转换成一个tuple
dict(),dict(list) 转换成一个dictionary
int(x) 转换成一个integer
long(x) 转换成一个long interger
float(x) 转换成一个浮点数
complex(x) 转换成复数
max(...) 求最大值
min(...) 求最小值
用于执行程序的内置函数
complie 如果一段代码经常要使用,那么先编译,再运行会更快。
2.和操作系统相关的调用
系统相关的信息模块 import sys
sys.argv是一个list,包含所有的命令行参数.
sys.stdout sys.stdin sys.stderr 分别表示标准输入输出,错误输出的文件对象.
sys.stdin.readline() 从标准输入读一行 sys.stdout.write("a") 屏幕输出a
sys.exit(exit_code) 退出程序
sys.modules 是一个dictionary,表示系统中所有可用的module
sys.platform 得到运行的操作系统环境
sys.path 是一个list,指明所有查找module,package的路径.
操作系统相关的调用和操作 import os
os.environ 一个dictionary 包含环境变量的映射关系 os.environ["HOME"] 可以得到环境变量HOME的值
os.chdir(dir) 改变当前目录 os.chdir('d:\\outlook') 注意windows下用到转义
os.getcwd() 得到当前目录
os.getegid() 得到有效组id os.getgid() 得到组id
os.getuid() 得到用户id os.geteuid() 得到有效用户id
os.setegid os.setegid() os.seteuid() os.setuid()
os.getgruops() 得到用户组名称列表
os.getlogin() 得到用户登录名称
os.getenv 得到环境变量
os.putenv 设置环境变量
os.umask 设置umask
os.system(cmd) 利用系统调用,运行cmd命令
操作举例:
os.mkdir('/tmp/xx') os.system("echo 'hello' /tmp/xx/a.txt") os.listdir('/tmp/xx')
os.rename('/tmp/xx/a.txt','/tmp/xx/b.txt') os.remove('/tmp/xx/b.txt') os.rmdir('/tmp/xx')
用python编写一个简单的shell
#!/usr/bin/python
import os, sys
cmd = sys.stdin.readline()
while cmd:
os.system(cmd)
cmd = sys.stdin.readline()
用os.path编写平台无关的程序
os.path.abspath("1.txt") == os.path.join(os.getcwd(), "1.txt")
os.path.split(os.getcwd()) 用于分开一个目录名称中的目录部分和文件名称部分。
os.path.join(os.getcwd(), os.pardir, 'a', 'a.doc') 全成路径名称.
os.pardir 表示当前平台下上一级目录的字符 ..
os.path.getctime("/root/1.txt") 返回1.txt的ctime(创建时间)时间戳
os.path.exists(os.getcwd()) 判断文件是否存在
os.path.expanduser('~/dir') 把~扩展成用户根目录
os.path.expandvars('$PATH') 扩展环境变量PATH
os.path.isfile(os.getcwd()) 判断是否是文件名,1是0否
os.path.isdir('c:\Python26\temp') 判断是否是目录,1是0否
os.path.islink('/home/huaying/111.sql') 是否是符号连接 windows下不可用
os.path.ismout(os.getcwd()) 是否是文件系统安装点 windows下不可用
os.path.samefile(os.getcwd(), '/home/huaying') 看看两个文件名是不是指的是同一个文件
os.path.walk('/home/huaying', test_fun, "a.c")
遍历/home/huaying下所有子目录包括本目录,对于每个目录都会调用函数test_fun.
例:在某个目录中,和他所有的子目录中查找名称是a.c的文件或目录。
def test_fun(filename, dirname, names): //filename即是walk中的a.c dirname是访问的目录名称
if filename in names: //names是一个list,包含dirname目录下的所有内容
print os.path.join(dirname, filename)
os.path.walk('/home/huaying', test_fun, "a.c")
文件操作
打开文件
f = open("filename", "r") r只读 w写 rw读写 rb读二进制 wb写二进制 w+写追加
读写文件
f.write("a") f.write(str) 写一字符串 f.writeline() f.readlines() 与下read类同
f.read() 全读出来 f.read(size) 表示从文件中读取size个字符
f.readline() 读一行,到文件结尾,返回空串. f.readlines() 读取全部,返回一个list. list每个元素表示一行,包含"\n"\
f.tell() 返回当前文件读取位置
f.seek(off, where) 定位文件读写位置. off表示偏移量,正数向文件尾移动,负数表示向开头移动。
where为0表示从开始算起,1表示从当前位置算,2表示从结尾算.
f.flush() 刷新缓存
关闭文件
f.close()
regular expression 正则表达式 import re
简单的regexp
p = re.compile("abc") if p.match("abc") : print "match"
上例中首先生成一个pattern(模式),如果和某个字符串匹配,就返回一个match object
除某些特殊字符metacharacter元字符,大多数字符都和自身匹配。
这些特殊字符是 。^ $ * + ? { [ ] \ | ( )
字符集合(用[]表示)
列出字符,如[abc]表示匹配a或b或c,大多数metacharacter在[]中只表示和本身匹配。例:
a = ".^$*+?{\\|()" 大多数metachar在[]中都和本身匹配,但"^[]\"不同
p = re.compile("["+a+"]")
for i in a:
if p.match(i):
print "[%s] is match" %i
else:
print "[%s] is not match" %i
在[]中包含[]本身,表示"["或者"]"匹配.用
和
表示.
^出现在[]的开头,表示取反.[^abc]表示除了a,b,c之外的所有字符。^没有出现在开头,即于身身匹配。
-可表示范围.[a-zA-Z]匹配任何一个英文字母。[0-9]匹配任何数字。
\在[]中的妙用。
\d [0-9]
\D [^0-9]
\s [ \t\n\r\f\v]
\S [^ \t\n\r\f\v]
\w [a-zA-Z0-9_]
\W [^a-zA-Z0-9_]
\t 表示和tab匹配, 其他的都和字符串的表示法一致
\x20 表示和十六进制ascii 0x20匹配
有了\,可以在[]中表示任何字符。注:单独的一个"."如果没有出现[]中,表示出了换行\n以外的匹配任何字符,类似[^\n].
regexp的重复
{m,n}表示出现m个以上(含m个),n个以下(含n个). 如ab{1,3}c和abc,abbc,abbbc匹配,不会与ac,abbbc匹配。
m是下界,n是上界。m省略表下界是0,n省略,表上界无限大。
*表示{,} +表示{1,} ?表示{0,1}
最大匹配和最小匹配 python都是最大匹配,如果要最小匹配,在*,+,?,{m,n}后面加一个?.
match object的end可以得到匹配的最后一个字符的位置。
re.compile("a*").match('aaaa').end() 4 最大匹配
re.compile("a*?").match('aaaa').end() 0 最小匹配
使用原始字符串
字符串表示方法中用\\表示字符\.大量使用影响可读性。
解决方法:在字符串前面加一个r表示raw格式。
a = r"\a" print a 结果是\a
a = r"\"a" print a 结果是\"a
使用re模块
先用re.compile得到一个RegexObject 表示一个regexp
后用pattern的match,search的方法,得到MatchObject
再用match object得到匹配的位置,匹配的字符串等信息
RegxObject常用函数:
re.compile("a").match("abab") 如果abab的开头和re.compile("a")匹配,得到MatchObject
_sre.SRE_Match object at 0x81d43c8
print re.compile("a").match("bbab")
None 注:从str的开头开始匹配
re.compile("a").search("abab") 在abab中搜索第一个和re_obj匹配的部分
_sre.SRE_Match object at 0x81d43c8
print re.compile("a").search("bbab")
_sre.SRE_Match object at 0x8184e18 和match()不同,不必从开头匹配
re_obj.findall(str) 返回str中搜索所有和re_obj匹配的部分.
返回一个tuple,其中元素是匹配的字符串.
MatchObject的常用函数
m.start() 返回起始位置,m.end()返回结束位置(不包含该位置的字符).
m.span() 返回一个tuple表示(m.start(), m.end())
m.pos(), m.endpos(), m.re(), m.string()
m.re().search(m.string(), m.pos(), m.endpos()) 会得到m本身
m.finditer()可以返回一个iterator,用来遍历所有找到的MatchObject.
for m in re.compile("[ab]").finditer("tatbxaxb"):
print m.span()
高级regexp
| 表示联合多个regexp. A B两个regexp,A|B表示和A匹配或者跟B匹配.
^ 表示只匹配一行的开始行首,^只有在开头才有此特殊意义。
$ 表示只匹配一行的结尾
\A 表示只匹配第一行字符串的开头 ^匹配每一行的行首
\Z 表示只匹配行一行字符串的结尾 $匹配第一行的行尾
\b 只匹配词的边界 例:\binfo\b 只会匹配"info" 不会匹配information
\B 表示匹配非单词边界
示例如下:
print re.compile(r"\binfo\b").match("info ") #使用raw格式 \b表示单词边界
_sre.SRE_Match object at 0x817aa98
print re.compile("\binfo\b").match("info ") #没有使用raw \b表示退格符号
None
print re.compile("\binfo\b").match("\binfo\b ")
_sre.SRE_Match object at 0x8174948
分组(Group) 示例:re.compile("(a(b)c)d").match("abcd").groups() ('abc', 'b')
#!/usr/local/bin/python
import re
x = """
name: Charles
Address: BUPT
name: Ann
Address: BUPT
"""
#p = re.compile(r"^name:(.*)\n^Address:(.*)\n", re.M)
p = re.compile(r"^name:(?P.*)\n^Address:(?P.*)\n", re.M)
for m in p.finditer(x):
print m.span()
print "here is your friends list"
print "%s, %s"%m.groups()
Compile Flag
用re.compile得到RegxObject时,可以有一些flag用来调整RegxObject的详细特征.
DOTALL, S 让.匹配任意字符,包括换行符\n
IGNORECASE, I 忽略大小写
LOCALES, L 让\w \W \b \B和当前的locale一致
MULTILINE, M 多行模式,只影响^和$(参见上例)
VERBOSE, X verbose模式
作为一个python新手,在学习中遇到很多问题,要善于运用各种方法。今天,在学习中,碰到了如何通过收盘价计算股票的涨跌幅。
第一种:
读取数据并建立函数:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import spline
from pylab import *
import pandas as pd
from pandas import Series
a=pd.read_csv('d:///1.csv',sep=',')#文件位置
t=a['close']
def f(t):
s=[]
for i in range(1,len(t)):
if i==1:
continue
else:
s.append((t[i]-t[i-1])/t[i]*100)
print s
plot(s)
plt.show()
f(t)
第二种:
利用pandas里面的方法:
import pandas as pd
a=pd.read_csv('d:///1.csv')
rets = a['close'].pct_change() * 100
print rets
第三种:
close=a['close']
rets=close/close.shift(1)-1
print rets
总结:python是一种非常好的编程语言,一般而言,我们可以运用构建相关函数来实现自己的思想,但是,众所周知,python中里面的有很多科学计算包,里面有很多方法可以快速解决计算的需要,如上面提到的pandas中的pct_change()。因此在平时的使用中应当学会寻找更好的方法,提高运算速度。
售后响应及时
7×24小时客服热线数据备份
更安全、更高效、更稳定价格公道精准
项目经理精准报价不弄虚作假合作无风险
重合同讲信誉,无效全额退款