python Как разбить файл без разделителя?

У меня есть интересная проблема, которая возникла из-за некоторых недавно отформатированных и плохо структурированных файлов данных. Это текстовые файлы, разделенные запятыми, которые содержат несколько наборов данных, каждый из которых имеет уникальный заголовок. Первоначально я использовал genFromTxt для чтения только в одном экземпляре данных с одним заголовком. Теперь с несколькими экземплярами genFromTxt просто не может справиться с этим. Каков наилучший способ разделения файла и подачи каждого отдельного экземпляра в genFromTxt? Вот пример файла. Данные из первого экземпляра сразу же попадают в заголовок второго экземпляра. Это повторяется около 20 раз на файл. Я не нашел общего разделителя, который бы мог их разделить.

       0.8 9999.0 999.0 999.0 999.0 9999.0 9999.0 999.0 999.0 999.0 9999.000 999.000 999.0 999.0 99999.0  9.0  9.0  9.0  9.0  9.0  9.0
       0.5 9999.0 999.0 999.0 999.0 9999.0 9999.0 999.0 999.0 999.0   72.380  -7.761 999.0 999.0 99999.0  9.0  9.0  9.0  9.0  9.0  9.0
       0.3 9999.0 999.0 999.0 999.0 9999.0 9999.0 999.0 999.0 999.0 9999.000 999.000 999.0 999.0 99999.0  9.0  9.0  9.0  9.0  9.0  9.0
       0.0 9999.0 999.0 999.0 999.0 9999.0 9999.0 999.0 999.0 999.0   72.381  -7.760 999.0 999.0 99999.0  9.0  9.0  9.0  9.0  9.0  9.0
      -1.0  906.7  20.0  18.9  92.8  -10.1   -3.7  10.7  70.0 999.0   72.380  -7.761 999.0 999.0   953.8  1.0  1.0  1.0  1.0  1.0  9.0
    Data Type:                         AVAPS SOUNDING DATA, Channel 2/Descending
    Project ID:                        DYNAMO
    Release Site Type/Site ID:         NOAA P3/N43RF 20111116I1
    Release Location (lon,lat,alt):    072 12.04'E, 08 11.50'S, 72.201, -8.192, 966.4
    UTC Release Time (y,m,d,h,m,s):    2011, 11, 16, 04:22:07
    Reference Launch Data Source/Time: IWGADTS Format (IWG1)/04:22:07
    Sonde Id:                          110355308
    System Operator/Comments:          TMR/none, Good Drop
    Post Processing Comments:          Aspen Version 3.1; Created on 01 Feb 2012 23:18 UTC; Configuration research-dropsonde
    /
    /
    Nominal Release Time (y,m,d,h,m,s):2011, 11, 16, 04:22:07
     Time  Press  Temp  Dewpt  RH    Ucmp   Vcmp   spd   dir   Wcmp     Lon     Lat   Ele   Azi    Alt    Qp   Qt   Qrh  Qu   Qv   QdZ
      sec    mb     C     C     %     m/s    m/s   m/s   deg   m/s      deg     deg   deg   deg     m    code code code code code code
    ------ ------ ----- ----- ----- ------ ------ ----- ----- ----- -------- ------- ----- ----- ------- ---- ---- ---- ---- ---- ----
      89.8 1011.6  27.3  23.9  81.0 9999.0 9999.0 999.0 999.0 999.0 9999.000 999.000 999.0 999.0     0.0  1.0  1.0  1.0  9.0  9.0  9.0

1 ответ

Решение

Вы можете адаптировать код как... (Предупреждение Python3, если вы хотите запустить его в Python2.7+, замените range() с xrange() (в целях эффективности))

def readSacredAttribute(holyInput):
    raw = [ x.strip() for x in holyInput.readline()[:-1].split(':') ]
    newRaw = []
    for i in range(len(raw) - 1):
        for x in [ x.strip() for x in raw[ i + 1 ].split(',') ]:
            newRaw.append(x)

    raw[ 1 : ] = newRaw

    parameters = {}
    if '(' in raw[0]:
        base = raw[0].index('(') + 1
        to = raw[0].index(')')
        splitted = [ x.strip() for x in raw[1].split(',') ]
        for i, x in enumerate([ x.strip() for x in raw[0][ base : to ].split(',') ]):
            parameters[x] = splitted[i]

    return (raw, parameters)

def splitThisStupidMess(holyInput):
    holyHeader = []
    for i in range(6):
        holyHeader.append([ float(x) for x in holyInput.readline().split()])

    sacredAttributes = { x[0][0] : (x[0][1], x[1]) for x in [  readSacredAttribute(holyInput) for i in range(9) ] }

    # Ignore the '\' lines
    for i in range(2):
        holyInput.readline()

    nominalTime = readSacreAttribute(holyInput)
    sacredAttributes[nominalTime[0][0]] = (nominalTime[0][1], nominalTime[1])

    divineNames = holyInput.readline().split()
    divineUnits = holyInput.readline().split()
    holyInput.readline()    # Avoid decoration...
    divineValues = [ float(x) for x in holyInput.readline().split() ]

    divineFooter = { divineNames[i] : (divineUnits[i], divineValues[i]) for i in len(divineNames) }

    return (holyHeader, sacredAttributes, divineFooter)
Другие вопросы по тегам