#python #pandas #parsing #tabulate
Вопрос:
Я пытаюсь свести в таблицу текстовый файл в следующем формате. Это похоже на блоки данных, которые появляются несколько раз. Первые 5 полей обычно появляются один раз в каждом блоке информации, и в выводе я хотел бы, чтобы они были заполнены (значения выделены зеленым цветом).
SOME TEXT
SOME TEXT
SOME TEXT
GSHSH = 0 OK:SUCCESS
ABC = 1
TDE = 0
TNLH = WL_CS
TKKJW = ZZR
MBTYIE = PRM
MHGT = 165
MRLL = CTM
TTDDX = 0
ZDTR = FALSE
UEEM = FALSE
KQTY = FALSE
MHGT = 211
MRLL = CTM
TTDDX = 0
ZDTR = FALSE
UEEM = FALSE
KQTY = FALSE
MHGT = 32
MRLL = CTM
TTDDX = 0
ZDTR = FALSE
UEEM = FALSE
KQTY = FALSE
SOME TEXT
SOME TEXT
SOME TEXT
GSHSH = 23 OK:SUCCESS
ABC = 1
TDE = 0
TNLH = WL_PS
KKJW = ZZZN
MBTYIE = PRM
MHGT = 9254
MRLL = PRM
ZDTR = FALSE
UEEM = FALSE
KQTY = FALSE
SOME TEXT
SOME TEXT
SOME TEXT
GSHSH = 0 OK:SUCCESS
ABC = 1
TDE = 1
TNLH = RTC_RMN
TKKJW = ZZR
BTYIE = RTC
MHGT = 1150
MRLL = PRM
ZDTR = FALSE
UEEM = FALSE
KQTY = FALSE
MHGT = 41
MRLL = CTM
TTDDX = 0
ZDTR = FALSE
UEEM = FALSE
KQTY = FALSE
SOME TEXT
SOME TEXT
SOME TEXT
GSHSH = 1 OK:SUCCESS
Мой желаемый результат был бы таким:
Мой текущий код выглядит так, как показано ниже, я могу считывать данные и сохранять значения по умолчанию. После этого я пытаюсь преобразовать данные в фрейм данных pandas, но получаю ошибку. И я застрял в том, как организовать значения, которые будут напечатаны в правильном столбце. Спасибо за любую помощь
import re
from collections import defaultdict
from tabulate import tabulate
import pandas as pd
file = 'file.txt'
f=open(file,"r").read().splitlines()
lst=[]
for line in f:
if re.match(r'[ t]', line):
lst.append(line.replace(' ', '').split('='))
print(lst)
d = defaultdict(list)
for k, v in lst:
d[k].append(v)
>>> d
defaultdict(<class 'list'>, {'ABC': ['1', '1', '1'], 'TDE': ['0', '0', '1'], 'TNLH': ['WL_CS',
'WL_PS', 'RTC_RMN'], 'TKKJW': ['ZZR', 'ZZR'], 'MBTYIE': ['PRM', 'PRM'], 'MHGT': ['165', '211',
'32', '9254', '1150', '41'], 'MRLL': ['CTM', 'CTM', 'CTM', 'PRM', 'PRM', 'CTM'], 'TTDDX':
['0', '0', '0', '0'], 'ZDTR': ['FALSE', 'FALSE', 'FALSE', 'FALSE', 'FALSE', 'FALSE'], 'UEEM':
['FALSE', 'FALSE', 'FALSE', 'FALSE', 'FALSE', 'FALSE'], 'KQTY': ['FALSE', 'FALSE', 'FALSE',
'FALSE', 'FALSE', 'FALSE'], 'KKJW': ['ZZZN'], 'BTYIE': ['RTC']})
df = pd.DataFrame.from_dict(d)
>> ValueError: arrays must all be same length
Ответ №1:
Попробуй:
file = 'file.txt'
f=open(file,"r").read().splitlines()
lst=[]
data = {}
dfs = []
group = 1
for line in f:
if line.endswith('SUCCESS'):
print(f'============== {line} ================')
if data:
df = pd.DataFrame.from_dict(data)
df = pd.pivot(data=df, columns=['col'], values=['val'], index=['group']).reset_index(drop=True)
df.columns = df.columns.droplevel()
df.fillna(method='ffill', inplace=True)
dfs.append(df)
data = []
group = 1
else:
if re.match(r'[ t]', line):
split_data = line.replace(' ', '').split('=')
data.append({'group': group, 'col': split_data[0], 'val': split_data[1]})
if not line.strip():
group =1
cols_order = ['ABC', 'TDE', 'TNLH', 'TKKJW', 'MBTYIE', 'MHGT', 'MRLL', 'TTDDX', 'ZDTR', 'UEEM', 'KQTY']
fina_df = pd.concat(dfs, ignore_index=True)
fina_df['TKKJW'].fillna(fina_df['KKJW'], inplace=True)
fina_df['MBTYIE'].fillna(fina_df['BTYIE'], inplace=True)
fina_df = fina_df[cols_order]
выход:
col ABC TDE TNLH TKKJW MBTYIE MHGT MRLL TTDDX ZDTR UEEM KQTY
0 1 0 WL_CS ZZR PRM 165 CTM 0 FALSE FALSE FALSE
1 1 0 WL_CS ZZR PRM 211 CTM 0 FALSE FALSE FALSE
2 1 0 WL_CS ZZR PRM 32 CTM 0 FALSE FALSE FALSE
3 1 0 WL_PS ZZZN PRM 9254 PRM NaN FALSE FALSE FALSE
4 1 1 RTC_RMN ZZR RTC 1150 PRM NaN FALSE FALSE FALSE
5 1 1 RTC_RMN ZZR RTC 41 CTM 0 FALSE FALSE FALSE
Комментарии:
1. Спасибо за помощь, но я получаю несколько ошибок, как будто
ValueError: Shape of passed values is (23, 1), indices imply (1, 1)
не знаю почему.2. Для меня это прекрасно сработало. Можете ли вы поделиться текстовым файлом, над которым вы работаете, или тем же файлом, который вы опубликовали в вопросе?
3. Это тот же файл, в котором я пробовал ваш код. Спасибо
4. Я попробовал в другом терминале, и на этот раз сработало. Большое спасибо за помощь