Создание DataFrame из результатов ElasticSearch

Я пытаюсь создать DataFrame в пандах, используя результаты очень простого запроса к ElasticSearch. Я получаю данные, которые мне нужны, но это вопрос обрезания результатов способом построения правильного фрейма данных. Я действительно забочусь только о том, чтобы получить метку времени и путь каждого результата. Я попробовал несколько разных шаблонов es.search.

Код:

from datetime import datetime from elasticsearch import Elasticsearch from pandas import DataFrame, Series import pandas as pd import matplotlib.pyplot as plt es = Elasticsearch(host="192.168.121.252") res = es.search(index="_all", doc_type='logs', body={"query": {"match_all": {}}}, size=2, fields=('path','@timestamp')) 

Это дает 4 куска данных. [u'hits ', u'_shards', u'took ', u'timed_out']. Мои результаты попадают в хиты.

 res['hits']['hits'] Out[47]: [{u'_id': u'a1XHMhdHQB2uV7oq6dUldg', u'_index': u'logstash-2014.08.07', u'_score': 1.0, u'_type': u'logs', u'fields': {u'@timestamp': u'2014-08-07T12:36:00.086Z', u'path': u'app2.log'}}, {u'_id': u'TcBvro_1QMqF4ORC-XlAPQ', u'_index': u'logstash-2014.08.07', u'_score': 1.0, u'_type': u'logs', u'fields': {u'@timestamp': u'2014-08-07T12:36:00.200Z', u'path': u'app1.log'}}] 

Единственное, что меня волнует, – это получить метку времени и путь для каждого удара.

 res['hits']['hits'][0]['fields'] Out[48]: {u'@timestamp': u'2014-08-07T12:36:00.086Z', u'path': u'app1.log'} 

Я не могу, чтобы жизнь меня определяла, кто получит этот результат, в кадр данных в пандах. Таким образом, для двух результатов, которые я вернул, я ожидал бы, например, dataframe.

  timestamp path 0 2014-08-07T12:36:00.086Z app1.log 1 2014-08-07T12:36:00.200Z app2.log 

  • Переплетение двух данных
  • pandas создает новый столбец на основе значений из других столбцов
  • pandas сводная таблица продаж
  • python pandas: применить функцию с аргументами к ряду. Обновить
  • Приведение модели ARMA к временным рядам, индексированным по времени в python
  • pandas / matplotlib: фанерные заготовки
  • Pandas: выберите строки DF на основе другого DF
  • Как найти 5-минутные пробелы в кадре данных Pandas?
  • 4 Solutions collect form web for “Создание DataFrame из результатов ElasticSearch”

    Есть хорошая игрушка под названием pd.DataFrame.from_dict которую вы можете использовать в такой ситуации:

     In [34]: Data = [{u'_id': u'a1XHMhdHQB2uV7oq6dUldg', u'_index': u'logstash-2014.08.07', u'_score': 1.0, u'_type': u'logs', u'fields': {u'@timestamp': u'2014-08-07T12:36:00.086Z', u'path': u'app2.log'}}, {u'_id': u'TcBvro_1QMqF4ORC-XlAPQ', u'_index': u'logstash-2014.08.07', u'_score': 1.0, u'_type': u'logs', u'fields': {u'@timestamp': u'2014-08-07T12:36:00.200Z', u'path': u'app1.log'}}] In [35]: df = pd.concat(map(pd.DataFrame.from_dict, Data), axis=1)['fields'].T In [36]: print df.reset_index(drop=True) @timestamp path 0 2014-08-07T12:36:00.086Z app2.log 1 2014-08-07T12:36:00.200Z app1.log 

    Покажите это в четыре этапа:

    1, Прочитайте каждый элемент в списке (который является dictionary ) в DataFrame

    2, мы можем поместить все элементы в список в большой DataFrame их по ряду строк, так как мы сделаем шаг № 1 для каждого элемента, мы можем использовать map чтобы сделать это.

    3, Затем мы обращаемся к столбцам, помеченным как 'fields'

    4, мы, вероятно, хотим повернуть DataFrame 90 градусов (транспонировать) и reset_index если хотим, чтобы индекс был стандартной последовательностью по умолчанию.

    введите описание изображения здесь

    Или вы можете использовать функцию json_normalize для pandas:

     from pandas.io.json import json_normalize df = json_normalize(res['hits']['hits']) 

    И затем фильтрация результирующего фрейма по именам столбцов

    Вот немного кода, который может оказаться полезным для вашей работы. Он прост и расширяем, но сэкономил мне много времени, когда вы столкнулись с «захватом» некоторых данных из ElasticSearch для анализа.

    Если вы просто хотите захватить все данные данного индекса и doc_type вашего localhost, вы можете сделать:

     df = ElasticCom(index='index', doc_type='doc_type').search_and_export_to_df() 

    Вы можете использовать любой из аргументов, которые вы обычно использовали в elasticsearch.search (), или указать другой хост. Вы также можете выбрать, включать ли _id или нет, и указать, находятся ли данные в '_source' или 'fields' (он пытается угадать). Он также пытается преобразовать значения полей по умолчанию (но вы можете отключить это).

    Вот код:

     from elasticsearch import Elasticsearch import pandas as pd class ElasticCom(object): def __init__(self, index, doc_type, hosts='localhost:9200', **kwargs): self.index = index self.doc_type = doc_type self.es = Elasticsearch(hosts=hosts, **kwargs) def search_and_export_to_dict(self, *args, **kwargs): _id = kwargs.pop('_id', True) data_key = kwargs.pop('data_key', kwargs.get('fields')) or '_source' kwargs = dict({'index': self.index, 'doc_type': self.doc_type}, **kwargs) if kwargs.get('size', None) is None: kwargs['size'] = 1 t = self.es.search(*args, **kwargs) kwargs['size'] = t['hits']['total'] return get_search_hits(self.es.search(*args, **kwargs), _id=_id, data_key=data_key) def search_and_export_to_df(self, *args, **kwargs): convert_numeric = kwargs.pop('convert_numeric', True) convert_dates = kwargs.pop('convert_dates', 'coerce') df = pd.DataFrame(self.search_and_export_to_dict(*args, **kwargs)) if convert_numeric: df = df.convert_objects(convert_numeric=convert_numeric, copy=True) if convert_dates: df = df.convert_objects(convert_dates=convert_dates, copy=True) return df def get_search_hits(es_response, _id=True, data_key=None): response_hits = es_response['hits']['hits'] if len(response_hits) > 0: if data_key is None: for hit in response_hits: if '_source' in hit.keys(): data_key = '_source' break elif 'fields' in hit.keys(): data_key = 'fields' break if data_key is None: raise ValueError("Neither _source nor fields were in response hits") if _id is False: return [x.get(data_key, None) for x in response_hits] else: return [dict(_id=x['_id'], **x.get(data_key, {})) for x in response_hits] else: return [] 

    Еще лучше, вы можете использовать фантастическую библиотеку pandasticsearch :

     from elasticsearch import Elasticsearch es = Elasticsearch('http://localhost:9200') result_dict = es.search(index="recruit", body={"query": {"match_all": {}}}) from pandasticsearch import Select pandas_df = Select.from_dict(result_dict).to_pandas() 
    Python - лучший язык программирования в мире.