3

我正在从雅虎下载标准普尔 500 指数的股票价格,该指数的交易量对于 32 位整数来说太大了。

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

如果我将 dtype 声明为使用 int64,为什么我仍然会收到此错误?这是否表明 io 函数并没有真正使用我的 dtype 序列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
4

2 回答 2

3

我不确定,但我认为你在 numpy.xml 中发现了一个错误。我在这里归档。

正如我在那里所说,如果您打开 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

我还通过在 datetime 字段中使用本机 python 对象“修复”了 datetime 问题。我不知道这是否对你有用。

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)
于 2012-06-16T17:28:37.857 回答
1

您需要将日期字符串转换为实际日期。您的 dtype 中的格式将被忽略,因为第一列无法直接转换为日期时间。

numpy期望您相当明确并且拒绝猜测日期格式。

(编辑:以前是这样,但现在不是了。)

它需要日期时间对象。看看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)
于 2012-06-16T17:23:29.383 回答