Импорт отсканированного PDF Извлеченного текста в CSV - PullRequest
0 голосов
/ 01 июня 2018

Я извлек текст из отсканированного PDF с помощью Tesseract.У меня есть выходная строка как-то так ..

Haemoglobin 13.5 14-16 g/dl
Random Blood Sugar 186 60 - 160 mg/dl
Random Urine Sugar Nil
¢ Blood Urea 43 14-40 mg/dl
4 — Serum Creatinine 2.13 0.4-1.5 mg/dl
Serum Uric Acid 4.9 3.4-7.0 mg/dl
Serum Sodium 142 135 - 150 meq/L
/ Serum Potassium 2.6 3.5-5.0 meq/L
Total Cholesterol] 146 110 - 160 mg/dl
Triglycerides 162 60 - 180 mg/d]

Теперь мне нужно передать это в dataframe или csv со всем текстом в одном столбце и значениями в другом, т.е..

**Haemoglobin**            13.5   14-16     g/dl
**Random Blood Sugar**     186    60 - 160  mg/dl

пока, лучшее, что я мог бы пройти через это что-то вроде этого ...

  text = text.split('\n')
  text = [x.split(' ') for x in text]
df = pd.DataFrame(text, columns['Header','Detail','a','e,','b','c','d','f'])
df

    Header    Detail   a      e     b      c      d  f
0 Haemoglobin 13.5    14-16   g/dl  None   None  None  None
1 Random      Blood   Sugar   186   60      -     160  mg/dl
2 Random      Urine   Sugar   Nil   None   None  None  None

Пожалуйста, помогите !!

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Я должен отметить, что это требует много работы, и, честно говоря, вы еще ничего не пробовали.Но чтобы дать вам преимущество, вот код, который устраняет некоторые очевидные проблемы в вашем вводе:

import re
def isnum(x):
    try:
        float(x)
        return True
    except:
        return False

def clean_line(lnin):
    # clean the leading garbage
    ln=re.sub('^[^A-Za-z]+','',lnin).split()
    for i in range(len(ln)):
        if isnum(ln[i]):
            ind=i
            break
    Header=' '.join(ln[:ind])
    ln=[Header]+ln[ind:]
    if '-' in ln:
        ind=ln.index('-')
        ln[ind-1]=ln[ind-1]+'-'+ln[ind+1]
        del ln[ind:ind+2]
    return ln

Используйте функцию clean_line для очистки каждой из ваших строк.Затем вы можете передать его на информационный фрейм.

0 голосов
/ 01 июня 2018

Используя регулярные выражения, приведенный ниже пример кода будет анализировать текст в строку CSV с токенами: description, result, normal_value, unit.

Обратите внимание, что список test_results обычно читается из файла с использованием:

с открытым ('name_test_file') в качестве test_file: test_results = test_file.read (). Splitlines ()

import re
tests = 'Haemoglobin 13.5 14-16 g/dl\nRandom Blood Sugar 186 60 - 160 mg/dl\n'\
    'Random Urine Sugar Nil\n¢ Blood Urea 43 14-40 mg/dl\n'\
    '4 — Serum Creatinine 2.13 0.4-1.5 mg/dl\n'\
    'Serum Uric Acid 4.9 3.4-7.0 mg/dl\nSerum Sodium 142 135 - 150 meq/L\n'\
    '/ Serum Potassium 2.6 3.5-5.0 meq/L\n'\
    'Total Cholesterol] 146 110 - 160 mg/dl\n'\
    'Triglycerides 162 60 - 180 mg/d]\n'

test_results = tests.splitlines()

for test_result in test_results:
    print('input :', test_result)

    m = re.search(r'.*?(?=[a-zA-Z][a-zA-Z])(?P<description>.*?)(?=[ ][0-9])'
              r'[ ](?P<result>[0-9.]*?)(?=[ ][0-9])'
              r'[ ](?P<normal_value>[ 0-9.\-]*?)(?=[ ][a-zA-Z])'
              r'[ ](?P<unit>.[ a-zA-Z/]*)',
              test_result)

    if m is not None:
        normal_value = m.group('normal_value')
        unit = m.group('unit')

    else:
        m = re.search(r'.*?(?=[a-zA-Z][a-zA-Z])(?P<description>.*?)(?=[ ]Nil)'
                  r'[ ](?P<result>Nil).*',
                  test_result)
        normal_value = ''
        unit = ''

    if m is not None:
        description = m.group('description')
        result = m.group('result')

    else:
        description = test_result
        result = ''

    write_string = description + ',' + result + ',' + normal_value + ',' + unit
    print(write_string)
0 голосов
/ 01 июня 2018

Работа в обратном направлении от конца, так как остальная часть записи, кажется, имеет фиксированный формат, т. Е. Работает в обратном направлении,

строка, представляющая единицы (без пробелов): число: тире: число: число:текст, который вы хотите

Haemoglobin 13.5 14-16 g/dl
Field 5 (all characters backwards from end until space reached) = g/gl
Field 4 (jump over space, all characters backwards until space or dash reached) = 16
Field 3 (jump over space if present, pick up dash) = -
Field 2 (jump over space if present, all characters backwards until space reached) = 14
Field 1 (jump over space, all characters backwards until space reached) = 13.5
Field 0 (jump over space and take the rest) = Haemoglobin

Total Cholesterol] 146 110 - 160 mg/dl
Field 5 (all characters backwards from end until space reached) = mg/dl
Field 4 (jump over space, all characters backwards until space or dash reached) = 160
Field 3 (jump over space if present, pick up dash) = -
Field 2 (jump over space if present, all characters backwards until space reached) = 110
Field 1 (jump over space, all characters backwards until space reached) = 146
Field 0 (jump over space and take the rest) = Total Cholesterol]
...