Python 使用包含丢失数据的文本文件的循环将数据填充到数据框

Python 使用包含丢失数据的文本文件的循环将数据填充到数据框,python,pandas,dataframe,missing-data,Python,Pandas,Dataframe,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 BL

我正在处理包含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数据帧来实现这一点,但这不是很有效。我可以在日志文件中找到感兴趣的值的值和日期,但我不知道如何为该特定日期和时间的其余变量设置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)的列


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

data = pd.read_csv('CleanLog.txt', sep='\s+', header=None)
使用时间(#0)和变量名(#2)作为索引,保留具有变量值(#6)的列


您可以解析日志文件,只将感兴趣的信息返回给DataFrame构造函数

为了解析日志行,我在这里使用regex,但是实际的解析函数应该取决于您的日志格式,而且我假设日志文件位于相对于脚本运行位置的路径
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
最后,使用下面两条语句之一透视数据帧

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

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

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

为了解析日志行,我在这里使用regex,但是实际的解析函数应该取决于您的日志格式,而且我假设日志文件位于相对于脚本运行位置的路径
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
最后,使用下面两条语句之一透视数据帧

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

希望您有足够的信息来处理日志文件。这里比较棘手的部分是处理日志行解析,您必须修改我的示例函数以使其正确。

谢谢您的回复。数据真的很混乱。为了提问,我简化了它。例如,有时真正的价值是,有时是。谢谢你的回复。数据真的很混乱。为了提问,我简化了它。例如,有时真正的价值是,有时是。非常感谢你的帮助。只有一个问题,如果是基本的,我很抱歉,基于这种方法,我的列名是时间、代码和价值。我如何将它们更改为时间,ABCD,gfh我非常感谢您的帮助。只有一个问题,如果是基本问题,我很抱歉,基于这种方法,我的列名是时间、代码和值。如何将它们更改为时间、ABCD、GFHTI