如何有效地解析结构复杂的大型文本文件?

时间:2019-05-20 20:10:04

标签: python-3.x pandas

首先,我是Python的新手,所以我可能会犯一些基本的错误。 我有以下要求。

实体数据行的示例:

'SAFRP ASBDZ0192894   1 ABCDEFGHIJKLMNOPQRSTUV1234567809'
     |     |          |   
     | Entity Type Code
           |          |
           | Entity Type SubCode
                      |
                      | Continued Indicator
AFR in the line = Region
  • 我有500,000多个数据行的文件。
  • 我正在使用.readlines()将其读入列表
  • 每行都是代表实体的固定长度的字母数字字符串/记录
  • 实体存在订单处理依赖性,例如,在处理任何Widget2之前必须先处理所有Widget1实体
  • 使用实体代码和子代码的组合,您可以确定数据代表什么实体
  • 文件按地区分组,然后按该地区内的每个实体分组
  • 实体类型代码始终位于位置5
  • 如上所述,实体类型子代码对于正确识别和解码行也是必需的
  • 但是,子代码的位置将根据实体类型代码而改变。但是它将位于位置6或位置13
  • 续指示器的位置将根据实体类型+子代码的种类而变化。它可以位于以下位置18、20、22、25、26、27、39或56
  • 连续指示符用于指示无法将实体所需的所有信息都编码在一行中,而其余信息则在后续行中进行编码。
  • 如果延续标记= 0,则没有延续线
  • 如果延续标记= 1,则表明该实体还有多余的行
  • 连续数据的结尾由乱序号表示,例如每条续行上的续行指示器将显示为2、3、4(0或1)
  • 零或1表示一个新实体,而不是先前实体的延续

我的问题

我需要以最有效的方式来解码此文件中的实体(大约20种类型)。目前,我为每个要解码的实体迭代文件。
我使用Regex来测试每一行,以查看它是否代表我要查找的实体。

ISENTITY = re.compile(r'^(S|T)(?P<Region>.{3})(?P<EntityCode>[ADEHPRTU])(?P<SubCodeA>.).{6}(?P<SubCodeB>.).{8}.{102}(?P<FRN>.{5})(?P<Date>[0-9]{4})')

--within loop iterating through all lines/records
m = ISENTITY.match(record)
    if m:   
        entitycode = m.group('EntityCode')
        switcher = {
            'A': m.group('SubCodeA'),
            'D': m.group('SubCodeA'),
            'E': m.group('SubCodeA'),
            'H': m.group('SubCodeB'),
            'P': m.group('SubCodeB'),
            'R': '-',
            'T': m.group('SubCodeA'),
            'U': m.group('SubCodeA')
        }
        subcode = switcher.get(entitycode, None)

        if entitycode+subcode == entity_to_process_code:
            # This is line represents a Widget that I need to process using
            # the decode info for that specific entity type

每个实体类型50s x 20处理每个实体大约需要50秒的时间


问题

我认为一种更有效的方法可能是先以某种方式对文件进行排序,然后按实体类型对其进行排序,然后依次迭代以按顺序处理实体类型。

当我完成一种实体类型的处理后,我可以从文件列表中删除所有这些行,然后再次开始寻找下一个实体类型的过程(在现在较小的列表中)。

不幸的是,我不知道如何对列表进行排序,以便可以正确地对列表进行排序(按实体类型+子代码),并保证保持任何连续行的顺序。 list.sort()不会解决问题。

此外,如果我完全错误地从这个角度出发,请提出一些更合适的建议。

谢谢

0 个答案:

没有答案