【问题标题】:How to remove a duplicated block of text using python如何使用python删除重复的文本块
【发布时间】:2019-03-30 07:39:34
【问题描述】:

我正在处理作为放射学报告的文本文件。如果文档有两页,则在所有页面的顶部重复出现包含患者姓名和其他元数据的文本块,页面的其余部分包含报告的内容。我已将页面合并为一个文本对象。保留第一个块我想删除所有其他重复块。有没有办法以编程方式从所有此类文件中删除这些块? 重复的块看起来像这样:

 Patient ID            xxx                 Patient Name           xxx
 Gender                 Female                         Age                     43Y 8M
 Procedure Name         CT Scan - Brain (Repeat)       Performed Date          14-03-2018
 Study DateTime         14-03-2018 07:10 am            Study Description       BRAIN REPEAT
 Study Type             CT                             Referring Physician     xxx

【问题讨论】:

  • 如果你知道每个块是如何开始和结束的,那么是的,因为有一个模式
  • 感谢 SPYBUG96。是的,我愿意。我以添加的块模式为例编辑了问题。我想用 python 处理一批文件。
  • 基于多行的解决方案:stackoverflow.com/a/68614409/191246

标签: python regex nltk


【解决方案1】:

一个纯文本文件可以在 python 中表示为一个序列。考虑下面的plain.txt

This is the first line!\n
This is the second line!\n
This is the third line!\n

您可以使用with 保留字来创建管理打开/关闭逻辑的上下文,如下所示:

with open("./plain.txt", "r") as file:
    for line in file:
        # program logic
        pass

"r"是指open使用的模式。

因此,使用此习惯用法,您可以存储重复值并在遇到它时忽略它,以适合您的文件访问模式的方式。

编辑:我看到了你的编辑,看起来这实际上是一个 csv,对吧?如果是这样,我推荐 pandas 包。

import pandas as pd # Conventional namespace is pd

# Check out blob, os.walk, os.path for programmatic ways to generate this array
files = ["file.csv", "names.csv", "here.csv"] 

df = pd.DataFrame()
for filepath in files:
    df = df.append(pd.read_csv(filepath))

# To display result
print(df)

# To save to new csv
df.to_csv("big.csv")

【讨论】:

  • 嗨。谢谢。不,它不是 CSV,它的文本以表格格式显示在每页的顶部。该页面的其余部分包含报告中的发现。
  • 好的,那么我认为我原来的简介中的 for 循环更相关。如果打印每一行会发生什么(即在示例代码中将pass 替换为print(line))?您可以随意选择一个示例文件,因为您似乎确信它们都以相同的方式组织
  • 谢谢。我对此很陌生。需要一些时间来尝试一下。当我这样做时会回复你。
【解决方案2】:

假设您可以将每个单独的页面放入文档列表中

def remove_patient_data(documents: list, pattern: str) -> str:
    document_buffer = ""
    for count, document in enumerate(documents):
        if count != 0:
            document = document.replace(pattern, "")
        document_buffer += document + '\n'
    return document_buffer

my_documents = ["blah foo blah", "blah foo bar", "blah foo baz"]
remove_patient_data(my_documents, "foo")

哪个会返回

'blah foo blah\nblah bar\nblah baz\n'

【讨论】:

  • 我想在一批几百个类似文件上使用它。尽管模式保持不变,但名称和日期会有所不同。那么我应该在您的解决方案中的模式变量中使用正则表达式吗?如果可以,您能否推荐一个正则表达式序列?
  • 病人数据后面的第一个词总是一样的吗?
  • 不,这也可能改变。
  • 这是一个困难的问题,因为“患者元数据”和文档的其余部分之间没有明确的分隔符。如果有少量可能的“推荐医生”,您可以循环使用所有可能的医生的模板正则表达式模式
  • 在转诊医生的名字之后会有一个换行符。希望可以充当分隔符。推荐医师\s* 一些名字\n。那就是休息开始的地方。我一直在尝试整个块的正则表达式序列,但我就是做错了。
【解决方案3】:

您可以通过以下方式找到所有患者数据出现的起始索引:

str.find(sub,start,end)

在哪里

sub :这是需要在给定字符串中搜索的子字符串 - 在您的情况下,它将是患者数据 start :需要在字符串中检查 sub 的起始位置 end : 字符串中需要检查后缀的结束位置

它将返回搜索字符串(患者数据)出现的最低索引。

您可以循环执行此过程,以获取出现患者数据的所有索引。

然后您可以从第二个实例开始替换患者数据,方法是:

str_new = ''.join(( str_old[ : indicies[1] ], '' , s_old[ indicies[2] + len(str_old) + 1 : ] ))
  ... assuming a total of 3 pages in your record.

其他选择:

str.replace(old, new [, max])

在哪里

old: - 这是要替换的旧子字符串——在您的情况下是患者数据
new: - 这是新的子字符串,它将替换旧的子字符串——这可能是 ' '(空格) max: - 如果给定这个可选参数 max,则仅替换第一次出现的计数 - 这意味着患者数据现在将仅显示在 last 页面上。

【讨论】:

  • 谢谢。会试一试。名称和日期可能会更改。我们可以给子字符串的正则表达式序列吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
  • 2012-06-05
相关资源
最近更新 更多