7

私は常にアラビア語のテキストファイルに取り組んでおり、エンコードの問題を回避するために、バックウォルターのスキーム(http://www.qamus.org/transliteration.htm)に従ってアラビア語の文字を英語に音訳します。

これが私のコードですが、400kbのような小さなファイルでも非常に遅いです。それを速くするためのアイデア?

ありがとう

     def transliterate(file):
          data = open(file).read()
          buckArab = {"'":"ء", "|":"آ", "?":"أ", "&":"ؤ", "<":"إ", "}":"ئ", "A":"ا", "b":"ب", "p":"ة", "t":"ت", "v":"ث", "g":"ج", "H":"ح", "x":"خ", "d":"د", "*":"ذ", "r":"ر", "z":"ز", "s":"س", "$":"ش", "S":"ص", "D":"ض", "T":"ط", "Z":"ظ", "E":"ع", "G":"غ", "_":"ـ", "f":"ف", "q":"ق", "k":"ك", "l":"ل", "m":"م", "n":"ن", "h":"ه", "w":"و", "Y":"ى", "y":"ي", "F":"ً", "N":"ٌ", "K":"ٍ", "~":"ّ", "o":"ْ", "u":"ُ", "a":"َ", "i":"ِ"}    
          for char in data: 
               for k, v in arabBuck.iteritems():
                     data = data.replace(k,v)                 
      return data
4

5 に答える 5

8

2021 年 10 月の編集

最近リリースされた python パッケージがこれ (およびそれ以上) を実行するため、この投稿を読んでいる人は、他のすべての回答を無視して Camel Tools を使用する必要があります。(Nizar Habash と NYU アブダビの彼のチームは、これを開発し、アクセスしやすくするために素晴らしいです!)

::python
from camel_tools.utils.charmap import CharMapper
sentence = "ذهبت إلى المكتبة."
print(sentence)

ar2bw = CharMapper.builtin_mapper('ar2bw')

sent_bw = ar2bw(sentence)
print(sent_bw)

出力:

هبت إلى المكتبة.
*hbt <lY Almktbp.

ここでインストール手順とチュートリアルを見つけることができます: https://github.com/CAMeL-Lab/camel_tools


古い回答 ちなみに、誰かが既にこれを行うスクリプトを書いているので、自分で時間を費やす前にそれをチェックしたいかもしれません: buckwalter2unicode.py

おそらく必要以上の機能を備えていますが、すべてを使用する必要はありません。私は 2 つの辞書と transliterateString 関数 (いくつかの調整を加えたものだと思います) だけをコピーし、それを私のサイトで使用しています。

編集: 上記のスクリプトは私が使用しているものですが、特に大規模なコーパスの場合、replace を使用するよりもはるかに遅いことがわかりました。これは私が最終的に得たコードで、よりシンプルで高速に見えます (これは辞書 buck2uni を参照しています)。

def transString(string, reverse=0):
    '''Given a Unicode string, transliterate into Buckwalter. To go from
    Buckwalter back to Unicode, set reverse=1'''

    for k, v in buck2uni.items():
        if not reverse:
            string = string.replace(v, k)
        else:
            string = string.replace(k, v)

    return string
于 2012-10-16T19:03:32.537 に答える
5

文字変換を行う必要がある場合はいつでもstr.translate、使用する方法です。

>>> import timeit
>>> buckArab = {"'":"ء", "|":"آ", "?":"أ", "&":"ؤ", "<":"إ", "}":"ئ", "A":"ا", "b":"ب", "p":"ة", "t":"ت", "v":"ث", "g":"ج", "H":"ح", "x":"خ", "d":"د", "*":"ذ", "r":"ر", "z":"ز", "s":"س", "$":"ش", "S":"ص", "D":"ض", "T":"ط", "Z":"ظ", "E":"ع", "G":"غ", "_":"ـ", "f":"ف", "q":"ق", "k":"ك", "l":"ل", "m":"م", "n":"ن", "h":"ه", "w":"و", "Y":"ى", "y":"ي", "F":"ً", "N":"ٌ", "K":"ٍ", "~":"ّ", "o":"ْ", "u":"ُ", "a":"َ", "i":"ِ"}
>>> def repl(data, table):
...     for k,v in table.iteritems():
...         data = data.replace(k, v)
... 
>>> def trans(data, table):
...     return data.translate(table)
... 
>>> T = u'This is a test to see how fast is translitteration'
>>> timeit.timeit('trans(T, buckArab)', 'from __main__ import trans, T, buckArab', number=10**6)
6.766200065612793
>>> T = 'This is a test to see how fast is translitteration' #in python2 requires ASCII string
>>> timeit.timeit('repl(T, buckArab)', 'from __main__ import repl, T, buckArab', number=10**6)
12.668706893920898

ご覧のとおり、小さな文字列str.translateでも 2 倍高速です。

于 2012-10-06T08:45:51.467 に答える
3

キャラクターごとに同じ作業をやり直しています。を実行すると、ファイル全体で特定の文字が出現するすべてdata = data.replace(k, v)が置き換えられます。ただし、音訳ペアごとに 1 回だけ実行する必要がある場合は、これをループで何度も実行します。最も外側のループを削除するだけで、コードが大幅に高速化されます。

さらに最適化する必要がある場合は、文字列のtranslate メソッドを参照してください。それがパフォーマンス面でどのように機能するかはわかりません。

于 2012-10-06T06:47:57.327 に答える
2

@larapsodiaの答えを拡張すると、辞書付きの完全なコードがここにあります:

# -*- coding: utf-8 -*-

# Arabic Transliteration based on Buckwalter
# dictionary source is buckwalter2unicode.py http://www.redhat.com/archives/fedora-extras-commits/2007-June/msg03617.html 

buck2uni = {"'": u"\u0621", # hamza-on-the-line
            "|": u"\u0622", # madda
            ">": u"\u0623", # hamza-on-'alif
            "&": u"\u0624", # hamza-on-waaw
            "<": u"\u0625", # hamza-under-'alif
            "}": u"\u0626", # hamza-on-yaa'
            "A": u"\u0627", # bare 'alif
            "b": u"\u0628", # baa'
            "p": u"\u0629", # taa' marbuuTa
            "t": u"\u062A", # taa'
            "v": u"\u062B", # thaa'
            "j": u"\u062C", # jiim
            "H": u"\u062D", # Haa'
            "x": u"\u062E", # khaa'
            "d": u"\u062F", # daal
            "*": u"\u0630", # dhaal
            "r": u"\u0631", # raa'
            "z": u"\u0632", # zaay
            "s": u"\u0633", # siin
            "$": u"\u0634", # shiin
            "S": u"\u0635", # Saad
            "D": u"\u0636", # Daad
            "T": u"\u0637", # Taa'
            "Z": u"\u0638", # Zaa' (DHaa')
            "E": u"\u0639", # cayn
            "g": u"\u063A", # ghayn
            "_": u"\u0640", # taTwiil
            "f": u"\u0641", # faa'
            "q": u"\u0642", # qaaf
            "k": u"\u0643", # kaaf
            "l": u"\u0644", # laam
            "m": u"\u0645", # miim
            "n": u"\u0646", # nuun
            "h": u"\u0647", # haa'
            "w": u"\u0648", # waaw
            "Y": u"\u0649", # 'alif maqSuura
            "y": u"\u064A", # yaa'
            "F": u"\u064B", # fatHatayn
            "N": u"\u064C", # Dammatayn
            "K": u"\u064D", # kasratayn
            "a": u"\u064E", # fatHa
            "u": u"\u064F", # Damma
            "i": u"\u0650", # kasra
            "~": u"\u0651", # shaddah
            "o": u"\u0652", # sukuun
            "`": u"\u0670", # dagger 'alif
            "{": u"\u0671", # waSla
}

def transString(string, reverse=0):
    '''Given a Unicode string, transliterate into Buckwalter. To go from
    Buckwalter back to Unicode, set reverse=1'''

    for k, v in buck2uni.items():
      if not reverse:
            string = string.replace(v, k)
      else:
            string = string.replace(k, v)

    return string


>>> print(transString(u'مرحبا'))
mrHbA
>>> print(transString('mrHbA', 1))
مرحبا
>>>

これは、GPLv2 以降でライセンスされているhttp://www.redhat.com/archives/fedora-extras-commits/2007-June/msg03617.htmlからの抜粋です。

于 2016-10-21T22:21:50.237 に答える