簡體   English   中英

np.where如何用正則表達式提高性能?

[英]np.where how to improve performance with regular expression?

我是python numpy和正則表達式的新手。 我試圖從每行的pandas文本列中提取模式。 根據我的要求,有許多可能的案例可供使用,所以我在下面寫了不同的正則表達式。 迭代和搜索給定的模式我使用python的np.where但我遇到了性能問題。 有沒有辦法改善性能或任何替代方案以實現低於輸出。

x_train['Description'] is my pandas column.

54672 rows in my dataset.


Code:

pattern1 = re.compile(r'\bAGE[a-z]?\b[\s\w]*\W+\d+.*(?:year[s]|month[s]?)',re.I)

pattern2 = re.compile(r'\bfor\b[\s]*age[s]?\W+\d+\W+(?:month[s]?|year[s]?)',re.I)

pattern3 = re.compile(r'\badult[s]?.[\w\s]\d+',re.I)

pattern4 = re.compile(r'\b\d+\W+(?:month[s]?|year[s]?)\W+of\W+age[a-z]?',re.I)

pattern5 = re.compile(r'[a-z][a-z\s]+(?:month[s]?|year[s]?)[\w\s]+age[s]?',re.I) 

pattern6 = re.compile(r'\bage.*?\s\d+[\s]*\+',re.I)

pattern7 = re.compile(r'\bbetween[\s]*age[s]?[\s]*\d+.*(?:month[s]?|year[s]?)',re.I)

pattern8 = re.compile(r'\b\d+[\w+\s]*?(?:\band\sup\b|\band\sabove\b|\band\sold[a-z]*\b)',re.I)

np_time = time.time()

x_train['pattern'] = np.where(x_train['Description'].str.contains(pattern1), x_train['Description'].str.findall(pattern1),

                              np.where (x_train['Description'].str.contains(pattern2), x_train['Description'].str.findall(pattern2),

                              np.where (x_train['Description'].str.contains(pattern3), x_train['Description'].str.findall(pattern3),

                              np.where (x_train['Description'].str.contains(pattern4), x_train['Description'].str.findall(pattern4),  

                              np.where (x_train['Description'].str.contains(pattern5), x_train['Description'].str.findall(pattern5),  

                              np.where (x_train['Description'].str.contains(pattern6), x_train['Description'].str.findall(pattern6),  

                              np.where (x_train['Description'].str.contains(pattern7), x_train['Description'].str.findall(pattern7),  

                              np.where (x_train['Description'].str.contains(pattern8), x_train['Description'].str.findall(pattern8),                                


                                                'NO PATTERN')      

                                                             )))))))


print "pattern extraction ran in = "
print("--- %s seconds ---" % (time.time() - np_time))



pattern extraction ran in = 
--- 99.5106501579 seconds ---

示例輸入和輸出代碼

        Description                                  pattern     

    0  **AGE RANGE: 6 YEARS** AND UP 10' LONG          AGE RANGE: 6 YEARS 
       STRING OF BEAUTIFUL LIGHTS MULTIPLE 
       LIGHT EFFECTS FADE IN AND OUT

    1  DIMENSIONS   OVERALL HEIGHT - TOP           AGE GROUP: -2 YEARS/3 TO 4 
       TO BOTTOM: 34.5'' OVERALL WIDTH - SIDE      YEARS/5 TO 6 YEARS/7 TO 8 
                                                   YEARS/7 TO 8 YEARS.
       TO SIDE: 20''  OVERALL DEPTH - 
       FRONT TO BACK:      15''  COUNTER TOP 
       HEIGHT - TOP TO BOTTOM: 23''  OVERALL 
       PRODUCT WEIGHT: 38 LBS "   
       **"AGE GROUP: -2 YEARS/3 TO 4 YEARS/5 TO 6 
        YEARS/7 TO 8 YEARS**.

   2   THE FLAME-RETARDANT FOAM ALSO CONTAINS              AGED 1-5 YEARS
       ANTIMICROBIAL PROTECTION, SO IT WON'T GROW 
       MOLD OR BACTERIA IF IT GETS WET. THE 
       BRIGHTLY-COLORED 
       VINYL EXTERIOR IS EASY TO WIPE CLEAN. FOAMMAN 
       IS DESIGNED FOR KIDS **AGED 1-5 YEARS**

您可以嘗試以下幾種方法:

首先,您需要識別較慢的正則表達式。 例如,您可以使用https://regex101.com/觀察'steps'值。

我檢查了正則表達式,第5和第8是最慢的。

27800 steps = [a-z][a-z\s]+(?:month[s]?|year[s]?)[\w\s]+age[s]?
 4404 steps= \b\d+[\w+\s]*?(?:\band\sup\b|\band\sabove\b|\band\sold[a-z]*\b)

您可以考慮優化這兩個正則表達式。

例如,你可以重寫這個\\b\\d+[\\w+\\s]*?(?:\\band\\sup\\b|\\band\\sabove\\b|\\band\\sold[az]*\\b)

進入這個\\b\\d+[\\w+\\s]*?(?:\\band\\s(?:up|above|old[az]*\\b))使用大約50%的步數。

對於其他正則表達式,有幾個選項。 您可以將其重寫為:

[AZ][A-LN-XZ\\s]+(?:(?:Y(?!EARS?)|M(?!ONTHS?))[A-LN-XZ\\s]+)*(?:MONTHS?|YEARS?)[\\w\\s]+AGE[S]?

哪個更快一點。 不多,雖然(27800 vs 23800)

但是,它真正加速它的目的是使它區分大小寫。

原始正則表達式區分大小寫僅執行3700步。 並優化了一個1470。

所以你可以只用大寫/小寫整個字符串並在你的(區分大小寫)正則表達式上使用它。 您可能甚至不需要像在樣本上那樣轉換字符串,無論如何它似乎都是大寫的。

另一件要看的是正在測試的正則表達式的順序。 如果某些正則表達式比其他正則數更可能匹配,則應首先測試它們。

如果你不能知道這些概率並且你認為它們或多或少相同,你可以考慮先把更簡單的正則表達式。 一如既往地測試一個難以匹配的復雜正則表達式是浪費時間。

最后,當你有這樣的選項(a | b | c)時,你可以考慮把最可能的東西放在開頭,原因和以前一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM