【问题标题】:Speeding up text processing step加快文本处理步骤
【发布时间】:2020-10-08 14:15:42
【问题描述】:

我创建了一个函数,它对长度为 1045459 的数据帧进行一些文本处理。编译时间似乎比正常情况要长。

这就是我所做的:

def clean_descriptions(text_list):
    
    # First get everything into lowercase
    text_list = str(text_list)
    for x in text_list:
        x = x.lower()
    
    # Remove all instances of 3 characters followed by a number
    for substr in re.findall(r'\W([A-Z][A-Z][A-Z]\d)\W', text_list):
        text_list = text_list.replace(substr, '')
    text_list = text_list.replace('[]','') 
        
    # Remove NA
    text_list = text_list.replace('NA','')
        
    return text_list

这是我使用函数的方式:

df['short_description'] = clean_descriptions(df['short_description'].tolist())

有没有更有效的方法来做后者?

以下是 short_description 的示例:

PRG2 - stelucie needs help with Radio
[VLR44] vlrd-fc-edg-fw-01-00-01:BGP Status - WARNING [DEEP-DIVE]
[LGB3] lgb3-ar-acc-sw172129.amazon.com:PSU Check
[BFI4] Walk Up Ticket - Other
[FC-OOB]-DMO3 is down [DEEP-DIVE]

【问题讨论】:

  • 熊猫? text_list 是什么?列表?数据框?系列?为什么不使用 pandas 内置的正则表达式和 pandas 函数对 df` 进行操作?
  • 当您可以同时使用re.sub 时,为什么还要调用findall 然后replace
  • @PatrickArtner 我编辑了我的问题,但是我正在使用 pandas 数据框,但我可能正在做一些导致它超级慢的事情。
  • 我认为我有一个更有效的解决方案来解决您的问题,但是您是否有一些示例输入数据以及我可以测试的所需输出?

标签: python regex pandas


【解决方案1】:

如果你让 pandas 来做这件事,你就会让自己表现不佳。

inplaceregex 语法使用 pandas 自己的 replace

import pandas as pd

df = pd.DataFrame({"short": ["Some text " + a + b + c + d + " more text" 
                             for a in "A"
                             for b in "DE"
                             for c in "1G"
                             for d in "2z"]})
print(df)

df["short"].replace(to_replace=r"(?i)(^|\W)([A-Z][A-Z][A-Z]\d)\W", value="", 
                    regex=True, inplace=True) # In Place - do not reassign else all None
print(df)

输出:

                      short
0  Some text AD12 more text
1  Some text AD1z more text
2  Some text ADG2 more text
3  Some text ADGz more text
4  Some text AE12 more text
5  Some text AE1z more text
6  Some text AEG2 more text
7  Some text AEGz more text

                      short
0  Some text AD12 more text
1  Some text AD1z more text
2        Some textmore text
3  Some text ADGz more text
4  Some text AE12 more text
5  Some text AE1z more text
6        Some textmore text
7  Some text AEGz more text

【讨论】:

  • 使用你的函数我仍然得到 BHX4 的实例(3 个字符后跟一个数字),应该删除这些实例。
  • 如果可行的话,让我编辑我的问题以包含一个更大的示例。
  • @Snorrlaxxx 对于初学者,尝试使用 r"(?i)(^|\W)([A-Z][A-Z][A-Z]\d)\W" - (?i) 来区分大小写,(^|\W) 可选用于行首或 \W 应该有帮助。您可以将更多数据粘贴到 regex101.com 并使用正则表达式模式来获得合适的内容。
  • 感谢您的帮助,最后一个问题。如果我想删除包含在 [] 或 () 中的字符串,你知道我会怎么做吗?
  • @Snorrlaxxx python-regex-replace-bracketed-text-with-contents-of-brackets - 类似于 r'(?i)(\[[a-z]{3}\d\])' - 前缀 \ 以使 [ 和 ] 文字 [] --> regex101.com 是你的朋友
【解决方案2】:

尝试替换这部分代码:

for substr in re.findall(r'\W([A-Z][A-Z][A-Z]\d)\W', text_list):
        text_list = text_list.replace(substr, '')

使用所有可能的子字符串创建一个集合(不是列表),以便它只创建一次,而不是每次调用您的函数时创建(1045459 次来自您的数据帧)。

也可以简单地替换您的 to_lower 函数(顺便说一句,这是不正确的):

text_list=text_list.lower()

最后将所有替换添加到同一命令:

text_list = text_list.replace('[]','').replace('NA','')

【讨论】:

  • 如果我创建一个集合,我假设它只包含 pandas 数据框列中的唯一字符串。从那里我将如何进行适当的替换?也许是地图?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 2014-05-08
  • 2017-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多