从日志文件中解析python中的矩阵的最佳方法

时间:2014-07-17 22:18:09

标签: python parsing matrix

我在这样的日志文件中打印了一个矩阵:

[[ 73.1   0.7   5.3   3.7   3.5   1.    0.9   1.3   8.8   1.7]
[  1.9  76.5   1.1   1.6   1.2   0.9   2.4   0.3   5.9   8.2]
[  4.2   0.3  64.5   5.7   9.1   5.9   6.5   2.7   1.    0.1]
[  2.2   0.5   9.4  49.4   9.6  15.6   8.5   3.3   1.2   0.3]
[  1.5   0.1   9.    5.3  71.3   3.5   4.8   3.7   0.8   0. ]
[  1.    0.4   7.7  15.9   6.5  59.5   4.4   3.7   0.7   0.2]
[  0.1   0.3   7.    5.6   3.8   2.2  80.3   0.5   0.2   0. ]
[  1.    0.2   6.3   4.5  11.2   6.2   0.9  69.1   0.2   0.4]
[  6.2   0.7   1.7   2.3   1.6   0.6   1.    0.4  84.    1.5]
[  4.3   8.6   1.9   3.7   1.3   1.2   1.7   1.9   4.4  71. ]]
.... some text and then again another matrix ......
[[ 71.9   0.6   8.1   2.    1.    1.9   2.    1.6   8.4   2.5]
 [  1.2  82.9   1.1   1.1   0.5   1.3   1.5   0.7   3.9   5.8]
 [  4.7   0.9  59.6   4.1   7.6  10.    7.3   3.8   1.5   0.5]
 [  2.3   0.7   6.5  43.1   6.8  24.5   7.4   4.    2.6   2.1]
 [  1.7   0.3   5.6   5.4  62.5   7.4   6.5   9.3   1.    0.3]
 [  1.4   0.2   6.   12.7   5.3  64.4   3.3   5.4   0.8   0.5]
 [  0.7   0.6   5.5   4.9   3.9   4.5  78.2   0.6   0.8   0.3]
 [  1.7   0.2   4.5   3.4   4.4   7.6   1.   76.    0.7   0.5]
 [  6.3   1.9   1.7   1.4   0.8   0.9   1.4   0.4  83.    2.2]
 [  3.4   8.6   1.4   1.2   0.8   1.3   0.9   2.4   3.8  76.2]]

我尝试这样做以读取第一个矩阵,然后将其附加到矩阵列表中:

with open('log.txt') as f:
    for line in f:
        for i in range(N):
            cnf_mline = f.next().strip()
            cnf_mvalue = cnf_mline[cnf_mline.rfind('[')+1:]
            cnf_mtx.append(map(float, (cnf_mvalue,)))
        print cnf_mline
        print cnf_mvalue

我看到以下错误:

ValueError: invalid literal for float(): 73.1   0.7   5.3   3.7   3.5   1.    0.9   1.3   8.8   1.7]

如何直接将此矩阵从日志文件解析为列表?

提前致谢!

2 个答案:

答案 0 :(得分:2)

final = [[]]
with open("log.txt") as f:
    counter = 0
    for line in f:
        match = re.findall("\d+\.\d+|\d+\.", line)
        if match:
            final[counter].append(map(float,match))
        else:
            counter += 1
            final.append([])
print final
[[[73.1, 0.7, 5.3, 3.7, 3.5, 1.0, 0.9, 1.3, 8.8, 1.7], [1.9, 76.5, 1.1, 1.6, 1.2, 0.9, 2.4, 0.3, 5.9, 8.2], [4.2, 0.3, 64.5, 5.7, 9.1, 5.9, 6.5, 2.7, 1.0, 0.1], [2.2, 0.5, 9.4, 49.4, 9.6, 15.6, 8.5, 3.3, 1.2, 0.3], [1.5, 0.1, 9.0, 5.3, 71.3, 3.5, 4.8, 3.7, 0.8, 0.0], [1.0, 0.4, 7.7, 15.9, 6.5, 59.5, 4.4, 3.7, 0.7, 0.2], [0.1, 0.3, 7.0, 5.6, 3.8, 2.2, 80.3, 0.5, 0.2, 0.0], [1.0, 0.2, 6.3, 4.5, 11.2, 6.2, 0.9, 69.1, 0.2, 0.4], [6.2, 0.7, 1.7, 2.3, 1.6, 0.6, 1.0, 0.4, 84.0, 1.5], [4.3, 8.6, 1.9, 3.7, 1.3, 1.2, 1.7, 1.9, 4.4, 71.0]], [[71.9, 0.6, 8.1, 2.0, 1.0, 1.9, 2.0, 1.6, 8.4, 2.5], [1.2, 82.9, 1.1, 1.1, 0.5, 1.3, 1.5, 0.7, 3.9, 5.8], [4.7, 0.9, 59.6, 4.1, 7.6, 10.0, 7.3, 3.8, 1.5, 0.5], [2.3, 0.7, 6.5, 43.1, 6.8, 24.5, 7.4, 4.0, 2.6, 2.1], [1.7, 0.3, 5.6, 5.4, 62.5, 7.4, 6.5, 9.3, 1.0, 0.3], [1.4, 0.2, 6.0, 12.7, 5.3, 64.4, 3.3, 5.4, 0.8, 0.5], [0.7, 0.6, 5.5, 4.9, 3.9, 4.5, 78.2, 0.6, 0.8, 0.3], [1.7, 0.2, 4.5, 3.4, 4.4, 7.6, 1.0, 76.0, 0.7, 0.5], [6.3, 1.9, 1.7, 1.4, 0.8, 0.9, 1.4, 0.4, 83.0, 2.2], [3.4, 8.6, 1.4, 1.2, 0.8, 1.3, 0.9, 2.4, 3.8, 76.2]]]

答案 1 :(得分:1)

您遇到的问题是您有一个字符串“73.1 0.7”等,并且无法解析为浮点数。如果你想要一些可解析的东西,你将不得不拆分该字符串(并删除那个尾随]

cnf_mvalues = cnf_mline[cnf_mline.rfind('[')+1:-1].split()
cnf.mtx.append(map(float, cnf_mvalues))

这可以帮助您解决异常问题。 (但这不是一个完整的解决方案!)

我认为您可能希望拥有一个更有状态的模型,因为:

  • [[开头并以]结尾的行标志着开始
  • [开头且以]结尾的行是矩阵中的一行
  • [开头并以]]结尾的行标记结束

(甚至这也做了很多假设。)实际上只有两种状态:矩阵和矩阵之外。我们可以将变量称为“n_matrix”。

然后对于每一行逻辑:

"[[...]":
    in_matrix := True
    start an empty matrix
    append the data on the row to the empty matrix
"[...]":
    if in_matrix:
        append the data on the row to the matrix under collection
    else:
        stray data, ignore
"[...]]":
    if in_matrix:
        append the data on the row to the matrix under collection
        append the matrix under collection to the list of matrices
        in_matrix := False
    else:
        stray data, ignore

当然,很多异常处理都包含无效值等。大多数情况下,如果您收到错误的数据,将in_matrix设置为False就足够了。

这个状态机应该变成一个简短的代码,因为检查括号并不是很困难。