разделенная строка без разделителя с ограничительными именами полей и содержимым - PullRequest
0 голосов
/ 20 марта 2020

У меня есть фрейм данных с bankmutations.
Фрейм данных содержит столбец описания. В этом столбце есть ограничительные имена полей с их содержимым. Это выглядит так:

AAm.loc[0, ’OmsBank'] => ‘  fieldname1: content fn1   fieldname3: content fn3     ‘
AAm.loc[1, ’OmsBank'] => ‘  fieldname5: content fn5   fieldname2: content fn2     ‘

Я много гуглил, если было решение этой проблемы в целом (разбивка длинной строки в именах полей и содержимом). До сих пор не найдено простого решения.

Я мог бы использовать двойной пробел в качестве разделителя для разбиения, но внутри содержимого полей также есть двойные пробелы. Так что это не плохой вариант. Пробовал использовать split со списком / массивом, но тоже не повезло.

До сих пор я создал небольшой второй фрейм данных с ограничительными именами полей, начальной позицией имени поля и начальной позицией контента и конечной позицией контента .

I l oop по строкам банковских отчетов, проверьте, какие имена полей присутствуют, и сохраните позицию начальной метки и начального содержимого в маленьком фрейме данных. Я отсортировал небольшой фрейм данных по позиции fieldname, сбросил Индекс, а затем я могу определить конечную позицию содержимого (начало следующего имени поля). Последнее имя поля не имеет следующего имени поля. Поэтому я должен хранить длину строки описания в качестве конечного значения. Тогда я могу сохранить содержимое указанных c элементов в кадре данных banktatement.

У меня такое ощущение, что это можно сделать более «питоническими» и эффективными векторизованными лямбда-функциями?
Если у кого-то есть предложения, я был бы очень признателен. Также решение этой проблемы в целом может помочь другим.

Мой код до сих пор:

import pandas as pd
# data
tosplit = ['SEPA Inc dl Incassant: blabla  Naam: Insurance    Machtiging: number  Omschrijving: Rel.nr. number2    IBAN: iban#', 
          'SEPA Overboeking  IBAN: iban#  BIC: bic#  Naam: blabla  Omschrijving: Refund  Kenmerk: refcode', 
          'SEPA iDEAL  IBAN: iban#  BIC: bic#  Naam: seller  Omschrijving: description  double space  Kenmerk: refcode',
          'SEPA iDEAL  IBAN: iban#  BIC: bic#  Naam: city  Omschrijving: citytax']
AAm = pd.DataFrame(tosplit, columns= ['OmsBank'])
AAm['Naam'] = ''
AAm['Oms'] = ''
AAm
# field list
fld = [' IBAN: ', ' BIC: ', ' Naam: ', ' Omschrijving: ', ' Kenmerk: ', ' Referentie: ', ' Machtiging: ', ' Incassant: ']
fld.sort()

# store field list in dataframe and add columns for position
fld= pd.DataFrame(fld, columns = ['fldnm'] )
ser= [0]*len(fld)
fld = fld.assign(bgn = ser, bgc = ser, end = ser )
# loop through AAm (dataframe with bankmutations) and proces data
for i in AAm.index:

    # search for fieldnames and store postion (begin of fieldname and begin of fieldcontent) if the are found
    for j in fld.index:
        temp = AAm.loc[i, 'OmsBank'].find(fld.loc[j,'fldnm'])
        if temp == -1: 
            temp2 = -1 
        else:
            temp2 = temp+len(fld.loc[j,'fldnm'])
            fld.loc[j,'bgn'] = temp
            fld.loc[j,'bgc'] = temp2

    # order by postion and reset index
    fld = fld.sort_values(by ='bgc')
    fld.reset_index(drop=True, inplace = True)
    # establish end of content position. For the last one it is length general string
    for j in fld.index:
        if (fld.loc[j, 'bgn']>0) & (j < len(fld)-1):
            fld.loc[j, 'end'] = fld.loc[(j+1), 'bgn']
        fld.loc[len(fld)-1, 'end'] = len(AAm.loc[i, 'OmsBank'])

    # store start/end of relevant field content in AAm
    nm_om = fld[(fld['fldnm'] == ' Naam: ') | (fld['fldnm'] == ' Omschrijving: ')]
    nm_om.reset_index(drop=True, inplace = True)
    AAm.loc[i,'Naam'] = AAm.loc[i,'OmsBank'][nm_om.loc[0, 'bgc']:nm_om.loc[0, 'end']].strip()
    AAm.loc[i,'Oms'] = AAm.loc[i,'OmsBank'][nm_om.loc[1, 'bgc']:nm_om.loc[1, 'end']].strip()

    #reset values in fieldlist
    fld[['bgn', 'bgc', 'end']]=0
...