【问题标题】:How to parse and tabulate file with repeated values如何解析和制表具有重复值的文件
【发布时间】:2021-09-23 02:43:23
【问题描述】:

我正在尝试将具有以下格式的文本文件制成表格。它就像多次出现的数据块。前 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

我想要的输出是这样的:

我当前的代码如下所示,我能够读取数据并将值存储在 defaultdict 中。之后,我尝试转换为 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

【问题讨论】:

    标签: python pandas parsing tabulate


    【解决方案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
    

    【讨论】:

    • 感谢您的帮助,但我收到了几个错误,例如 ValueError: Shape of passed values is (23, 1), indices imply (1, 1) 我不知道为什么。
    • 对我来说效果很好。您能否分享您正在处理的文本文件或与您发布的问题相同的文本文件?
    • 与我在其中尝试您的代码的文件相同。谢谢
    • 我在另一个终端上试过,这次成功了。非常感谢您的帮助
    猜你喜欢
    • 2012-10-12
    • 2020-05-02
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多