Предварительно обработать файл данных перед пандами read_csv

Я работаю с данными, выводимыми из SAP, но это не CSV, поскольку он не заключает в кавычки строки, содержащие его разделитель, или фиксированную ширину, поскольку он имеет многобайтовые символы. Это своего рода «фиксированная ширина» по характеру.

Чтобы получить его в пандах, я в настоящее время читаю файл, получаю положение разделителей, нарезаю каждую строку вокруг разделителей и затем сохраняю их в соответствующий файл CSV, который я могу читать без проблем.

Я вижу, что панды read_csv могут получить буфер файлов. Как бы я передать свой поток прямо на него, без сохранения файла CSV? Должен ли я сделать генератор? Могу ли я получить вывод csv.writer.writerow без указания дескриптора файла?

Вот мой код:

import pandas as pd

caminho= r'C:\Users\user\Documents\SAP\Tests\\'
arquivo = "ExpComp_01.txt"
tipo_dado = {"KEY_GUID":"object", "DEL_IND":"object", "HDR_GUID":"object", , "PRICE":"object", "LEADTIME":"int16", "MANUFACTURER":"object", "LOAD_TIME":"object", "APPR_TIME":"object", "SEND_TIME":"object", "DESCRIPTION":"object"} 

def desmembra(linha, limites):
    # This functions receives each delimiter's index and cuts around it
    posicao=limites[0]    
    for limite in limites[1:]:
        yield linha[posicao+1:limite]
        posicao=limite

def pre_processa(arquivo):
    import csv
    import os
    # Translates SAP output in standard CSV
    with open(arquivo,"r", encoding="mbcs") as entrada, open(arquivo[:-3] +
    "csv", "w", newline="", encoding="mbcs") as saida:
        escreve=csv.writer(saida,csv.QUOTE_MINIMAL, delimiter=";").writerow
        for line in entrada:
            # Find heading
            if line[0]=="|":
                delimitadores = [x for x, v in enumerate(line) if v == '|']
                if line[-2] != "|": 
                    delimitadores.append(None)
                cabecalho_teste=line[:50]
                escreve([campo.strip() for campo in desmembra(line,delimitadores)])
                break
        for line in entrada:
            if line[0]=="|" and line[:50]!=cabecalho_teste:
                escreve([campo.strip() for campo in desmembra(line, delimitadores)])

pre_processa(caminho+arquivo)       
dados = pd.read_csv(caminho + arquivo[:-3] + "csv", sep=";",
                    header=0, encoding="mbcs", dtype=tipo_dado)

Кроме того, если вы могли бы поделиться передовым опытом: у меня есть странные строки даты и времени, как это20.120.813.132.432 который я могу успешно конвертировать с помощью

dados["SEND_TIME"]=pd.to_datetime(dados["SEND_TIME"], format="%Y%m%d%H%M%S")
dados["SEND_TIME"].replace(regex=False,inplace=True,to_replace=r'.',value=r'')

Я не могу написать для него парсер, потому что у меня даты хранятся в разных форматах. Будет ли быстрее указать конвертер, который будет делать это во время импорта, или панды сделают это по столбцам в конце? У меня похожая проблема с кодом99999999 что я должен добавить точки к99.999.999, Я не знаю, если яследует написать конвертер или подождать, пока после импорта сделатьdf.replace

РЕДАКТИРОВАТЬ -- Пример данных:

|                        KEY_GUID|DEL_IND|                        HDR_GUID|Prod_CD |DESCRIPTION                      |      PRICE|LEADTIME|MANUFACTURER|          LOAD_TIME|APPR_TIME     |          SEND_TIME|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|000427507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|75123636|Vneráéíoaeot.sadot.m             |     29,55 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.157 |
|000527507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|75123643|Tnerasodaeot|sadot.m             |    122,91 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.141 |
|0005DB50112F9E69E10000000A1D2028|       |384BB350BF56315DE20062700D627978|75123676|Dnerasodáeot.sadot.m             |252.446,99 |3       |POLAND      |20.121.226.175.640 |20121226183608|20.121.222.000.015 |
|000627507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|75123652|Pner|sodaeot.sadot.m             |    657,49 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.128 |
|000727507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|        |Rnerasodaeot.sadot.m             |    523,63 |30      |            |20.120.813.132.432 |20120813132929|20.120.707.010.119 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|                        KEY_GUID|DEL_IND|                        HDR_GUID|Prod_CD |DESCRIPTION                      |      PRICE|LEADTIME|MANUFACTURER|          LOAD_TIME|APPR_TIME     |          SEND_TIME|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------   |000827507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|75123603|Inerasodéeot.sadot.m             |  2.073,63 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.127 |
|000927507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|75123662|Ane|asodaeot.sadot.m             |      0,22 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.135 |
|000A27507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|75123626|Pneraíodaeot.sadot.m             |    300,75 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.140 |
|000B27507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|        |Aneraéodaeot.sadot.m             |      1,19 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.131 |
|000C27507E64FB29E2006281548EB186|       |4C1AD7E25DC50D61E10000000A19FF83|75123613|Cnerasodaeot.sadot.m             |     30,90 |30      |            |20.120.813.132.432 |20120813132929|20.120.505.010.144 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Я бы имел дело с другими таблицами с другими полями. Все в этом общем виде. Я могу доверять только разделителям в заголовке. Также у меня могут быть повторные заголовки в данных. Это выглядит как матричная распечатка.

Ответы на вопрос(1)

Ваш ответ на вопрос