2016-11-29 8 views
2

私は20GB以上のニュース記事データを渡しているPythonスクリプトを書いています。 "日付"(100行ごとに1回)の1行ごとに、その記事のタイトルが財務であるかどうかを確認する必要があります。タイトルは形式である:Regex Performance Python

SOME BIG NEWS HAPPENED TO CISCO 

私のコードは、(私がsetにキャッシュされている)S & P 500内のすべての会社名をループ、タイトルが一致するかどうかを確認しようとします。

line = "SOME BIG NEWS HAPPENED TO CISCO" 
for company in company_names: 
    pattern = re.compile("(\\b" + company_name + "\\b)", flags=re.IGNORECASE) 
    if re.search(pattern, line): 
     do_something() 

プログラムをテストするために単なる100,000行以上を別のファイルにコピーしたところ、347秒かかりました。このレートでは、すべてのデータを1週間以上上回ることはありません。

私はファイルをループするのに時間がかかる可能性があることを理解しようとしています。 PythonはコンパイルされたDFAをすべてキャッシュできないため、新しい記事が出現するたびに〜500を構築する必要がありますか?

また、このような長い実行時間の原因になる現在の正規表現には別の問題がありますか?

ご協力いただければ幸いです。

+0

あなたはそれらをすべて500回を再コンパイルする対プリコンパイルされた正規表現のセットを維持してみてください可能性があります(または、TigerhawkT3の''.join(filter(str.isalpha, line.lower())).split(): do_something()を使用)

また、一般的な単語を取得するためにset intersectionを使用することができます。 – dawg

+0

ありがとう@ダウグ、私は実際に投稿した直後に同じことを考えていました。私はテストしようとしています。 –

+0

regexをまったく使用せず、代わりに 'company_name in line'を試してみることもできます。それはずっと速くなければならないが、同じ複雑さでなければならない。 –

答えて

3

事前にコンパイルされたパターンを辞書に入れてみてください。以下のような何か:

companies=('Cisco', 'Apple', 'IBM', 'GE') 
patterns={co:re.compile("(\\b" + co + "\\b)", flags=re.IGNORECASE) for co in companies} 
line = "SOME BIG NEWS HAPPENED TO CISCO" 
for co, pat in patterns.items(): 
    if re.search(pat, line): 
     print "'{}' found in: '{}'".format(co, line) 

それとも、あなたはPythonの文字列メソッド試してみてください:ライン上[e.strip(',.!:;') for e in line.lower().split()]を行うことは正規表現で鈍感な単語の境界とケースを使用してほぼ同等であることを

words=line.lower().split()  
for co in [e.lower() for e in companies]: 
    if co in words: 
     print "'{}' found in: '{}'".format(co, line)  

注意を。

>>> line2="Apple acquires Cisco: Generally a good thing" 
>>> set(e.lower() for e in companies) & set(e.strip(',.!:;') for e in line2.lower().split()) 
set(['cisco', 'apple']) 
+1

'.lower()。split()'は等価ではありません。見出しに記載されている会社名は完全一致でなければなりません。先頭または末尾の句読点(例:「会社名の難しさ、解雇が予想される」など)が壊れてしまうことを意味します。 – TigerhawkT3

+0

@ TigerhawkT3:はい - 正しい - それを修正してください。あなたはそれを定期的に拾う! – dawg

+1

スニペットの修正:スペースを削除します。おっとっと。 '' '.join(c.strip()やc.isalpha())でないならline.lower(cのc)。split():do_something() 'おそらく良いでしょう。 – TigerhawkT3