Python 弹性搜索滚动(扫描)到数据帧
我需要从Python 弹性搜索滚动(扫描)到数据帧,python,pandas,dataframe,
elasticsearch,generator,Python,Pandas,Dataframe,
elasticsearch,Generator,我需要从Elasticsearch(es)中获取大量数据,因此我正在使用scan命令,这是本机esscroll命令的总结。 因此,我将获得以下生成器对象:。此外,我还想将所有数据插入到PandasDataFrame对象中,以便轻松处理它 代码如下: from elasticsearch import Elasticsearch from elasticsearch.helpers import scan as escan import pandas as pd es = Elasticsear
Elasticsearch
(es)中获取大量数据,因此我正在使用scan
命令,这是本机esscroll
命令的总结。
因此,我将获得以下生成器对象:
。此外,我还想将所有数据插入到Pandas
DataFrame
对象中,以便轻松处理它
代码如下:
from elasticsearch import Elasticsearch
from elasticsearch.helpers import scan as escan
import pandas as pd
es = Elasticsearch(dpl_server, verify_certs=False)
body = {
"size": 1000,
"query": {
"match_all": {}
}
}
response = escan(client=es,
index="index-*,
query=body, request_timeout=30, size=1000)
print(response)
#<generator object scan at 0x000001BF5A25E518>
for res in response:
print(res['_source'])
# { .... }
# { .... }
# { .... }
我会买很多字典。到目前为止,我的一个简单解决方案是将它们逐个相加,如下所示:
df = None
for res in response:
if (df is None):
df = pd.DataFrame([res['_source']])
else:
df = pd.concat([df, pd.DataFrame([res['_source']])], sort=True)
我想知道是否有更好的方法(第一,在速度方面,第二,在干净的代码方面)。例如,将生成器的所有结果累加到一个列表中,然后构建一个完整的
数据帧是否更好?您可以使用panda的json\u normalize
from pandas.io.json import json_normalize
from elasticsearch import Elasticsearch
from elasticsearch.helpers import scan as escan
import pandas as pd
es = Elasticsearch(dpl_server, verify_certs=False)
body = {
"size": 1000,
"query": {
"match_all": {}
}
}
response = escan(client=es,
index="index",
query=body, request_timeout=30, size=1000)
# Initialize a double ended queue
output_all = deque()
# Extend deque with iterator
output_all.extend(response)
# Convert deque to DataFrame
output_df = json_normalize(output_all)
您可以找到有关双端队列的更多信息。这是一个很好的答案!但这给我提出了一些问题。我们为什么选择deque()?是否有更好(更快)的数据结构?此外,我想添加res[''u source'](对于每次“命中”,我想在''u source'下添加对象),而不是整个响应对象。@EranMoshe deque()只允许更快地追加/扩展。为了只选择属于_source的字段,我有一个小函数,它只选择以“_source.”开头的列,在output_df=output_df[[x代表x在output_df.columns如果“_source.”在x]]的行中,如果你有更好的解决方案,多处理或多线程或类似的,请告诉我!如果我开发一个,我也会这样做。我尝试了你的解决方案和答案解决方案,但在这两种情况下,我都被困在一个无限循环中,我无法打破for循环,因为我知道我的响应中只有很少的元素(大约500个)。有什么线索吗?