2012-06-16 29 views
3

我下载的股票价格从雅虎对于S & P500,它具有体积太大,一个32位整数。获取NumPy的溢出尽管宣称D型= Int64的

def yahoo_prices(ticker, start_date=None, end_date=None, data='d'): 

    csv = yahoo_historical_data(ticker, start_date, end_date, data) 

    d = [('date',  np.datetime64), 
     ('open',  np.float64), 
     ('high',  np.float64), 
     ('low',  np.float64), 
     ('close',  np.float64), 
     ('volume', np.int64), 
     ('adj_close', np.float64)] 

    return np.recfromcsv(csv, dtype=d) 

这里的错误:

>>> sp500 = yahoo_prices('^GSPC') 
Traceback (most recent call last): 
    File "<stdin>", line 108, in <module> 
    File "<stdin>", line 74, in yahoo_prices 
    File "/usr/local/lib/python2.6/dist-packages/numpy/lib/npyio.py", line 1812, in recfromcsv 
    output = genfromtxt(fname, **kwargs) 
    File "/usr/local/lib/python2.6/dist-packages/numpy/lib/npyio.py", line 1646, in genfromtxt 
    output = np.array(data, dtype=ddtype) 
OverflowError: long int too large to convert to int 

为什么我还可以,如果我宣布使用Int64设置D型得到这个错误?这是一个迹象表明,IO功能是不是真的用我的D型序列d

===编辑...例如CSV添加===

Date,Open,High,Low,Close,Volume,Adj Close 
2012-06-15,1329.19,1343.32,1329.19,1342.84,4401570000,1342.84 
2012-06-14,1314.88,1333.68,1314.14,1329.10,3687720000,1329.10 
2012-06-13,1324.02,1327.28,1310.51,1314.88,3506510000,1314.88 
+0

可以显示一行或两行CSV示例输入吗? –

回答

3

我不知道,但我认为你发现numpy的一个bug。我提起了here

正如我说有,如果你打开npyio.py和编辑内recfromcsv这行:

kwargs.update(dtype=kwargs.get('update', None),

这样:

kwargs.update(dtype=kwargs.get('dtype', None),

然后,它为我的作品没有问题为长整型(我没有检查的日期时间正确性乔在他的回答中写道)。你可能会注意到你的日期也没有被转换。这是可用的特定代码。 “test.csv”的内容是从你的示例csv数据复制粘贴的。

import numpy as np 
d = [('date',  np.datetime64), 
    ('open',  np.float64), 
    ('high',  np.float64), 
    ('low',  np.float64), 
    ('close',  np.float64), 
    ('volume', np.int64), 
    ('adj_close', np.float64)] 
a = np.recfromcsv("test.csv", dtype=d) 
print(a) 

[ (datetime.datetime(1969, 12, 31, 23, 59, 59, 999999), 1329.19, 1343.32, 1329.19, 1342.84, 4401570000, 1342.84) 
(datetime.datetime(1969, 12, 31, 23, 59, 59, 999999), 1314.88, 1333.68, 1314.14, 1329.1, 3687720000, 1329.1) 
(datetime.datetime(1969, 12, 31, 23, 59, 59, 999999), 1324.02, 1327.28, 1310.51, 1314.88, 3506510000, 1314.88)] 

更新:如果你不想修改numpy的,只需要用相应numpy的代码recfromcsv

我还通过在日期时间使用本机Python对象的“固定”的日期时间问题领域。我不知道这是否会对你有用。

import datetime 
import numpy as np 

d = [('date',  datetime.datetime), 
    ('open',  np.float64), 
    ('high',  np.float64), 
    ('low',  np.float64), 
    ('close',  np.float64), 
    ('volume', np.int64), 
    ('adj_close', np.float64)] 

#a = np.recfromcsv("test.csv", dtype=d) 
kwargs = {"dtype": d} 
case_sensitive = kwargs.get('case_sensitive', "lower") or "lower" 
names = kwargs.get('names', True) 
kwargs.update(
    delimiter=kwargs.get('delimiter', ",") or ",", 
    names=names, 
    case_sensitive=case_sensitive) 
output = np.genfromtxt("test.csv", **kwargs) 
output = output.view(np.recarray) 

print(output) 
+0

我认为你对错误是正确的,但是你的问题更可能在github上受到关注(他们正在摆脱旧的bug跟踪器)。 –

+0

@JoeKington感谢您的回复和建议。我会仔细看看的。 – KobeJohn

+0

在附注上,我不确定为什么日期时间没有正确转换,但是使用这种方法它们不正确。 'np.datetime64('2012-06-15')'完美地工作,但它不能作为dtype的一部分工作...(这似乎是一个已修复的错误,尽管...似乎工作正常当我从Git的提示建立?) –

1

您需要将日期字符串转换为实际日期。在D类的格式被忽略,因为第一列不能直接转换为datetime。

numpy希望你是相当明确的,并拒绝猜测日期格式。

(编辑:这曾经是如此,但已不再)

该公司预计datetime对象。见dateutil.parser如果你想从字符串猜测的日期/时间格式。

在任何情况下,你会希望类似如下:

from cStringIO import StringIO 
import datetime as dt 
import numpy as np 

dat = """Date,Open,High,Low,Close,Volume,Adj Close 
2012-06-15,1329.19,1343.32,1329.19,1342.84,4401570000,1342.84 
2012-06-14,1314.88,1333.68,1314.14,1329.10,3687720000,1329.10 
2012-06-13,1324.02,1327.28,1310.51,1314.88,3506510000,1314.88""" 
infile = StringIO(dat) 

d = [('date',  np.datetime64), 
    ('open',  np.float64), 
    ('high',  np.float64), 
    ('low',  np.float64), 
    ('close',  np.float64), 
    ('volume', np.int64), 
    ('adj_close', np.float64)] 


def parse_date(item): 
    return dt.datetime.strptime(item, '%Y-%M-%d') 

data = np.recfromcsv(infile, converters={0:parse_date}, dtype=d) 

然而,像这样的事情在哪里pandas眼前一亮。考虑使用类似以下内容:

from cStringIO import StringIO 
import pandas 

dat = """Date,Open,High,Low,Close,Volume,Adj Close 
2012-06-15,1329.19,1343.32,1329.19,1342.84,4401570000,1342.84 
2012-06-14,1314.88,1333.68,1314.14,1329.10,3687720000,1329.10 
2012-06-13,1324.02,1327.28,1310.51,1314.88,3506510000,1314.88""" 

infile = StringIO(dat) 
data = pandas.read_csv(infile, index_col=0, parse_dates=True) 
+1

你能检查我的答案吗?如果我提出了一个似是而非的错误,我想删除它。我似乎得到了一个工作日期时间,无论它做了什么假设。 – KobeJohn