質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

7338閲覧

Pytho3.X 複数の文字列置換の高速化

KK-31

総合スコア22

CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2019/11/25 02:58

編集2019/11/25 02:59

Python3.X系で、文字列を高速に置換する方法を試行錯誤しておりますが、中々高速化が出来ません。
CPUで並列計算させることはできるのですが、これ以上速度を上げる方法はないでしょうか?
実際には100万件くらいのデータと、辞書が20万語ほどあるデータを置換するプログラムを組んでいます。

環境:Azure VM NV6インスタンス(Vm cpu:6core)

試した方法

Python

1#replaceを使った方法 2import random 3import time 4from tqdm import tqdm 5 6def replacer(text,replace_list): 7 rtn_val = "" 8 for item in replace_list: 9 rtn_val = text.replace(item,"") #置換後文字は、空白(文章の一部を削除したい 10 return rtn_val 11 12 13 14text_list = ["あいうえお、かきくけこ、さしすせそ!"]* 10000 15replace_list =["あい" + str(random.random()) for _ in range(10000)] #わざと乱数をつけて、辞書の数を多くする 16replace_list += ["あい"] 17start = time.time() 18#replaced_list = [replacer(sentence,replace_list) for sentence in text_list] 19replaced_list = [replacer(sentence,replace_list) for sentence in tqdm(text_list)] #tqdmで可視化用 20process_time = time.time() - start 21print(process_time) 22 23100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 10000/10000 [00:33<00:00, 294.98it/s] 2433.90771460533142

re.subを使った、方法でも試しましたが、遅いです。

Python

1import random 2import time 3import re 4from tqdm import tqdm 5def trans_word2(text,replace_dict): 6 return re.sub('({})'.format('|'.join(map(re.escape, replace_dict.keys()))), lambda m: replace_dict[m.group()], text) 7 8 9text_list = ["あいうえお、かきくけこ、さしすせそ!"]* 10000 10replace_list = ["あい" + str(random.random()) for _ in range(10000)] #わざと乱数をつけて、辞書の数を多くする 11replace_dict =dict([(item,"") for item in replace_list]) 12replace_dict["あい"] = "" 13start = time.time() 14replaced_list = [trans_word2(sentence,replace_dict) for sentence in tqdm(text_list)] #tqdmで可視化用 15process_time = time.time() - start 16print(process_time) 17 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████▍ | 10000/10000 [12:59<00:00, 12.71it/s] 18779.81234680347942

ご教授のほどよろしくお願いいたします。

TaniguchiTakaki👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2019/11/25 04:49

意図している置換処理の内容を詳しく説明していただいた方が回答しやすいです。また、正規表現を使わないバージョンのコードは間違っている気がします(rtn_val = text.replace(item,"")で意図した結果になるでしょうか?)。
KK-31

2019/11/25 05:07

対象のリストに対して、置換したい辞書リストを使って、高速に処理したいです。 意図した動きになっています。(rtn_val = text.replace(item,"")
hayataka2049

2019/11/25 05:10

たとえば replacer("ほげふがぴよ", ["ほげ", "ふが", "ぴよ"]) の結果は 'ほげふが' で良いということですか?
hayataka2049

2019/11/25 05:14 編集

あと、これもたぶん問題になるので先に書いておくと、 replacer("ぴふほげがよ", ["ほげ", "ふが", "ぴよ"]) が空文字列になる処理方法とならない処理方法もそれぞれ考えられます。どちらを意図しているのかはわかりません。 ということで繰り返しになりますが、 >意図している置換処理の内容を詳しく説明していただいた方が回答しやすいです。 (できるだけ詳しく、厳密に定義して説明してほしい。場合によってはアドホックな最適化があるかもしれないしさ)
guest

回答2

0

ベストアンサー

正規表現のプレコンパイルを使ったらどうでしょう。手元では最初のコードの8倍ぐらいになりました。

Python

1import random 2import time 3import re 4from tqdm import tqdm 5 6 7# コンパイル済みの正規表現を受け取る 8def trans_word2(text, pat): 9 return pat.sub(lambda m: replace_dict[m.group()], text) 10 11 12text_list = ["あいうえお、かきくけこ、さしすせそ!"] * 10000 13replace_list = ["あい" + str(random.random()) 14 for _ in range(10000)] # わざと乱数をつけて、辞書の数を多くする 15replace_dict = dict([(item, "") for item in replace_list]) 16replace_dict["あい"] = "" 17 18# ここでコンパイル 19pat = re.compile('({})'.format('|'.join(map(re.escape, replace_dict.keys())))) 20 21start = time.time() 22replaced_list = [trans_word2(sentence, pat) 23 for sentence in tqdm(text_list)] # tqdmで可視化用 24process_time = time.time() - start 25print(process_time)

投稿2019/11/25 04:13

編集2019/11/25 04:17
TaniguchiTakaki

総合スコア171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KK-31

2019/11/25 05:16

早いです!ありがとうございました。
guest

0

曖昧な記憶ですが、昔同じようなことをやってたことがあります。

subprocessでコマンド呼び出して置換させるか、C呼び出して置換させるかしたら早くなったような記憶があります。

投稿2019/11/25 03:31

yamato_user

総合スコア2321

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問