Анализ выходных данных в фрейм данных

#python #python-3.x #pandas #parsing

Вопрос:

Мне нужно проанализировать вывод бота и преобразовать его в формат таблицы. Ниже приведена ссылка на необработанный файл, и он также выглядит так

https://www.dropbox.com/s/ab7sdl74krwltrd/raw_file.txt?dl=0

 Invoice: 13613289,
------------------------,
HEAD Segment 1: ST~ST~~005010X222A1,
HEAD Segment 5: NM1~40~2~GEHC~~~~~46~GEHC,
HEAD Segment 16: HL~2~1~22~0,
HEAD Segment 32: CLM~03X13613289-7~1968~~~24>B>1~Y~A~Y~Y,
HEAD Segment 40: REF~BDE~229~BROWARD COUNTY   AABC~219:BRD,
HEAD Segment 51: HI~ABK>N471,
HEAD Segment 54: HI~BP>54150,
"HEAD Segment 58: NM1~77~2~OUTPATIENT SURGICAL SERVICES, LTD~~~~~XX~1427012202",
HEAD Segment 60: N4~PLANTATION~FL~333241811,
BODY Segment 1: LX~1,
BODY Segment 2: SV1~HC>00920>QZ>P2>X4>>~1968~MJ~65~~~1,
BODY Segment 3: DTP~472~D8~20210406,
BODY Segment 7: REF~6R~1,
,
END,
Invoice: 13828170,
------------------------,
HEAD Segment 1: ST~ST~~005010X222A1,
HEAD Segment 8: NM1~85~2~JLR MEDICAL GROUP~~~~~XX~1518910520,
HEAD Segment 16: HL~2~1~22~0,
HEAD Segment 57: PRV~PE~PXC~207L00000X,
HEAD Segment 74: NM1~PR~2~TRICARE EAST REGION~~~~~PI~GET93776P,
BODY Segment 1: LX~1,
BODY Segment 2: SV1~HC>00402>QK>X4>>>~1722~MJ~108~~~1>2,
BODY Segment 3: DTP~472~D8~20210426,
BODY Segment 7: REF~6R~1,
,
END,
Invoice: 13828171,
------------------------,
HEAD Segment 1: ST~ST~~005010X222A1,
HEAD Segment 6: HL~1~~20~1,
HEAD Segment 16: HL~2~1~22~0,
HEAD Segment 41: REF~DDE~6~JLR MEDICAL GROUP ANESTHESIA~200:JLRAA,
HEAD Segment 57: PRV~PE~PXC~367H00000X,
HEAD Segment 70: OI~~~Y~B~~Y,
HEAD Segment 74: NM1~PR~2~TRICARE EAST REGION~~~~~PI~GET93776P,
BODY Segment 1: LX~1,
BODY Segment 2: SV1~HC>00402>QX>X4>>>~1722~MJ~108~~~1>2,
BODY Segment 3: DTP~472~D8~20210426,
BODY Segment 7: REF~6R~1,
,
END,
 

Он имеет счет-фактуру, а затем переменные сегменты ГОЛОВЫ от 1 до 100 и переменные сегменты ТЕЛА от 1 до 10. Моя мысль состоит в том, чтобы сначала создать пустой фрейм данных pandas со столбцами Счет-фактура, ГОЛОВНОЙ сегмент 1, ГОЛОВНОЙ сегмент 2,….. Сегмент ГОЛОВЫ 100, Сегмент ТЕЛА 1, Сегмент ТЕЛА 2,…..Сегмент тела 10 и создайте список для каждого проанализированного элемента, а затем сопоставьте значения списка на основе имени столбца df. Наконец, удалите все столбцы df, которые имеют все нулевые значения. Но мне трудно сопоставить содержимое значения списка на основе имени столбца df и вставить в df. Я понял это до сих пор.

 import pandas as pd

filename = 'Z:\Projects\Compliance BOT\raw_file.txt'

a_list = ['Invoice']  
a_list.extend(['HEAD Segment '  str(x) for x in range(1,100   1)])    
a_list.extend(['BODY Segment '  str(x) for x in range(1,10   1)])   
df = pd.DataFrame(columns = a_list)

l = []
with open(filename, 'r', encoding='utf-8-sig') as input:
    for line in input:
        print(line.strip())
        line = line.strip()
        if line.startswith('"') and line.endswith('",'):
            line = line[1:-1]
        l.append(line.strip())        
        if '------------------------,' in l: l.remove('------------------------,')
        if ',' in l: l.remove(',')
        # l = [x[:-1] for x in l]
        l1 = [x[:-1] for x in l]
        if line.strip() == ',':
            break  
print(l)
 

Ожидаемый результат должен быть таким

https://www.dropbox.com/scl/fi/j7mpwy84ne37mtyaprwp3/output.xlsx?dl=0amp;rlkey=lluo9lsc2rgcd4lxepwk0hb1u

Также, пожалуйста, дайте мне знать, если я усложняю это и есть какой-либо другой простой способ сделать это?

Комментарии:

1. загрузите «Completed_07202021.csv» и вставьте ссылку сюда. При необходимости подвергните цензуре конфиденциальные данные перед загрузкой. кроме того, покажите свой ожидаемый результат здесь, в теле вашего поста SO.

2. Я загрузил входной необработанный файл, а также ожидаемый результат. Спасибо!!

Ответ №1:

Попробуйте этот код

 import pandas as pd

filename = 'Completed_07202021.csv'

a_list = ['Invoice']  
a_list.extend(['HEAD Segment '  str(x) for x in range(1,100   1)])    
a_list.extend(['BODY Segment '  str(x) for x in range(1,10   1)])   
df = pd.DataFrame(columns = a_list)

l = []
l.append(df)
out={}
with open(filename, 'r', encoding='utf-8-sig') as input:
    for line in input:
        print(line)
        if line.strip() == ',':
            continue  
        line = line.strip()
        if line.startswith('"') and line.endswith('",'):
            line = line[1:-1]
        if 'END,' in line:
            l.append(pd.DataFrame.from_dict(out))
            out={}
        data = line.strip().split(':')
        if len(data)!=2:
            continue
        out_str = ':'.join(data[1:])
        out[data[0].strip()]=[out_str[:-1].strip() if out_str.endswith(',') else out_str.strip()]
        
df_out = pd.concat(l)
df_out
 

дайте мне знать, если у вас возникнут какие-либо проблемы с этим кодом

Комментарии:

1. Большое тебе спасибо, Теджас. Ты сделал это так просто.

2. Просто предложение, как вы упомянули в проблеме, что вы хотите удалить столбцы, которые имеют все значения NAN, один простой способ-удалить эту строку df = pd.DataFrame(столбцы = a_list), мы объединяем фрейм данных, поэтому, если значение столбца доступно, то только этот столбец добавляется в основной фрейм данных, поэтому вам не нужно снова удалять этап NAN

3. дайте мне знать, если вы хотите обновить код для этого

4. Одна из моих проблем заключается в том, что у нас есть несколько «:» для сегмента 40 ex HEAD для первого счета. Как я могу это исправить?

5. data = line.strip().split(‘:’,1) сделал трюк для установки maxsplit = 1