如何使用python处理传入的实时数据
哪一种是处理熊猫实时传入数据的最受推荐/最适合的方式 每隔几秒钟,我就会收到以下格式的数据点:如何使用python处理传入的实时数据,python,pandas,Python,Pandas,哪一种是处理熊猫实时传入数据的最受推荐/最适合的方式 每隔几秒钟,我就会收到以下格式的数据点: {'time' :'2013-01-01 00:00:00', 'stock' : 'BLAH', 'high' : 4.0, 'low' : 3.0, 'open' : 2.0, 'close' : 1.0} 我想将其附加到现有的数据帧中,然后对其运行一些分析 问题是,仅使用DataFrame.append追加行可能会导致所有复制的性能问题 我尝试过的事情: 一些人建议预先分配一个大数据框,并在
{'time' :'2013-01-01 00:00:00', 'stock' : 'BLAH',
'high' : 4.0, 'low' : 3.0, 'open' : 2.0, 'close' : 1.0}
我想将其附加到现有的数据帧中,然后对其运行一些分析
问题是,仅使用DataFrame.append追加行可能会导致所有复制的性能问题
我尝试过的事情:
一些人建议预先分配一个大数据框,并在数据进来时更新它:
In [1]: index = pd.DatetimeIndex(start='2013-01-01 00:00:00', freq='S', periods=5)
In [2]: columns = ['high', 'low', 'open', 'close']
In [3]: df = pd.DataFrame(index=t, columns=columns)
In [4]: df
Out[4]:
high low open close
2013-01-01 00:00:00 NaN NaN NaN NaN
2013-01-01 00:00:01 NaN NaN NaN NaN
2013-01-01 00:00:02 NaN NaN NaN NaN
2013-01-01 00:00:03 NaN NaN NaN NaN
2013-01-01 00:00:04 NaN NaN NaN NaN
In [5]: data = {'time' :'2013-01-01 00:00:02', 'stock' : 'BLAH', 'high' : 4.0, 'low' : 3.0, 'open' : 2.0, 'close' : 1.0}
In [6]: data_ = pd.Series(data)
In [7]: df.loc[data['time']] = data_
In [8]: df
Out[8]:
high low open close
2013-01-01 00:00:00 NaN NaN NaN NaN
2013-01-01 00:00:01 NaN NaN NaN NaN
2013-01-01 00:00:02 4 3 2 1
2013-01-01 00:00:03 NaN NaN NaN NaN
2013-01-01 00:00:04 NaN NaN NaN NaN
另一种选择是建立一个目录列表。只需将传入的数据附加到一个列表中,并将其分割成更小的数据帧即可完成这项工作
In [9]: ls = []
In [10]: for n in range(5):
.....: # Naive stuff ahead =)
.....: time = '2013-01-01 00:00:0' + str(n)
.....: d = {'time' : time, 'stock' : 'BLAH', 'high' : np.random.rand()*10, 'low' : np.random.rand()*10, 'open' : np.random.rand()*10, 'close' : np.random.rand()*10}
.....: ls.append(d)
In [11]: df = pd.DataFrame(ls[1:3]).set_index('time')
In [12]: df
Out[12]:
close high low open stock
time
2013-01-01 00:00:01 3.270078 1.008289 7.486118 2.180683 BLAH
2013-01-01 00:00:02 3.883586 2.215645 0.051799 2.310823 BLAH
或者诸如此类的事情,可能需要对输入进行多一点处理。实际上,您正试图解决两个问题:捕获实时数据和分析数据。第一个问题可以用解决,它就是为此而设计的。然后,另一个问题可以通过读取相同的日志文件来解决。我将使用HDF5/pytables,如下所示:
- 使用pandas io(和可追加的表)推送到HDF5存储区
- 清除列表
我们定义了一个函数,您可以在每行
d
中调用该函数:
CACHE = {}
STORE = 'store.h5' # Note: another option is to keep the actual file open
def process_row(d, key, max_len=5000, _cache=CACHE):
"""
Append row d to the store 'key'.
When the number of items in the key's cache reaches max_len,
append the list of rows to the HDF5 store and clear the list.
"""
# keep the rows for each key separate.
lst = _cache.setdefault(key, [])
if len(lst) >= max_len:
store_and_clear(lst, key)
lst.append(d)
def store_and_clear(lst, key):
"""
Convert key's cache list to a DataFrame and append that to HDF5.
"""
df = pd.DataFrame(lst)
with pd.HDFStore(STORE) as store:
store.append(key, df)
lst.clear()
注意:我们使用with语句在每次写入后自动关闭存储。它保持开放的速度可能会更快,但如果是这样的话。还请注意,使用列表可能比使用列表更具可读性,但此处列表的性能会稍好一些
要使用此选项,请将其称为:
process_row({'time' :'2013-01-01 00:00:00', 'stock' : 'BLAH', 'high' : 4.0, 'low' : 3.0, 'open' : 2.0, 'close' : 1.0},
key="df")
注:“df”是pytables存储中使用的存储
作业完成后,确保存储并清除剩余的缓存:
for k, lst in CACHE.items(): # you can instead use .iteritems() in python 2
store_and_clear(lst, k)
现在,您可以通过以下方式获得完整的数据帧:
with pd.HDFStore(STORE) as store:
df = store["df"] # other keys will be store[key]
一些评论:
- 5000可以调整,尝试使用较小/较大的数字以满足您的需要
- ,数据帧追加为O(
)len(df)
- 在你进行统计或数据搜索之前,你不需要熊猫,使用最快的
- 此代码适用于多个输入的键(数据点)
- 这是非常少的代码,我们将停留在香草python列表中,然后是熊猫数据帧
此外,要获取最新的读取,可以定义一个get方法,该方法在读取之前存储并清除。通过这种方式,您将获得最新的数据:
def get_latest(key, _cache=CACHE):
store_and_clear(_cache[key], key)
with pd.HDFStore(STORE) as store:
return store[key]
现在,当您通过以下方式访问:
df = get_latest("df")
您将获得可用的最新“df”
另一个选项稍微复杂一些:在表中定义自定义表,请参阅
注意:您需要知道字段名才能创建数据。这在很大程度上取决于您将对数据执行的操作,例如,您是否需要整个系列的框架。另一个选项是附加到
HDFStore
;然后选择您需要的(您已经同步了读/写操作),预分配的数据帧应该可以工作。快速检查df的内存使用情况。。。1000000个数据点=大约50年的第二次数据(假设工作日和10小时交易日)。因此,大约5年的时间和1000只股票将使用大约1G内存。这取决于是否可以接受的应用程序和资源限制。将对此发表评论“问题是,仅使用DataFrame.append附加行可能会导致所有复制操作的性能问题”。您是否尝试将所需字段转换为“元组”,然后将其附加到DataFrame。如果您在这方面需要帮助,请告诉我。正如其他人所提到的,除非您需要立即采取实时行动(如果您使用python并且仅接收OHLC数据,并且仅每隔几秒钟接收一次,则我怀疑情况是否如此),将过程分为两个阶段:1.数据检索/存储和2.数据处理将使生活变得更加轻松。我有一个脚本,每秒接收数百个OHLC条;首先将它们保存到DICT列表中,然后定期将其附加到HDFStore中,这对我来说很有效-我相信它可以进一步优化,但已经有所改进CPU使用率比将每行添加到df或存储中要高出许多倍。Matthew RocklinI刚刚启动了一个新项目。我真的不明白为什么日志记录可以帮助捕获时间序列数据?你的意思是将时间序列存储为字符串,然后解析字符串吗?那么我们为什么需要日志记录?我们不应该将它们转换为适当的d吗ata结构?日志记录专门设计用于帮助捕获时间序列数据。它将为您处理所有缓冲和文件管理。Pandas设计用于高效读取大型数据文件。同时,它们可以解决您的数据管理问题。此外,您有一份数据副本,因此可以仔细检查您的work稍后。这里有一篇相关帖子:如果你关心数据,那么是的,使用日志记录来构建一个非常健壮的系统,确保所有内容都被保存。然后单独使用一个分析应用程序,每隔一段时间读取一次分块日志,并将分块添加到数据框中。如果你不关心数据,并且总是可以启动ov呃,然后将传入的数据聚合成块,一次追加100或1000行。如果您确实需要尽快追加行,则至少追加1000个空行以分配内存,然后手动插入数据,就好像您只有numpy数组一样。有人能解释一下Python日志解决方案的相对优缺点吗关于另一个答案中给出的HDF5/PyTables解决方案,后者似乎更适用于在线分析,因为它具有奇特的索引功能。谢谢。由于实时数据通常很大,并且大小不断增加,因此,相同的