使用带有缺少数据的文本文件的循环将数据填充到 pandas 数据框

Filling Data to pandas dataframe using loop with text file that have missing data

我正在处理包含 1000 个变量(ABCD、GFHTI、AAAA、BBBB、...)的大型日志文件(4 Gig),但我只对其中的 50 个变量(ABCD、GFHTI、...)感兴趣).日志文件结构如下:

20100101_00:01:33.436-92.451 BLACKBOX ABCD ref 2183 value 24 
20100101_00:01:33.638-92.651 BLACKBOX GFHTI  ref 2183 value 25 
20100101_00:01:33.817-92.851 BLACKBOX AAAA ref 2183 value 26   (Not interested in this one)
20100101_00:01:34.017-93.051 BLACKBOX BBBB ref 2183 value 27  (Not interested
 in this one) 

我正在尝试从这个日志文件中创建一个 pandas 数据框,看起来像这样。

Time                               ABCD                GFHTI 
20100101_00:01:33.436-92.451        24                 NaN 
20100101_00:01:33.638-92.651        NaN                25  

我可以通过使用循环并附加到 pandas 数据框来做到这一点,但这不是很有效。我可以在日志文件中找到兴趣值的值和日期,但我不知道如何将 NaN 用于该特定日期和时间的其余变量,并在最后将其转换为数据框。 如果有人能提供帮助,我将不胜感激。

这是我的部分代码

ListOfData={}
fruit={ABCD, GFHTI}
for file in FileList:
   i=i+1
    thefile = open('CleanLog'+str(i)+'.txt', 'w')
    with open(file,'rt') as in_file:
        i=0
        for linenum, line in enumerate(in_file):        # Keep track of line numbers.
            if fruit.search(line) != None:# If substring search finds a match,
                i=i+1
                Loc=(fruit.search(line))
                d = [{'Time': line[0:17], Loc.group(0): line[Loc.span()[1]:-1]}]
                for word in Key:
                    if word == Loc.group(0):
                        ListOfData.append(d)

当您使用 pandas 时,无需在循环中手动读取文件:

data = pd.read_csv('CleanLog.txt', sep='\s+', header=None)

使用时间(#0)和变量名(#2)作为索引,保留变量值列(#6)。

columns_of_interest = ['ABCD','GFHTI']
data.set_index([0,2])[6].unstack()[columns_of_interest].dropna(how='all')
#2                             ABCD  GFHTI
#0                                        
#20100101_00:01:33.436-92.451  24.0    NaN
#20100101_00:01:33.638-92.651   NaN   25.0

您可以解析日志文件,并且只解析 return DataFrame 构造函数感兴趣的信息

为了解析日志行,我在这里使用正则表达式,但实际的解析函数应该取决于你的日志格式,而且我假设日志文件在相对于这个脚本所在的路径 log.txt 中是 运行.

import pandas as pd
import re

def parse_line(line):
    code_pattern = r'(?<=BLACKBOX )\w+'
    value_pattern = r'(?<=value )\d+'
    code = re.findall(code_pattern, line)[0]
    value = re.findall(value_pattern, line)[0]
    ts = line.split()[0]
    return ts, code, value

def parse_filter_logfile(fname):
    with open(fname) as f:
       for line in f:
           data = parse_line(line)
           if data[1] in ['ABCD', 'GFHTI']:
               # only yield rows that match the filter
               yield data

然后输入那个生成器来构造一个数据框

logparser = parse_filter_logfile('log.txt')
df = pd.DataFrame(logparser, columns = ['Time', 'Code', 'Value'])

最后,使用以下两个语句之一对数据框进行透视

df.pivot(index='Time', columns='Code')
df.set_index(['Time', 'Code']).unstack(-1)

输出如下:

                             Value      
Code                          ABCD GFHTI
Time                                    
20100101_00:01:33.436-92.451    24  None
20100101_00:01:33.638-92.651  None    25

希望您有足够的信息来处理您的日志文件。这里棘手的部分是处理日志行解析,您必须调整我的示例函数才能正确处理。