【问题标题】:How to sort a structured list of stock data for later access in Python?如何对结构化的股票数据列表进行排序以供以后在 Python 中访问?
【发布时间】:2011-06-16 21:35:52
【问题描述】:

我对 Python 非常陌生,想构建一个黑匣子股票交易程序,它可以找到股票收益率之间的各种相关性,并给我一个响应,例如买入、卖出、持有等。我发现一个简洁的有点容易使用 Python 模块检索名为 ystockquote 的股票数据,该模块从 Yahoo!金融。该模块可以在http://www.goldb.org/ystockquote.html找到。

它的一项功能是以['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Clos'] 的形式输出股票的历史价格。我可以给它一个日期范围来执行此操作,它给我一个嵌套列表,其中包含一个列表,其中包含每天的上述信息。

我的问题是如何将这些单独的数据点(日期、开盘价、高点、低点等)组织成一个结构,以便稍后在我的脚本中调用并进行排序。我需要这个过程易于自动化。什么样的算法或数据结构可能对我有用?

【问题讨论】:

  • 在python中对列表或字典进行排序很容易。但是你必须更具体,这样我们才能更具体。您不是在问如何对列表进行排序,是吗?
  • 你需要自己写一个cmp函数,它是sort函数中的一个可选参数,你可以看看help([].sort)
  • 对不起,我对此很陌生,所以在我最近编辑它之前,我认为这一切都需要自动化。为了澄清我需要从 ystockquote 模块获取输出数据并自动将其分类到类似配置的字典中的代码或方法,以便我可以每天调用每个值(例如特定日期的收盘价)并接收纯数字响应。因此,如果在 2011 年 5 月 1 日,当我致电时,一只股票的价格为 20.87 美元,我可以获得 20.87 美元作为回应。
  • 很好的说明,但我认为您可以自己弄清楚如何做。我已经完成了 99% 的工作……见下文。

标签: python list dictionary stocks yahoo-api


【解决方案1】:

您可能正在寻找dictionary 结构而不是列表:

>>> prices = dict()
>>> prices['2011-01-02'] = {'Open':20.00, 'High':30.00, 'Low':10.00, 'Close':21.00, 'Volume':14.00, 'Adj Clos':120}
>>> prices['2010-11-09'] = {'Open':22.00, 'High':50.00, 'Low':20.00, 'Close':42.00, 'Volume':10.00, 'Adj Clos':666}
>>> prices
{'2011-01-02': {'Volume': 14.0, 'Adj Clos': 120, 'High': 30.0, 'Low': 10.0, 'Close': 21.0, 'Open': 20.0}, '2010-11-09': {'Volume': 10.0, 'Adj Clos': 666, 'High': 50.0, 'Low': 20.0, 'Close': 42.0, 'Open': 22.0}}

在这里,我在主“价格”字典的每个条目中嵌套了一个字典。字典的第一级以日期为键,并映射到包含该日期价格信息的字典。

>>> prices['2011-01-02']
{'Volume': 14.0, 'Adj Clos': 120, 'High': 30.0, 'Low': 10.0, 'Close': 21.0, 'Open': 20.0}

第二层字典以属性名作为键,映射到属性值本身。

>>> prices['2010-11-09']['Open']
22.0
>>> prices['2010-11-09']['Close']
42.0

看来,对于您引用的get_historical_prices 函数,每天都以[Date, Open, High, Low, Close, Volume, Adj_Clos] 形式的条目输出。如果你想为这些条目的列表构建一个字典,你需要做三件事:

首先,您需要索引每个条目以将Date 与其他元素分开,因为您将使用它来索引dict 的第一个维度。您可以使用entry[0] 获取第一个元素,使用entry[1:] 获取其余元素。

>>> entry = ['2011-01-02', 20.00, 30.00, 10.00, 21.00, 14.00, 120]
>>> date = entry[0]
>>> date
'2011-01-02'
>>> values = entry[1:]
>>> values
[20.0, 30.0, 10.0, 21.0, 14.0, 120]

其次,由于您希望将其他每个元素与特定键相关联,因此您应该按照与数据元素提供给您的顺序相同的顺序列出这些键。使用zip() 函数,您可以组合两个列表pq,从每个列表中获取第i 个元素并生成zip(p,q)[i] == (p[i], q[i])。通过这种方式,您可以创建一个 (key, value) 对列表,您可以将其传递给字典构造函数:

>>> keys = ['Open', 'High', 'Low', 'Close', 'Volume', 'Adj Clos']
>>> pairs = zip(keys, entry[1:])
>>> pairs
[('Open', 20.0), ('High', 30.0), ('Low', 10.0), ('Close', 21.0), ('Volume', 14.0), ('Adj Clos', 120)]

最后你想构建你的字典,并将它索引到它在整个历史中的适当日期:

>>> stockdict = dict(pairs)
>>> stockdict
{'Volume': 14.0, 'Adj Clos': 120, 'High': 30.0, 'Low': 10.0, 'Close': 21.0, 'Open': 20.0}
>>> histodict = dict()
>>> histodict[date] = stockdict

您可以通过两种方式遍历嵌套的history 列表来构造您的字典,第一种是使用传统的for 循环:

keys = ['Open', 'High', 'Low', 'Close', 'Volume', 'Adj Clos']
histodict = dict()
for item in history:
    date = item[0]
    values = item[1:]
    histodict[date] = dict(zip(keys, values))

或者,如果您想使用更高级的 Python 技术,请尝试嵌套字典 generator statement

keys = ['Open', 'High', 'Low', 'Close', 'Volume', 'Adj Clos']
histodict = dict((item[0], dict(zip(keys, item[1:]))) for item in history)

如果您是编程新手,那最后一个会很麻烦,但我鼓励您阅读该链接;请记住,使用 Python 编程时,Google 是您的朋友。我希望我在这里给了你足够的关键词和想法来开始学习,剩下的就交给你了。

【讨论】:

  • 这正是我所需要的,但我如何使用来自 ystockquote 的输出数据自动执行它,这样我就不必为每个日期手动配置条目?
  • 经过一番修改后,我想出了如何以我想要的方式使用这段代码。非常感谢!你是一个巨大的帮助,你为我的学习做出了巨大的贡献。
【解决方案2】:

给定一个长度相等的列表,很容易按任何“列”排序:

>>> l = [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1], [0, 0, 0, 0, 0], [6, 6, 6, 6, 6]]
>>> l.sort(key=lambda l: l[1])
>>> l
[[0, 0, 0, 0, 0], [1, 2, 3, 4, 5], [5, 4, 3, 2, 1], [6, 6, 6, 6, 6]]
>>> l.sort(key=lambda l: l[4])
>>> l
[[0, 0, 0, 0, 0], [5, 4, 3, 2, 1], [1, 2, 3, 4, 5], [6, 6, 6, 6, 6]]

key 关键字参数采用一个函数,该函数给定列表中的一个项目,返回一个用作排序键的值。

但如果你想做更多有趣的事情,你最好使用数据库。为方便起见(对我而言),sqlite3 文档以股票表为例,我已对其进行了适当的修改和修改:

import sqlite3
conn = sqlite3.connect('/tmp/example')   # use ':memory:' for an in-memory db
c = conn.cursor()

# Create table
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')

# Insert a row of data
c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)""")

# Save (commit) the changes
conn.commit()

# Insert another row of data
c.execute("""insert into stocks
          values ('2006-01-07','SELL','RHAT',100,2.11)""")

# Select rows of data from table in an order
rows_by_date = c.execute("""select * from stocks order by date""")
for row in rows_by_date:
    print row

# In a different order
rows_by_price = c.execute("""select * from stocks order by price""")
for row in rows_by_price:
    print row

【讨论】:

  • 有一个 step-by-step 由 Michael Halls-Moore 编写的关于如何使用 MySQL 设置证券主数据库的教程,PandasSQLAlchemy。我发现它非常清晰和简单。
猜你喜欢
  • 2022-10-18
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
  • 2014-11-25
  • 1970-01-01
相关资源
最近更新 更多