Numpy 用recarray创建评分表

用recarray创建评分表recarray类是ndarray的子类。可以像在数据库里面一样,用recarray存放由不同类型的数据构成的记录。例如,可以用它来存放有关雇员的记录,包括薪资等数值类型的数据以及雇员姓名等字符串类型的数据。

现代经济理论告诉我们,投资可以归结为对风险和回报的优化。风险可以表示为对数收益率的标准差(更多有关算数收益率和对数收益率的信息请见http://en.wikipedia.org/wiki/Rate_of_return#Arithmetic_and_logarithmic_return),而回报可以表示为对数收益率的平均值。我们可以提供一个评分,用相对高的分值表示低风险和高回报。我们将计算若干股票的分值,并以表格的形式,把这些分值和股票代码一起保存到一个NumPy recarray对象中。

具体步骤

我们将从创建记录类型的数组开始。

  1. 创建记录类型的数组。

创建一个记录类型的数组。每条记录包括股票代码、标准差分值、均值分值和总评分等字段。

weights = numpy.recarray((len(tickers),),
    dtype=[('symbol', numpy.str_, 16),
    ('stdscore', float), ('mean', float),
    ('score', float)])              

  1. 初始化分值。

简单起见,我们基于对数收益率,通过一个循环,对分值进行初始化。

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. 对分值进行归一化处理。

我们现在已经获得了一些分值,但不同类型的分值是不能直接相互比较的。首先需要对这些分值进行归一化处理,然后才能对其进行组合。归一化意味着要确保同类型的分值加起来等于1。

for key in ['mean', 'stdscore']:
    wsum = weights[key].sum()
    weights[key] = weights[key]/wsum

  1. 计算总评分并排序。

本例中的总评分就是各个归一化处理后的单项分值的平均值。依据总评分对记录进行排序并生成排名表。

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数组的功能。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程