用于文本记录的Python-Pandas Parser以非均匀数量的行行排列

时间:2016-12-16 18:00:45

标签: python parsing pandas text

我是Python和pandas的新手,我想解析一个非常大的文本文件(200-500 MB),其中的信息显示为记录,每条记录包含数据字段为行/行而不是列这些记录具有不同的行数(因为它们提供不同类型的数据)。以下示例:

....
Record Type  = Record_Name
  attribute1 = 3090 (0x01218)
  attribute2     = attribute_name3090 (type: type_name1)
  timestamp: 21:47:33.360000
  attribute4: 731001-1 (0x0b277911)
  attribute5: 50000 (0x000000c350)
  attribute6: 3934 (0x0000000f5e)
  attribute7: 857 (0x0000000359)
Record Type  = Record_Name  
  attribute1 = 3099 (0x01227)
  attribute2     = attribute_name3099 (type: type_name2)
  timestamp: 21:49:07.359000
  attribute4     = 731001-3 (0x0b277911)
  attribute8: 14 (0x0000000e)
  attribute9: 17 (0x00000011)
  attribute10: 43 (0x0000002b)
  attribute11: 40 (0x00000028)
Record Type  = Record_Name
  attribute1 = 3090 (0x01218)
  attribute2     = attribute_name3090 (type: type_name1)
  timestamp: 21:51:17.142000
  attribute4: 942101-2 (0x0b345872)
  attribute5: 2490368 (0x00260000)
  attribute6: 24 (0x00000018)
  attribute7: 25 (0x00000019)
Record Type  = Record_Name
  attribute1 = 3102 (0x01230)
  attribute2     = attribute_name3102 (type: type_name1)
  timestamp: 21:52:42.359000
  attribute4: 731001-2 (0x0b277911)
  attribute12: 0 (0x0000000000)
  attribute13: 80 (0x0000000050)
....

因此,对于后处理,我想将所需的数据提取到几个pandas数据帧中,一个用于汇总记录,另一个用于过滤特定类型的记录。

DATAFRAME 1摘要记录表: 创建一个由timestamp索引的数据帧,只显示每条记录的几个属性,所有属性都保持字符串格式BUT而不包含()中的十六进制值:

                  attribute1  attribute2          type         attribute4
timestamp
...
21:47:33.360000   3090        attribute_name3090  type_name1   731001-1
21:49:07.359000   3099        attribute_name3099  type_name2   731001-3
21:51:17.142000   3090        attribute_name3090  type_name1   942101-2
21:52:42.359000   3102        attribute_name3102  type_name1   731001-2
....

DATAFRAME 2过滤记录: 仅捕获与attribute1 = 3090(type = typename1)关联的记录,并创建以timestamp索引的以下数据帧,其中attributes5-7不包含()中的十六进制值,并从字符串转换为整数:

                  attribute4   attribute5   attribute6   attribute7   
timestamp
...
21:47:33.360000   731001-1     5000         3934         857
21:51:17.142000   942101-2     2490368      24           25
....

我尝试打开文件并读取行但是需要花费大量时间。我读到了“生成器”,但无法弄清楚如何使用它们来简化代码。非常感谢您的建议。 提前谢谢。

格斯

1 个答案:

答案 0 :(得分:0)

此代码显示如何以简单的方式将输入行解析为两个字典。它假定输入非常规则。主要动作是在读取每行后,在空白处拆分行,冒号被删除(假设数据中没有冒号)并删除等号 - 所有这些都是为了简化后续处理,基于每行中的第一项

如果你运行代码,你会发现它创建了两个文本文件,每个文本文件每行包含一个字典。

with open ('DF1.txt', 'w') as DF1:
    with open ('DF2.txt', 'w') as DF2:

        DF1_record = {}
        DF2_record = {}
        with open('bigText.txt') as bigText:
            for inputLine in bigText:
                inputLine = [_.replace(':', '') for _ in inputLine.strip().split()]
                if '=' in inputLine:
                    inputLine.remove('=')
                kind = inputLine[0]
                if kind=='Record':
                    if DF1_record:
                        DF1.write(str(DF1_record)+'\n')
                    if DF2_record:
                        DF2.write(str(DF2_record)+'\n')
                        DF1_record={}
                        DF2_record={}
                    continue
                if kind in ['attribute1', 'attribute2', 'attribute4', 'timestamp']:
                    if kind=='attribute2':
                        DF1_record[kind]=inputLine[1]
                        DF1_record['type']=inputLine[3][:-1]
                    else:
                        DF1_record[kind]=inputLine[1]
                if kind in ['attribute1', 'attribute4', 'attribute4', 'attribute4', 'attribute7', 'timestamp']:
                    if DF1_record['attribute1']=='3090':
                        DF2_record[kind]=inputLine[1]