У меня есть фрейм данных с 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