Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用re(正则表达式)只解析行的块_Python_Python 3.x_Pandas_Dataframe - Fatal编程技术网

Python 使用re(正则表达式)只解析行的块

Python 使用re(正则表达式)只解析行的块,python,python-3.x,pandas,dataframe,Python,Python 3.x,Pandas,Dataframe,我的实验室正在使用一个软件,该软件会生成大量的数据作为输出,所以我正在尝试使用Python使事情变得更简单。到目前为止,我认为最好的方法是生成列表并将其视为数据块,但这并不容易: 第一块数据很简单:3列是固定的,只需使用以下方法即可获得: chunk1 = my_data[:3] 第二块数据并不容易,因为它可以有2、3或4列。我相信这里的关键是,当我们找到一个类似于137CCC的字母时,第二段就结束了。在这种情况下,我相信可以使用re模块解析两列、三列或四列,并在第一个字母之前停止,但我不知道

我的实验室正在使用一个软件,该软件会生成大量的数据作为输出,所以我正在尝试使用Python使事情变得更简单。到目前为止,我认为最好的方法是生成列表并将其视为数据块,但这并不容易: 第一块数据很简单:3列是固定的,只需使用以下方法即可获得:

chunk1 = my_data[:3]
第二块数据并不容易,因为它可以有2、3或4列。我相信这里的关键是,当我们找到一个类似于137CCC的字母时,第二段就结束了。在这种情况下,我相信可以使用re模块解析两列、三列或四列,并在第一个字母之前停止,但我不知道如何做。我打算通过用零或“-”填充空白点来“规范化”这些列,因此如果我有2列的情况,我将用[x,y,0,0]填充它,用[x,y,z,0]填充3列的情况

第三块是固定的两个、三个或四个字母和一个数字,如:CCC119.62

第四块是剩下的

下面是混乱输出的表示:

最终结果可能是: [s 91,1.00,OUT][9,3,12,7][OCCC,0.34][f829,27,f752,33]

到目前为止,我一直在想如何让re模块像这样工作:

text = """s 27    1.00   STRE   30   16   OC    1.355049  f1291 50
s 34   -1.00   BEND    1    3    7   CCC   119.62  f1037 26  f485 10
s 89    1.00   TORS   31   30   16   19   COCC     0.24  f161 14  f104 46  f87 19  f43 10
s 91    1.00   OUT     9    3   12    7   OCCC     0.34  f829 27  f752 33"""

my_file = StringIO(text)

chunks = []
for line in my_file:
    my_data = line.split()
    chunk1 = my_data[:4]
    chunk2 = my_data[4:6]
    for i in range(6, 8):
        if my_data[i].isdigit():
            chunk2.append(my_data[i])
        else:
            break
    chunk3_start = len(chunk1) + len(chunk2)
    chunk3 = my_data[chunk3_start:chunk3_start+2]
    chunk4 = my_data[chunk3_start+2:]
    chunks.append({1: chunk1, 2: chunk2, 3: chunk3, 4: chunk4})
非常感谢你们的帮助,伙计们

数据样本


这个问题不需要正则表达式。您可以这样做:

text = """s 27    1.00   STRE   30   16   OC    1.355049  f1291 50
s 34   -1.00   BEND    1    3    7   CCC   119.62  f1037 26  f485 10
s 89    1.00   TORS   31   30   16   19   COCC     0.24  f161 14  f104 46  f87 19  f43 10
s 91    1.00   OUT     9    3   12    7   OCCC     0.34  f829 27  f752 33"""

my_file = StringIO(text)

chunks = []
for line in my_file:
    my_data = line.split()
    chunk1 = my_data[:4]
    chunk2 = my_data[4:6]
    for i in range(6, 8):
        if my_data[i].isdigit():
            chunk2.append(my_data[i])
        else:
            break
    chunk3_start = len(chunk1) + len(chunk2)
    chunk3 = my_data[chunk3_start:chunk3_start+2]
    chunk4 = my_data[chunk3_start+2:]
    chunks.append({1: chunk1, 2: chunk2, 3: chunk3, 4: chunk4})
将生成以下输出:

[{1: ['s', '27', '1.00', 'STRE'],
  2: ['30', '16'],
  3: ['OC', '1.355049'],
  4: ['f1291', '50']},
 {1: ['s', '34', '-1.00', 'BEND'],
  2: ['1', '3', '7'],
  3: ['CCC', '119.62'],
  4: ['f1037', '26', 'f485', '10']},
 {1: ['s', '89', '1.00', 'TORS'],
  2: ['31', '30', '16', '19'],
  3: ['COCC', '0.24'],
  4: ['f161', '14', 'f104', '46', 'f87', '19', 'f43', '10']},
 {1: ['s', '91', '1.00', 'OUT'],
  2: ['9', '3', '12', '7'],
  3: ['OCCC', '0.34'],
  4: ['f829', '27', 'f752', '33']}]

基本上,你一直在向chunk2添加元素,直到你遇到一些不是数字的东西。使用chunk1和chunk2的长度来获取剩余的块。

这个问题不需要正则表达式。您可以这样做:

text = """s 27    1.00   STRE   30   16   OC    1.355049  f1291 50
s 34   -1.00   BEND    1    3    7   CCC   119.62  f1037 26  f485 10
s 89    1.00   TORS   31   30   16   19   COCC     0.24  f161 14  f104 46  f87 19  f43 10
s 91    1.00   OUT     9    3   12    7   OCCC     0.34  f829 27  f752 33"""

my_file = StringIO(text)

chunks = []
for line in my_file:
    my_data = line.split()
    chunk1 = my_data[:4]
    chunk2 = my_data[4:6]
    for i in range(6, 8):
        if my_data[i].isdigit():
            chunk2.append(my_data[i])
        else:
            break
    chunk3_start = len(chunk1) + len(chunk2)
    chunk3 = my_data[chunk3_start:chunk3_start+2]
    chunk4 = my_data[chunk3_start+2:]
    chunks.append({1: chunk1, 2: chunk2, 3: chunk3, 4: chunk4})
将生成以下输出:

[{1: ['s', '27', '1.00', 'STRE'],
  2: ['30', '16'],
  3: ['OC', '1.355049'],
  4: ['f1291', '50']},
 {1: ['s', '34', '-1.00', 'BEND'],
  2: ['1', '3', '7'],
  3: ['CCC', '119.62'],
  4: ['f1037', '26', 'f485', '10']},
 {1: ['s', '89', '1.00', 'TORS'],
  2: ['31', '30', '16', '19'],
  3: ['COCC', '0.24'],
  4: ['f161', '14', 'f104', '46', 'f87', '19', 'f43', '10']},
 {1: ['s', '91', '1.00', 'OUT'],
  2: ['9', '3', '12', '7'],
  3: ['OCCC', '0.34'],
  4: ['f829', '27', 'f752', '33']}]

基本上,你一直在向chunk2添加元素,直到你遇到一些不是数字的东西。使用chunk1和chunk2的长度来获取剩余的块。

我编写了一个生成器,从迭代器中提取,直到找到alpha字符串

from itertools import chain

def while_not_alpha(iterator):
    iterator = iter(iterator)
    for s in iterator:
        if not str(s).isalpha():
            yield s
        else:
            yield chain([s], iterator)
            break

def parse(line):
    *chunk1, rest = line.split(maxsplit=4)
    *chunk2, rest = while_not_alpha(rest.split())
    rest = list(rest)
    chunk3 = rest[:2]
    chunk4 = rest[2:]
    return chunk1, chunk2, chunk3, chunk4

# See below for definition of `txt`
chunk1, chunk2, chunk3, chunk4 = map(list, zip(*map(parse, txt.splitlines())))
我们可以看到chunk2看起来像

chunk2[:4]

[['30', '16'],
 ['8', '6'],
 ['14', '15'],
 ['14', '15']]
和chunk3

我们本可以更进一步制作数据帧

chunk1, chunk2, chunk3, chunk4 = map(
    pd.DataFrame, map(list, zip(*map(parse, txt.splitlines()))))

chunk2.head()

     0   1     2     3
0   30  16  None  None
1    8   6  None  None
2   14  15  None  None
3   14  15  None  None
4    8   6  None  None
5   30  31  None  None
6   13  11  None  None
7    1   3     7  None
8    3   1     4  None
9    7   3     1  None
10  21  14    15  None
11  24   5     2  None
12  25   2     6  None
13  24   5     2  None
14  25   2     6  None
15  26  19    18  None
16  31  30    16    19
17   8   2     3     6
18   9   3    12     7
或者更进一步:

df = pd.concat(
    map(pd.DataFrame, map(list, zip(*map(parse, txt.splitlines())))),
    axis=1, keys=[f'chunk{i}' for i in range(1, 5)]
)

df

   chunk1                  chunk2                 chunk3           chunk4                                          
        0   1      2     3      0   1     2     3      0         1      0   1      2     3      4     5     6     7
0       s  27   1.00  STRE     30  16  None  None     OC  1.355049  f1291  50   None  None   None  None  None  None
1       s  28  -1.00  STRE      8   6  None  None     CC  1.494281  f1340  12  f1271    17   None  None  None  None
2       s  29  -1.00  STRE     14  15  None  None     NC  1.421282  f1358  49   None  None   None  None  None  None
3       s  30   1.00  STRE     14  15  None  None     NC  1.421282  f1337  10  f1290    33   None  None  None  None
4       s  31   1.00  STRE      8   6  None  None     CC  1.494281  f1171  15   f323    11   None  None  None  None
5       s  32   1.00  STRE     30  31  None  None     OC  1.419982  f1082  51  f1077    24   None  None  None  None
6       s  33   1.00  STRE     13  11  None  None    ClC  1.740581   f842  15   f323    19   None  None  None  None
7       s  34  -1.00  BEND      1   3     7  None    CCC    119.62  f1037  26   f485    10   None  None  None  None
8       s  35  -1.00  BEND      3   1     4  None    CCC    119.74  f1124  29   None  None   None  None  None  None
9       s  36   1.00  BEND      7   3     1  None    CCC    119.62   f733  25   f288    13   None  None  None  None
10      s  37   1.00  BEND     21  14    15  None    HNC    116.16  f1578  40  f1560    20   None  None  None  None
11      s  38   1.00  BEND     24   5     2  None    HCC    119.73  f1186  67   None  None   None  None  None  None
12      s  39   1.00  BEND     25   2     6  None    HCC    118.80  f1536  53  f1082    10  f1077    17  None  None
13      s  40  -1.00  BEND     24   5     2  None    HCC    119.73  f1508  44  f1171    14  f1124    13  None  None
14      s  41   1.00  BEND     25   2     6  None    HCC    118.80  f1669  14  f1271    32  f1124    15  None  None
15      s  42  -1.00  BEND     26  19    18  None    HCC    119.04  f1578  10  f1560    37  f1291    11  None  None
16      s  89   1.00  TORS     31  30    16    19   COCC      0.24   f161  14   f104    46    f87    19   f43    10
17      s  90   1.00   OUT      8   2     3     6   CCCC      1.09   f466  36   f125    22   None  None  None  None
18      s  91   1.00   OUT      9   3    12     7   OCCC      0.34   f829  27   f752    33   None  None  None  None
设置


我编写了一个生成器,它从迭代器中提取,直到找到一个alpha字符串

from itertools import chain

def while_not_alpha(iterator):
    iterator = iter(iterator)
    for s in iterator:
        if not str(s).isalpha():
            yield s
        else:
            yield chain([s], iterator)
            break

def parse(line):
    *chunk1, rest = line.split(maxsplit=4)
    *chunk2, rest = while_not_alpha(rest.split())
    rest = list(rest)
    chunk3 = rest[:2]
    chunk4 = rest[2:]
    return chunk1, chunk2, chunk3, chunk4

# See below for definition of `txt`
chunk1, chunk2, chunk3, chunk4 = map(list, zip(*map(parse, txt.splitlines())))
我们可以看到chunk2看起来像

chunk2[:4]

[['30', '16'],
 ['8', '6'],
 ['14', '15'],
 ['14', '15']]
和chunk3

我们本可以更进一步制作数据帧

chunk1, chunk2, chunk3, chunk4 = map(
    pd.DataFrame, map(list, zip(*map(parse, txt.splitlines()))))

chunk2.head()

     0   1     2     3
0   30  16  None  None
1    8   6  None  None
2   14  15  None  None
3   14  15  None  None
4    8   6  None  None
5   30  31  None  None
6   13  11  None  None
7    1   3     7  None
8    3   1     4  None
9    7   3     1  None
10  21  14    15  None
11  24   5     2  None
12  25   2     6  None
13  24   5     2  None
14  25   2     6  None
15  26  19    18  None
16  31  30    16    19
17   8   2     3     6
18   9   3    12     7
或者更进一步:

df = pd.concat(
    map(pd.DataFrame, map(list, zip(*map(parse, txt.splitlines())))),
    axis=1, keys=[f'chunk{i}' for i in range(1, 5)]
)

df

   chunk1                  chunk2                 chunk3           chunk4                                          
        0   1      2     3      0   1     2     3      0         1      0   1      2     3      4     5     6     7
0       s  27   1.00  STRE     30  16  None  None     OC  1.355049  f1291  50   None  None   None  None  None  None
1       s  28  -1.00  STRE      8   6  None  None     CC  1.494281  f1340  12  f1271    17   None  None  None  None
2       s  29  -1.00  STRE     14  15  None  None     NC  1.421282  f1358  49   None  None   None  None  None  None
3       s  30   1.00  STRE     14  15  None  None     NC  1.421282  f1337  10  f1290    33   None  None  None  None
4       s  31   1.00  STRE      8   6  None  None     CC  1.494281  f1171  15   f323    11   None  None  None  None
5       s  32   1.00  STRE     30  31  None  None     OC  1.419982  f1082  51  f1077    24   None  None  None  None
6       s  33   1.00  STRE     13  11  None  None    ClC  1.740581   f842  15   f323    19   None  None  None  None
7       s  34  -1.00  BEND      1   3     7  None    CCC    119.62  f1037  26   f485    10   None  None  None  None
8       s  35  -1.00  BEND      3   1     4  None    CCC    119.74  f1124  29   None  None   None  None  None  None
9       s  36   1.00  BEND      7   3     1  None    CCC    119.62   f733  25   f288    13   None  None  None  None
10      s  37   1.00  BEND     21  14    15  None    HNC    116.16  f1578  40  f1560    20   None  None  None  None
11      s  38   1.00  BEND     24   5     2  None    HCC    119.73  f1186  67   None  None   None  None  None  None
12      s  39   1.00  BEND     25   2     6  None    HCC    118.80  f1536  53  f1082    10  f1077    17  None  None
13      s  40  -1.00  BEND     24   5     2  None    HCC    119.73  f1508  44  f1171    14  f1124    13  None  None
14      s  41   1.00  BEND     25   2     6  None    HCC    118.80  f1669  14  f1271    32  f1124    15  None  None
15      s  42  -1.00  BEND     26  19    18  None    HCC    119.04  f1578  10  f1560    37  f1291    11  None  None
16      s  89   1.00  TORS     31  30    16    19   COCC      0.24   f161  14   f104    46    f87    19   f43    10
17      s  90   1.00   OUT      8   2     3     6   CCCC      1.09   f466  36   f125    22   None  None  None  None
18      s  91   1.00   OUT      9   3    12     7   OCCC      0.34   f829  27   f752    33   None  None  None  None
设置

这是我的变体:

def simple_parsing(string):
    from re import split
    parts = split('\s+',string)
    result = [];i=4
    while not parts[i].isalpha():
        result.append(parts[i])
        i+=1
    return([parts[0:4],result,parts[i:i+2],parts[i+2:]])
例如,以您的一个字符串为例,结果如下:

simple_parsing('s 91    1.00   OUT     9    3   12    7   OCCC     0.34  f829 27  f752 33')
[['s', '91', '1.00', 'OUT'], ['9', '3', '12', '7'], ['OCCC', '0.34'], ['f829', '27', 'f752', '33']]
这是我的变体:

def simple_parsing(string):
    from re import split
    parts = split('\s+',string)
    result = [];i=4
    while not parts[i].isalpha():
        result.append(parts[i])
        i+=1
    return([parts[0:4],result,parts[i:i+2],parts[i+2:]])
例如,以您的一个字符串为例,结果如下:

simple_parsing('s 91    1.00   OUT     9    3   12    7   OCCC     0.34  f829 27  f752 33')
[['s', '91', '1.00', 'OUT'], ['9', '3', '12', '7'], ['OCCC', '0.34'], ['f829', '27', 'f752', '33']]

第一个错误是下意识地想到正则表达式。只要读一行,把它分成几个部分,然后根据内容进一步处理。当然,您可以使用正则表达式,它们甚至可以帮助验证行,但使用它们本身不应该是一个目标。第一个错误是考虑正则表达式时的下意识反应。只要读一行,把它分成几个部分,然后根据内容进一步处理。当然,您可以使用正则表达式,它们甚至可以帮助验证行,但使用它们本身不应该是一个目标。谢谢你@piRSquared@HenriqueJunior你这么说真是太好了。不用客气。我对这个解决方案有多优雅感到困惑。谢谢你@piRSquared@HenriqueJunior你这么说真是太好了。不客气。谢谢你的建议。谢谢你的建议。谢谢你的建议。谢谢你,@pault,这是一个非常优雅的方法。谢谢你,@pault,这是一个非常优雅的方法。