使用带有缺少数据的文本文件的循环将数据填充到 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
希望您有足够的信息来处理您的日志文件。这里棘手的部分是处理日志行解析,您必须调整我的示例函数才能正确处理。
我正在处理包含 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
希望您有足够的信息来处理您的日志文件。这里棘手的部分是处理日志行解析,您必须调整我的示例函数才能正确处理。