【问题标题】:Python Dataframe - Extract multiple lines between regex matchPython Dataframe - 在正则表达式匹配之间提取多行
【发布时间】:2017-09-20 05:30:55
【问题描述】:

我正在开发一个 python 3.x 项目,该项目需要读取需要过滤的大型 TXT 文件(例如,删除多个空格、空行、以某些字符串开头的行等)并最终拆分通过正则表达式匹配。

我现在正在做的是使用 pandas 数据框来存储每一行​​(这使得使用 pandas startswith() 或 endswith() 删除行变得容易)。另一方面,通过让文本文件的每一行对应于 DataFrame 中的一行,我无法弄清楚如何在 REGEX 匹配之间提取数据。这是一个例子:

| 0 | REGEX MATCH   |
| 1 | data          |
| 2 | data          |
| 3 | REGEX MATCH   |
| 4 | data          |
| 5 | REGEX MATCH   |

所以问题是如何在匹配项之间提取数据(在此示例中,第 0 到第 2 行;第 3 到第 4 和第 5 行)。这在熊猫中是否可能?

另一种选择是从文本文件中使用 read() 并进行常规的字符串操作而不是 DataFrame、过滤、拆分等,我不确定它是否适用于大文本文件。在那种情况下,我在 REGEX 匹配之间有不需要的数据。示例:

str = "This is REGEX_MATCH    while between another \n \n\ REGEX_MATCH there is some    unwanted data"

在上面,我需要删除多余的空格,\n 最后使用 REGEX 来拆分匹配项。唯一的问题是我的源文本文件非常大。

Pandas 删除/过滤速度很快,而常规字符串更容易拆分。

有什么想法吗?

谢谢!

编辑。这是我的源文本的样子。如您所见,它一团糟(从PDF中提取)。每一行都是 pandas 数据框中的一行。问题是是否可以提取包含一系列数字(包括那些行)的那些行之间的所有数据。

13 - 0005761-52.2014.4.02.5101                 Lorem ipsum dolor sit amet.
Quisque eget velit a orci consectetur pharetra. Aliquam.
\n
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
a
Lorem ipsum dolor sit amet.
        Lorem ipsum dolor sit amet - Sed ut tempus neque.
Sed ut tempus neque.
2 - 0117333-76.2015.4.02.5101 Lorem ipsum dolor sit amet

【问题讨论】:

  • txt 长什么样子?可以发 4-5 行吗?
  • 我不知道你的数据有多大,但是我用超过30K的字幕文件多次尝试了字符串操作。其中一个文件平均为 10 KB。因此,总共有 30MB 数据。每次我在 python 中尝试时,都需要几秒钟。
  • @Vaishali 刚刚编辑了我的帖子以包含我的文本中的 sn-p。
  • 您想要 13 - 0005761-52.2014.4.02.5101 和 2 - 0117333-76.2015.4.02.5101 之间的所有内容?
  • 正是@Vaishali。虽然我仍然需要做一些过滤来删除一些额外的空格和空行。但本质上,这些参数(包括参数)之间的所有文本数据都是我需要放在 pandas 数据框中的一行。之后就可以进行过滤了。

标签: python regex python-3.x pandas dataframe


【解决方案1】:

您可以使用并选择不包含匹配项的行将其全部读入 DataFrame:

import pandas as pd

df = pd.read_csv('test.txt', header=None, delimiter='|') 
df = df[df[2].str.contains('MATCH') == False]  # check column 2 from the example

或者,您可以找到您想要忽略的行,然后使用 skiprows 参数作为 pandas.read_csv

with open('test.txt') as f:
    lines = f.readlines()

skiprows = [i for i, line in enumerate(lines) if 'MATCH' in line]
df = pd.read_csv('test.txt', skiprows=skiprows, header=None, delimiter='|')

如果不需要或为空,按列号删除列:

df = df.drop(df.columns[[0, 1, 3]], axis=1)

从第 2 列中的所有值中清除多余的空格:

df[2] = [' '.join(x.split()) for x in df[2]]  

或者清除整个 DataFrame 中的空白:

cleaner = lambda x: ' '.join(x.split()) if isinstance(x, str) else x
df = df.applymap(cleaner)

【讨论】:

  • 我一定会试试这个!不过,我需要做一些改变。我只是不能删除包含 de REGEX 匹配的整行,因为有时在该匹配之后会有数据(例如:| 0 | REGEX MATCH 数据数据 |
  • 我明白了,在这种情况下,将每一行作为一个大列读取并从那里应用操作可能更有意义。
  • 列还是行?我目前正在做的是连续读取每一行,而不是列。此外,如果我将每一行读取为一个大列/行并应用我需要的所有过滤(额外的空格、空白行等),我仍然能够收集 REGEX 匹配之间的所有数据,即使它分布在许多列/行?这就是我卡住的地方。 REGEX 过滤仅适用于特定行,因此我无法使用此方法获取多行之间的所有数据。但是,是的,可能我做错了什么。
  • 嗯,我想这可能有助于查看更多示例数据。如果你愿意,我们可以在这里聊天chat.stackoverflow.com/rooms/155276/…
  • @Leandro 我很想知道你是否解决了这个问题,如果解决了,如何解决。我正在尝试为非常相似的情况找到解决方案,任何灵感都会很有用
猜你喜欢
  • 1970-01-01
  • 2018-04-04
  • 2016-02-02
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多