使用Python从事件日志文件中提取所需变量
示例事件日志文件的第一行,在这里,我成功地提取了最后一个键值对(即属性)之外的所有内容-使用Python从事件日志文件中提取所需变量,python,pandas,text-parsing,string-parsing,text-extraction,Python,Pandas,Text Parsing,String Parsing,Text Extraction,示例事件日志文件的第一行,在这里,我成功地提取了最后一个键值对(即属性)之外的所有内容- {"event_type":"ActionClicked","event_timestamp":1451583172592,"arrival_timestamp":1451608731845,"event_version":"3.0", "application":{"app_id":"7ffa58dab3c646cea642e961ff8a8070","cognito_identity_pool_id
{"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":{}}
大家好,我正在尝试从事件日志文件中提取内容,如附图所示。至于要求,我必须提取客户ID
,提供ID
,类别
这些是我需要从该事件日志文件中提取的重要变量。这是csv格式的文件。我尝试使用正则表达式,但它不起作用,因为你们可以观察到每一列的格式都是不同的。正如你看到的第一行有“代码>类别<代码>代码>客户ID 代码>报价ID <代码>第二行完全空白,在这种情况下,正则表达式将不起作用,我们必须考虑到所有可能的条件,我们有14000个示例。在事件日志文件中…#Jason#Parsing#Python#Pandas编辑
编辑后的数据现在显示为JSON数据。您仍然可以使用如下所示的literal\u eval
,也可以使用该模块:
要访问CustomerID
、OfferID
、类别
等,您需要访问与事件
字典中的键'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字典字符串。可以使用以下方法将其解析为Python字典:
这可能不是将文本文件(由行分隔)中的嵌套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()
这是纯文本文件吗?每行是否以
{}
开头和结尾?如果是这样,您似乎可以逐行读取文件,并使用literal\u eval
将每一行转换为Pythondict
对象。您是否可以提供实际的数据日志而不是图像格式?你不希望我们一个接一个地键入你的数据,对吗?是的,它是以前的txt格式。这是我从事件日志文件event_type event_timestamp arrival_timestamp event_version应用程序{app_id cognito_identity_pool_id}客户端{}设备{}会话{}属性{为什么图像中有单引号,而文本中有双引号?(后者可以是JSON格式。)@ayhan图像文件为csv格式,其中文本格式为.txt格式…从.txt文件中提取后,我将每个键分离为单个csv文件。我们需要提取客户id、提供id和类别的值,以及某些行中的“{}”没有键:值对,结果是>>>事件{u'MenuItem':u'Category',u'CustomerID':u'364'}@mhawke@NabiShaikh:拥有字典后,您可以访问其中的属性。查看更新后的数据样本(现在看起来是JSON数据!)实际上您有嵌套的字典,因此您可以使用event['attributes']['CustomerID']
访问客户id,例如,事件日志文件为.txt格式,这不是jason格式,我面临错误回溯(上次调用):文件“”,第7行,文件“C:\Anaconda2\lib\csv.py”,第152行,在writerow中返回self.writer.writerow(self.\u dict\u to_list(rowdict))文件“C:\Anaconda2\lib\csv.py”,第148行,在_dict_to_list+“,”.join([repr(x)for x in error_fields])ValueError:dict包含字段名以外的字段:u'Lat',u'Long'@NabiShaikh:这是一个文本文件,但内容是JSON。json
解析器成功地解析了它,不是吗?不要将字典传递给DictWriter.writerow()
,这些字典包含未在DictWriter
的fieldnames
参数中定义的键。在这种情况下,Lat
和Long
被传递到writerow()
。不要那样做。
from ast import literal_eval
with open('event.log') as events:
for line in events:
event = literal_eval(line)
# process event dictionary
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()