Извлечение необходимых переменных из файла журнала событий с использованием Python

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

образец первой строки файла журнала событий, здесь я успешно извлек все, кроме последней пары значений ключа, которая является атрибутом-

{"event_type":"ActionClicked","event_timestamp":1451583172592,"arrival_timestamp":1451608731845,"event_version":"3.0",
  "application":{"app_id":"7ffa58dab3c646cea642e961ff8a8070","cognito_identity_pool_id":"us-east-1:
    4d9cf803-0487-44ec-be27-1e160d15df74","package_name":"com.think.vito","sdk":{"name":"aws-sdk-android","version":"2.2.2"}
    ,"title":"Vito","version_name":"1.0.2.1","version_code":"3"},"client":{"client_id":"438b152e-5b7c-4e99-9216-831fc15b0c07",
      "cognito_id":"us-east-1:448efb89-f382-4975-a1a1-dd8a79e1dd0c"},"device":{"locale":{"code":"en_GB","country":"GB",
        "language":"en"},"make":"samsung","model":"GT-S5312","platform":{"name":"ANDROID","version":"4.1.2"}},
  "session":{"session_id":"c15b0c07-20151231-173052586","start_timestamp":1451583052586},"attributes":{"OfferID":"20186",
    "Category":"40000","CustomerID":"304"},"metrics":{}}

Всем привет, я пытаюсь извлечь содержимое из файла журнала событий, как показано на прикрепленном изображении. Что касается требования, я должен получить customer ID, offer id, category, это важные переменные, которые мне нужно извлечь из этого файла журнала событий. это файл в формате csv. я пробовал с регулярным выражением, но оно не работает, потому что вы можете наблюдать, что формат каждого столбца отличается. Как вы видите, первая строка имеет category customer id offer id, а вторая строка полностью пуста, в этом случае регулярное выражение не будет работать, кроме этого, мы должны учитывать, что мы должны учитывать все возможные условия, у нас есть 14000 Sample.in файл журнала событий ... # Джейсон # Разбор #Python #Pandas


person Nabi Shaikh    schedule 10.07.2016    source источник
comment
Это обычный текстовый файл? Каждая строка начинается и заканчивается на {}? Если это так, похоже, вы можете прочитать файл построчно и использовать literal_eval, чтобы превратить каждую строку в объект Python dict.   -  person DeepSpace    schedule 10.07.2016
comment
Можете ли вы предоставить фактическую часть вашего журнала данных вместо формата изображения? Вы же не ожидаете, что мы будем вводить ваши данные один за другим, верно?   -  person MaThMaX    schedule 10.07.2016
comment
да, это было в формате txt раньше. это был огромный файл, который я извлек из приведенной ниже переменной из файла журнала событий.   -  person Nabi Shaikh    schedule 10.07.2016
comment
Почему на изображении одинарные кавычки, а в тексте двойные? (Последний может быть в формате JSON.)   -  person ayhan    schedule 10.07.2016
comment
Файл изображения @ayhan находится в формате csv, а в текстовой форме - в формате .txt ... после извлечения из файла .txt я разделил каждый ключ на отдельный файл csv.   -  person Nabi Shaikh    schedule 10.07.2016
comment
могу ли я просто извлечь только значение, относящееся к одному ключу, и создать столбец только для этого ключа, но проблема здесь в том, что некоторые строки могут иметь этот ключ, а некоторые строки могут не иметь ... в этом случае это сложно .. @DeepSpace   -  person Nabi Shaikh    schedule 10.07.2016


Ответы (2)


Это может быть не самый эффективный способ преобразования вложенных записей json в текстовом файле (с разделителями строк) в объект DataFrame, но он выполняет свою работу.

import pandas as pd
import json
from pandas.io.json import json_normalize

with open('path_to_your_text_file.txt', 'rb') as f:
    data = f.readlines()

data = map(lambda x: eval(json_normalize(json.loads(x.rstrip())).to_json(orient="records")[1:-1]), data)
e = pd.DataFrame(data)
print e.head()
person Mohammad Yusuf    schedule 11.07.2016

Изменить

Данные после вашего редактирования теперь выглядят как данные JSON. Вы по-прежнему можете использовать literal_eval, как показано ниже, или использовать json модуль:

import json

with open('event.log') as events:
    for line in events:
        event = json.loads(line)
        # process event dictionary

Чтобы получить доступ к CustomerID, OfferID, Category и т. д., вам необходимо получить доступ к вложенному словарю, связанному с ключом 'attributes' в словаре event:

print(event['attributes']['CustomerID'])
print(event['attributes']['OfferID'])
print(event['attributes']['Category'])

Если это так, что некоторые ключи могут отсутствовать, используйте вместо них dict.get():

print(event['attributes'].get('CustomerID'))
print(event['attributes'].get('OfferID'))
print(event['attributes'].get('Category'))

Теперь вы получите None, если ключ отсутствует.

Вы можете расширить этот принцип для доступа к другим элементам словаря.

Насколько я понимаю ваш вопрос, вы также хотите создать файл CSV, содержащий извлеченные поля. Вы используете извлеченные значения с csv.DictWriter следующим образом:

import csv

with open('event.log') as events, open('output.csv', 'w') as csv_file:
    fields = ['CustomerID', 'OfferID', 'Category']
    writer = csv.DictWriter(csv_file, fields)
    writer.writeheader()
    for line in events:
        event = json.loads(line)
        writer.writerow(event['attributes'])

DictWriter просто оставит поля пустыми, если в словаре отсутствуют ключи.


Исходный ответ Данные не в формате CSV, они, похоже, содержат строки словаря Python. Их можно преобразовать в словари Python с помощью ast.literal_eval():

from ast import literal_eval

with open('event.log') as events:
    for line in events:
        event = literal_eval(line)
        # process event dictionary
person mhawke    schedule 10.07.2016
comment
нам нужно извлечь значения идентификатора клиента, идентификатора предложения и категории, а также в некоторых строках {} без пары ключ: значение в ней, сэр, результатом было ››› событие {u'MenuItem': u'Category', u 'CustomerID': u'364'} @mhawke - person Nabi Shaikh; 10.07.2016
comment
@NabiShaikh: Когда у вас есть словарь, вы можете получить доступ к его атрибутам. Глядя на ваш обновленный образец данных (который теперь выглядит как данные JSON!), Вы на самом деле имеете вложенные словари, поэтому вы можете получить доступ к идентификатору клиента, например, с помощью event['attributes']['CustomerID']. - person mhawke; 10.07.2016
comment
Файл ЖУРНАЛА СОБЫТИЙ имеет формат .txt, это не формат Джейсона. Я сталкиваюсь с ошибкой Traceback (последний последний вызов): Файл ‹stdin›, строка 7, в ‹module› Файл C:\Anaconda2\lib\csv.py , строка 152, в writerow return self.writer.writerow(self._dict_to_list(rowdict)) File C:\Anaconda2\lib\csv.py, строка 148, in _dict_to_list +, .join([repr(x) для x в неправильно_поля])) ValueError: dict содержит поля не в именах полей: u'Lat', u'Long' - person Nabi Shaikh; 10.07.2016
comment
@NabiShaikh: это текстовый файл, но содержимое в формате JSON. Парсер json успешно разбирает его, не так ли? Не передавайте в DictWriter.writerow() словари, содержащие ключи, которые вы не определили в аргументе fieldnames для DictWriter. В этом случае Lat и Long передаются writerow(). Не делай этого. - person mhawke; 10.07.2016