【问题标题】:Parse multicolumn string using python使用python解析多列字符串
【发布时间】:2015-06-16 17:26:16
【问题描述】:

我正在尝试从名为 NWChem 的化学信息学程序的文本输出中提取数据,我已经提取了我感兴趣的输出部分(振动模式),这里是 我提取的字符串

s = '''                   1           2           3           4           5           6

 P.Frequency       -0.00        0.00        0.00        0.00        0.00        0.00

           1    -0.23581     0.00000     0.00000     0.00000     0.01800    -0.04639
           2     0.00000     0.25004     0.00000     0.00000     0.00000     0.00000
           3    -0.00000     0.00000     0.00000     0.00000    -0.21968    -0.08522
           4    -0.23425     0.00000     0.00000     0.00000    -0.14541     0.37483
           5     0.00000     0.00000     0.99611     0.00000     0.00000     0.00000
           6     0.00192     0.00000     0.00000     0.00000    -0.42262     0.43789
           7    -0.23425     0.00000     0.00000     0.00000    -0.14541     0.37483
           8     0.00000     0.00000     0.00000     0.99611     0.00000     0.00000
           9    -0.00193     0.00000     0.00000     0.00000    -0.01674    -0.60834

                    7           8           9

 P.Frequency     1583.30     3661.06     3772.30

           1    -0.00000    -0.00000     0.06664
           2     0.00000     0.00000     0.00000
           3    -0.06754     0.04934     0.00000
           4     0.41551     0.56874    -0.52878
           5     0.00000     0.00000     0.00000
           6     0.53597    -0.39157     0.42577
           7    -0.41551    -0.56874    -0.52878
           8     0.00000     0.00000     0.00000
           9     0.53597    -0.39157    -0.42577'''

首先我使用正则表达式将数据拆分为行。

import re
p = re.compile('\n + +(?=[\d| ]+\n\n P.Frequency +)')
d = re.split(p, s)
print(d[0])

                   1           2           3           4           5           6

 P.Frequency       -0.00        0.00        0.00        0.00        0.00        0.00

           1    -0.23581     0.00000     0.00000     0.00000     0.01800    -0.04639
           2     0.00000     0.25004     0.00000     0.00000     0.00000     0.00000
           3    -0.00000     0.00000     0.00000     0.00000    -0.21968    -0.08522
           4    -0.23425     0.00000     0.00000     0.00000    -0.14541     0.37483
           5     0.00000     0.00000     0.99611     0.00000     0.00000     0.00000
           6     0.00192     0.00000     0.00000     0.00000    -0.42262     0.43789
           7    -0.23425     0.00000     0.00000     0.00000    -0.14541     0.37483
           8     0.00000     0.00000     0.00000     0.99611     0.00000     0.00000
           9    -0.00193     0.00000     0.00000     0.00000    -0.01674    -0.60834

但是我不知道如何提取垂直呈现的振动模式。我想轻松访问阵列阵列或 numpy 阵列中的每个振动模式。像这样:

[[-0.00, -0.23581, 0.0000, ..., -0.00193],
 [0.00, 0.00000, ..., 0.00000],
  ...
 [3772.30, 0.06664, ..., 0.0000, --0.42577]]

【问题讨论】:

  • 您可能投了反对票,因为您没有提供足够的背景信息:到目前为止您尝试了什么?你在哪里有输出 - 它是一个文本文件,它是在 R 中吗?
  • 尝试genfromtxt,使用跳过标题和跳过拖尾来隔离行集。

标签: python regex numpy cheminformatics


【解决方案1】:

通过 2 个np.genfromtxt 读取,我可以将您的数据文件加载到 2 个数组中,并将它们连接到一个 9x9 数组中:

In [134]: rows1 = np.genfromtxt('stack30874236.txt',names=None,skip_header=4,skip_footer=10)

In [135]: rows2 =np.genfromtxt('stack30874236.txt',names=None,skip_header=17)

In [137]: rows=np.concatenate([rows1[:,1:],rows2[:,1:]],axis=1)

In [138]: rows
Out[138]: 
array([[-0.23581,  0.     ,  0.     ,  0.     ,  0.018  , -0.04639, -0.     , -0.     ,  0.06664],
       [ 0.     ,  0.25004,  0.     ,  0.     ,  0.     ,  0.     , 0.     ,  0.     ,  0.     ],
       ...
       [-0.00193,  0.     ,  0.     ,  0.     , -0.01674, -0.60834, 0.53597, -0.39157, -0.42577]])

In [139]: rows.T
Out[139]: 
array([[-0.23581,  0.     , -0.     , -0.23425,  0.     ,  0.00192,  -0.23425,  0.     , -0.00193],
       [ 0.     ,  0.25004,  0.     ,  0.     ,  0.     ,  0.     ,
       ...
       [ 0.06664,  0.     ,  0.     , -0.52878,  0.     ,  0.42577, -0.52878,  0.     , -0.42577]])

我必须选择跳过页眉/页脚值以适合数据文件。用代码推断它们需要更多的工作。

【讨论】:

    【解决方案2】:

    正如hpaulj 建议的那样,numpy 函数genfromtxt 非常便于解析此类字符串,但是由于我使用的是python3,我需要将我的字符串转换为字节流以将其传递给此函数。

    下面是成功的代码:

    import numpy as np
    from io import BytesIO
    i = 0
    for row in d:
        values = np.genfromtxt(BytesIO(row.encode(encoding='UTF-8')), skip_header=1).transpose()[1:]
        if i == 0:
            data = values
        else:
            data = np.concatenate((data, values))
        i += 1
    

    【讨论】:

    • 我使用的是在 py3 中运行的 Ipython。在粘贴这样的文本时,我会在其前面加上 b: txt = b'''1 2 3 \n 4 5 6'''。我可能还需要通过splitlines 传递它,所以genfromtxt 不认为它是一个文件名。过去我也使用过io,尽管我发现这没有必要。 genfromtxt 对任何赋予它“行”(和“字节”)的迭代感到满意。
    • 感谢您提供这些精确度。
    猜你喜欢
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    相关资源
    最近更新 更多