Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 弹性搜索滚动(扫描)到数据帧_Python_Pandas_Dataframe_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Generator - Fatal编程技术网 elasticsearch,generator,Python,Pandas,Dataframe,elasticsearch,Generator" /> elasticsearch,generator,Python,Pandas,Dataframe,elasticsearch,Generator" />

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
命令,这是本机es
scroll
命令的总结。 因此,我将获得以下生成器对象:
。此外,我还想将所有数据插入到
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个)。有什么线索吗?