用recarray创建评分表,recarray
类是ndarray
的子类。可以像在数据库里面一样,用recarray
存放由不同类型的数据构成的记录。例如,可以用它来存放有关雇员的记录,包括薪资等数值类型的数据以及雇员姓名等字符串类型的数据。
现代经济理论告诉我们,投资可以归结为对风险和回报的优化。风险可以表示为对数收益率的标准差(更多有关算数收益率和对数收益率的信息请见http://en.wikipedia.org/wiki/Rate_of_return#Arithmetic_and_logarithmic_return),而回报可以表示为对数收益率的平均值。我们可以提供一个评分,用相对高的分值表示低风险和高回报。我们将计算若干股票的分值,并以表格的形式,把这些分值和股票代码一起保存到一个NumPy recarray
对象中。
具体步骤
我们将从创建记录类型的数组开始。
- 创建记录类型的数组。
创建一个记录类型的数组。每条记录包括股票代码、标准差分值、均值分值和总评分等字段。
weights = numpy.recarray((len(tickers),),
dtype=[('symbol', numpy.str_, 16),
('stdscore', float), ('mean', float),
('score', float)])
- 初始化分值。
简单起见,我们基于对数收益率,通过一个循环,对分值进行初始化。
for i in xrange(len(tickers)):
close = get_close(tickers[i])
logrets = numpy.diff
(numpy.log(close))
weights[i]['symbol'] =
tickers[i]
weights[i]['mean'] =
logrets.mean()
weights[i]['stdscore'] =
1/logrets.std()
weights[i]['score'] = 0
如你所见,可以使用上一步中定义的字段名访问记录中的各个字段。
- 对分值进行归一化处理。
我们现在已经获得了一些分值,但不同类型的分值是不能直接相互比较的。首先需要对这些分值进行归一化处理,然后才能对其进行组合。归一化意味着要确保同类型的分值加起来等于1。
for key in ['mean', 'stdscore']:
wsum = weights[key].sum()
weights[key] = weights[key]/wsum
- 计算总评分并排序。
本例中的总评分就是各个归一化处理后的单项分值的平均值。依据总评分对记录进行排序并生成排名表。
weights['score'] = (weights
['stdscore'] + weights['mean'])/2
weights['score'].sort()
本攻略的完整代码如下。
import numpy
from matplotlib.finance
import quotes_historical_yahoo
from datetime import date
# 道琼斯工业指数成分股,股利收益率>4%
tickers = ['MRK', 'T', 'VZ']
def get_close(ticker):
today = date.today()
start = (today.year - 1, today.month, today.day)
quotes = quotes_historical_yahoo
(ticker, start, today)
return numpy.array([q[4] for q in quotes])
weights = numpy.recarray((len(tickers),),
dtype=[('symbol', numpy.str_, 16),
('stdscore', float), ('mean', float),
('score', float)])
for i in xrange(len(tickers)):
close = get_close(tickers[i])
logrets = numpy.diff(numpy.log(close))
weights[i]['symbol'] = tickers[i]
weights[i]['mean'] = logrets.mean()
weights[i]['stdscore'] = 1/logrets.std()
weights[i]['score'] = 0
for key in ['mean', 'stdscore']:
wsum = weights[key].sum()
weights[key] = weights[key]/wsum
weights['score'] = (weights['stdscore'] +
weights['mean'])/2
weights['score'].sort()
for record in weights:
print "%s,mean=%.4f,stdscore=%.4f,
score=%.4f" % (record['symbol'],
record['mean'], record['stdscore'],
record['score'])
程序执行后,输出如下内容。
MRK,mean=0.1862,stdscore=0.2886,score=0.2374
T,mean=0.3570,stdscore=0.3556,score=0.3563
VZ,mean=0.4569,stdscore=0.3557,score=0.4063
攻略小结
我们计算了几支股票的分值,并把计算结果存储到了一个NumPy recarray
对象中。recarray
数组允许我们把不同类型的数据(例如本攻略中的股票代码和数值类型的分值)放在一条记录中。recarray
数组还允许我们访问数组成员的各个字段,例如arr.field
。本章介绍了recarray
数组的创建。在numpy.recarray模块中,可以发现更多有关recarray
数组的功能。