【问题标题】:Extracting required Variables from Event Log file using Python使用 Python 从事件日志文件中提取所需的变量
【发布时间】:2024-05-01 07:50:02
【问题描述】:

示例事件日志文件的第一行,这里我已经成功提取了除了最后一个键值对之外的所有内容-

{"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 IDoffer idcategory 这些是我需要提取的重要变量来自此事件日志文件。这是 csv 格式的文件。我尝试使用正则表达式,但它不起作用,因为您可以观察到每一列的格式都不同。如您所见,第一行有categorycustomer idoffer id,第二行完全空白,在这种情况下,正则表达式将不起作用,除此之外我们必须考虑我们必须考虑所有可能的条件,我们有 14000 个 sample.in 事件日志文件 ...#Jason # 解析 #Python #Pandas

【问题讨论】:

  • 这是纯文本文件吗?每行是否以{} 开头和结尾?如果是这样,您似乎可以逐行读取文件并使用 literal_eval 将每一行转换为 Python dict 对象。
  • 您能否提供数据日志的实际片段而不是图像格式?您不希望我们一一输入您的数据,对吧?
  • 是的,之前它是 txt 格式。它是我从事件日志文件 event_type event_timestamparrival_timestamp event_version application { app_id cognito_identity_pool_id } client{} device{} session{} attributes{}
  • 为什么图片中有单引号,文字中有双引号? (后者可以是 JSON 格式。)
  • @ayhan 图像文件为 csv 格式,而 in text 格式为 .txt 格式...从 .txt 文件中提取后,我将每个键分隔为单个 csv 文件。

标签: python pandas text-parsing string-parsing text-extraction


【解决方案1】:

编辑

编辑后的数据现在似乎是 JSON 数据。您仍然可以使用literal_eval,如下所示,或者您可以使用json 模块:

import json

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

要访问CustomerIDOfferIDCategory 等,您需要访问与event 字典中的键'attributes' 关联的嵌套字典:

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 字典字符串。这些可以使用ast.literal_eval()解析成Python字典:

from ast import literal_eval

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

【讨论】:

  • 我们需要提取客户 id 和商品 id 和类别的值,以及在某些行“{}”中没有键:值对先生,结果是 >>> 事件 {u 'MenuItem': u'Category', u'CustomerID': u'364'} @mhawke
  • @NabiShaikh:一旦你有了字典,你就可以访问其中的属性。查看更新后的数据样本(现在看起来是 JSON 数据!)您实际上有嵌套字典,因此您可以使用 event['attributes']['CustomerID'] 访问客户 ID。
  • ,事件日志文件是 .txt 格式,它不是 jason 格式我面临错误 Traceback(最近一次调用最后):文件“”,第 7 行,在 文件中“C:\Anaconda2\lib\csv.py”,第 152 行,在 writerow 返回 self.writer.writerow(self._dict_to_list(rowdict)) 文件“C:\Anaconda2\lib\csv.py”,第 148 行,在_dict_to_list + ", ".join([repr(x) for x in wrong_fields])) ValueError: dict contains fields not in fieldnames: u'Lat', u'Long'
  • @NabiShaikh:它是一个文本文件,但内容是 JSON。 json 解析器成功解析它,不是吗?不要将包含未在DictWriterfieldnames 参数中定义的键的字典传递给DictWriter.writerow()。在这种情况下,LatLong 被传递给 writerow()。不要那样做。
【解决方案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()

【讨论】:

    最近更新 更多