【问题标题】:Parse / Extract table from a messed .csv file?从混乱的 .csv 文件中解析/提取表?
【发布时间】:2020-05-09 01:45:40
【问题描述】:

我正在使用 Amazon Textract 解析图像 (png) 并提取表格。 当我用open(file_name, "r") 打开它并读取它的行时,这是一个这样的 csv 示例:

['Table: Table_1\n',
 '\n',
 'Test Name ,Result ,Flag ,Reference Range ,Lab ,\n',
 'HEPATIC FUNCTION PANEL PROTEIN, TOTAL ,6.1 ,,6.1-8.1 g/dL ,EN ,\n',
 'ALBUMIN ,4.3 ,,3.6-5.1 g/dL ,EN ,\n',
 'GLOBULIN ,1.8 ,LOW ,1.9-3.7 g/dL (calc) ,EN ,\n',
 'ALBUMIN/GLOBULIN RATIO ,2.4 ,,1.0-2.5 (calc) ,EN ,\n',
 'BILIRUBIN, TOTAL ,0.6 ,,0.2-1.2 mg/dL ,EN ,\n',
 'BILIRUBIN, DIRECT ,0.2 ,,< OR = 0.2 mg/dL ,EN ,\n',
 'BILIRUBIN, INDIRECT ,0.4 ,,0.2-1.2 mg/dL (calc) ,EN ,\n',
 'ALKALINE PHOSPHATASE ,61 ,,40-115 U/L ,EN ,\n',
 'AST ,27 ,,10-35 U/L ,EN ,\n',
 'ALT ,19 ,,9-46 U/L ,EN ,\n',
 '\n',
 '\n',
 '\n',
 '\n',
 '\n']

我可以用pandasread_csv 阅读它,但我遇到了错误(它总是以不同的格式出现——或多或少的空格,标题前的第一行不同)。 请告知如何从此类 csv 中提取表格?

【问题讨论】:

  • 你考虑过使用正则表达式吗?
  • @manu190466 这里适合什么正则表达式?我不这么认为...
  • BILIRUBIN 的 TOTAL、DIRECT 或 INDIRECT 标志应该去哪里?没有对应的列标题。

标签: python-3.x pandas amazon-textract


【解决方案1】:

使用正则表达式,您可以解析文件中的每一行以查找给定的模式并拒绝那些不匹配的模式。在正则表达式中创建组将允许您提取所需的值并将它们存储在可用于构造数据框的元组列表中:

import re
import pandas as pd

data = ['Table: Table_1\n',
        '\n',
        'Test Name ,Result ,Flag ,Reference Range ,Lab ,\n',
        'HEPATIC FUNCTION PANEL PROTEIN, TOTAL ,6.1 ,,6.1-8.1 g/dL ,EN ,\n',
        'ALBUMIN ,4.3 ,,3.6-5.1 g/dL ,EN ,\n',
        'GLOBULIN ,1.8 ,LOW ,1.9-3.7 g/dL (calc) ,EN ,\n',
        'ALBUMIN/GLOBULIN RATIO ,2.4 ,,1.0-2.5 (calc) ,EN ,\n',
        'BILIRUBIN, TOTAL ,0.6 ,,0.2-1.2 mg/dL ,EN ,\n',
        'BILIRUBIN, DIRECT ,0.2 ,,< OR = 0.2 mg/dL ,EN ,\n',
        'BILIRUBIN, INDIRECT ,0.4 ,,0.2-1.2 mg/dL (calc) ,EN ,\n',
        'ALKALINE PHOSPHATASE ,61 ,,40-115 U/L ,EN ,\n',
        'AST ,27 ,,10-35 U/L ,EN ,\n',
        'ALT ,19 ,,9-46 U/L ,EN ,\n',
        '\n',
        '\n',
        '\n',
        '\n',
        '\n']

regex=re.compile(r'(\D+),\s*(\d+\.?\d*)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,')
result=[]
for line in data:
    match=regex.search(line)
    if match:
        result.append(match.groups())
df=pd.DataFrame(data=result,columns=('Test Name' ,'Result' ,'Flag' ,'Reference Range' ,'Lab'))
print df

结果:

                                Test Name Result Flag       Reference Range  \
0  HEPATIC FUNCTION PANEL PROTEIN, TOTAL     6.1               6.1-8.1 g/dL   
1                                ALBUMIN     4.3               3.6-5.1 g/dL   
2                               GLOBULIN     1.8  LOW   1.9-3.7 g/dL (calc)   
3                 ALBUMIN/GLOBULIN RATIO     2.4             1.0-2.5 (calc)   
4                       BILIRUBIN, TOTAL     0.6              0.2-1.2 mg/dL   
5                      BILIRUBIN, DIRECT     0.2           < OR = 0.2 mg/dL   
6                    BILIRUBIN, INDIRECT     0.4       0.2-1.2 mg/dL (calc)   
7                   ALKALINE PHOSPHATASE      61                 40-115 U/L   
8                                    AST      27                  10-35 U/L   
9                                    ALT      19                   9-46 U/L   

  Lab  
0  EN  
1  EN  
2  EN  
3  EN  
4  EN  
5  EN  
6  EN  
7  EN  
8  EN  
9  EN 

【讨论】:

    【解决方案2】:

    我建议整理您的数据,将整理后的数据作为列表插入到 Pandas 中。我在您的示例中发现的问题是,在第一个字段中,它包含逗号,这会干扰 CSV 解析,也可以通过逗号分隔符工作。因此,需要对数据进行管理。 请在下面找到我的 Python 3 源代码:

    data = ['Table: Table_1\n',
            '\n',
            'Test Name ,Result ,Flag ,Reference Range ,Lab ,\n',
            'HEPATIC FUNCTION PANEL PROTEIN, TOTAL ,6.1 ,,6.1-8.1 g/dL ,EN ,\n',
            'ALBUMIN ,4.3 ,,3.6-5.1 g/dL ,EN ,\n',
            'GLOBULIN ,1.8 ,LOW ,1.9-3.7 g/dL (calc) ,EN ,\n',
            'ALBUMIN/GLOBULIN RATIO ,2.4 ,,1.0-2.5 (calc) ,EN ,\n',
            'BILIRUBIN, TOTAL ,0.6 ,,0.2-1.2 mg/dL ,EN ,\n',
            'BILIRUBIN, DIRECT ,0.2 ,,< OR = 0.2 mg/dL ,EN ,\n',
            'BILIRUBIN, INDIRECT ,0.4 ,,0.2-1.2 mg/dL (calc) ,EN ,\n',
            'ALKALINE PHOSPHATASE ,61 ,,40-115 U/L ,EN ,\n',
            'AST ,27 ,,10-35 U/L ,EN ,\n',
            'ALT ,19 ,,9-46 U/L ,EN ,\n',
            '\n',
            '\n',
            '\n',
            '\n',
            '\n']
    
    
    
    lines  = [x.replace('\n','') for x in data]
    
    import re
    p = re.compile('^[/A-Z ]+[,]*[/A-Z ]*,')
    curated_lines = []
    for l in lines:
        m = p.search(l)
        if m != None:
            s   = m.group(0)
            cs  = s.replace(',','')
            cl  = l.replace(s,cs+',')
            curated_lines.append(cl)
    
    frame_list_of_list = [l.split(',')[:-1] for l in curated_lines]
    
    import pandas as pd
    df = pd.DataFrame(frame_list_of_list,columns=['Test Name','Result','Flag','Reference Range','Lab'])
    print(df)
    

    这会产生以下结果:

                               Test Name Result  Flag        Reference Range  Lab
    0  HEPATIC FUNCTION PANEL PROTEIN TOTAL    6.1                 6.1-8.1 g/dL   EN 
    1                               ALBUMIN    4.3                 3.6-5.1 g/dL   EN 
    2                              GLOBULIN    1.8   LOW    1.9-3.7 g/dL (calc)   EN 
    3                ALBUMIN/GLOBULIN RATIO    2.4               1.0-2.5 (calc)   EN 
    4                       BILIRUBIN TOTAL    0.6                0.2-1.2 mg/dL   EN 
    5                      BILIRUBIN DIRECT    0.2             < OR = 0.2 mg/dL   EN 
    6                    BILIRUBIN INDIRECT    0.4         0.2-1.2 mg/dL (calc)   EN 
    7                  ALKALINE PHOSPHATASE     61                   40-115 U/L   EN 
    8                                   AST     27                    10-35 U/L   EN 
    9                                   ALT     19                     9-46 U/L   EN 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多