如何有效地为SecurityID列中的每个唯一值找到最后一个时间戳(来自Datetime列)? SecurityID列中大约有1000个唯一值。
目前我在整个表中查询SecurityID中的每个唯一值,然后查找最后一个时间戳。你可以想象它的速度极慢。该表超过40GB并且在不断增长。
我这样做:
os.chdir('E:\HDFStores')
store = pd.HDFStore('mysuperawesomehdfstore.h5')
assets = skBase.bbg_helper_assets('minutely')
df_timestamp = pd.Dataframe()
tags = ['T', 'B', 'A']
for asset in assets:
for tag in tags:
print asset, " ", tag
timestamp = (store.select('table', where = "SecurityID = ['" + asset + "'] & Tag = ['" + tag + "'] & columns = ['Datetime']")).tail(1)
if len(timestamp_.index) == 0:
print "value DNE"
else:
dt = (str(timestamp_iloc[0][0])).split(' ', 1)[0]
tm = (str(timestamp_iloc[0][0])).split(' ', 1)[1]
我曾考虑在我的4核机器中运行单独的python进程。但我宁愿采取更清洁的做事方式而不是诉诸黑客。
任何想法都会受到赞赏。
答案 0 :(得分:2)
由于您的数据库非常庞大,您必须从硬盘中查询它并遇到IO瓶颈。
这实际上是这里的主要问题。智能代码无法真正弥补必须查询40gb文件 - 特别是考虑到您的查询非常简单。多处理也无济于事(它不是CPU瓶颈)。所以我认为解决方案会更新您的工作流程。
所有解决方案都依赖于异步操作(首先处理所有数据,将其转储到单独的文件,根据需要从该文件读取),或者重新组织存储数据的方式。
如果您每天更新主HDF5文件的频率低于每日,您可以简单地:
更新主HDF5后,查询所有securityID的最新时间戳(包含现有代码)。将结果转储到单独的H5文件中(仅索引:SecurityID,值:最新时间戳)。当然,这个解决方案只有在每个查询花费不到30秒(这已经花了将近半天......)时才有效。
然后,您可以将此数据保存在内存中(应该只有几Kbs),并在您需要知道特定SecurityID的最新时间戳时随时访问它。
更智能的方式(但更多工作)是在收到更新数据时读取最后一个时间戳。我不确切知道你如何更新你的HDF5文件,但我想你正在下载新数据,并将其附加到当前文件。
在这种情况下,这将是获取最新时间戳数据的正确时机。您的工作流程将变为:
如果上述解决方案都不可行,那么您可以将每个SecurityID存储为h5文件中的单独节点。所以你要做的事情是:
store.select(asset, where = Tag = ['" + tag + "'] & columns ['Datetime']")).tail(1)
调整其余代码(以及重新组织数据库的前期工作)可能需要做更多工作,但这应该会显着缩短查询时间,并且长期有用。我没有看到任何有理由将所有SecurityID捆绑在一个巨大的节点中。而且它比其他解决方案更不那么骇人听闻了: - )