从日志文件转换矩阵

时间:2014-09-18 02:10:39

标签: python regex numpy

我在日志文件中有一个以这种格式写的矩阵:

2014-09-08 14:10:20,107 - root - INFO - [[  8.30857546   0.69993454   0.20645551  
77.01797674  13.76705776]
 [  8.35205432   0.53417203   0.19969048  76.78598173  14.12810144]
 [  8.37066492   0.64428449   0.18623849  76.4181809   14.3806312 ]
 [  8.50493296   0.5110043    0.19731849  76.45838604  14.32835821]
 [  8.18900791   0.4955451    0.22524777  76.96966663  14.12053259]]
...some text 
2014-09-08 14:12:22,211 - root - INFO - [[  3.25142253e+01   1.11788106e+00   1.51065008e-02   6.16496299e+01
    4.70315726e+00]
 [  3.31685887e+01   9.53522041e-01   1.49767860e-02   6.13449154e+01
    4.51799710e+00]
 [  3.31101827e+01   1.09729703e+00   5.03347259e-03   6.11818594e+01
    4.60562742e+00]
 [  3.32506957e+01   1.13837592e+00   1.51783456e-02   6.08651657e+01
    4.73058437e+00]
 [  3.26809490e+01   1.06617279e+00   1.00110121e-02   6.17429172e+01
    4.49994994e+00]]

我正在使用python日志包编写这个矩阵:

logging.info(conf_mat)

但是,logging.info没有向我展示以浮点%.3f格式编写矩阵的方法。所以我决定用这种方式解析日志文件:

conf_mat = [[]]
cf = '[+-]?(?=\d*[.eE])(?=\.?\d)\d*\.?\d*(?:[eE][+-]?\d+)?'

with open(sys.argv[1]) as f:
    for line in f:
        epoch = re.findall(ep, line) # find lines starting with epoch for other stuff
        if epoch:
            error_line = next(f) # grab the next line, which is the error line
            error_value = error_line[error_line.rfind('=')+1:]
            data_points.append(map(float,epoch[0]+(error_value,))) #get the error value for the specific epoch
            for i in range(N):
                cnf_mline = next(f)
                match = re.findall(cf, cnf_mline)
                if match:
                    conf_mat[count].append(map(float,match))
                else:
                    conf_mat.append([])
                    count += 1

然而,当我尝试使用

转换矩阵时,正则表达式在查看矩阵时没有捕获到行中断
conf_mtx = np.array(conf_mat)

1 个答案:

答案 0 :(得分:1)

您的正则表达式字符串cf必须是原始字符串文字:

cf = r'[+-]?(?=\d*[.eE])(?=\.?\d)\d*\.?\d*(?:[eE][+-]?\d+)?'

为了正常工作。反斜杠\字符被解释为"常规"中的转义序列。字符串,但不应该在正则表达式。您可以在re module's documentation的顶部以及此优秀的SO answer中阅读有关原始字符串文字的内容。 Alex Martelli很好地解释了他们,所以我不会重复他在这里所说的一切。可以这么说,如果你不使用原始文字,你必须用另一个反斜杠逃避你的每个反斜杠,而这只会变得丑陋和烦人。

至于你的其余代码,它不会在没有更多信息的情况下运行。 N中的for i in range(N):未定义,后面几行count。调用cnf_mline = next(f)实际上根本没有意义,因为您在重复调用next之前会重复使用文件中的行(通过重复调用for line in f:)使用next命令。目前还不清楚你的数据是否确实在下半部分中有一个换行符,列表中的一个成员位于下一行,我认为这是因为next()尝试的情况

我认为您应该首先尝试将输入文件清理为常规格式,然后您可以更轻松地在其上运行正则表达式。为了处理后续行,并且过度使用strip而不会耗尽您的生成器表达式,请查看itertools.tee()。它从单个迭代中返回 n 个独立的生成器,允许您在第一个之前提前一行。或者,您可以将文件的行读入列表,然后使用 i,i + 1 的索引进行操作。只需join每行,{{1}}将它们放在一起,然后写入新文件或列表。然后,您可以继续重写匹配循环,只需将适当格式的每个数字拉出,然后将其插入矩阵中的正确位置即可。好消息是你的正则表达式抓住了我投入的所有东西,所以你不需要修改任何东西。

祝你好运!

相关问题