1

さらに下を見る:

編集しようとしている非常に長い文字列に変換したリストがあります。収集できるように、それは tempString と呼ばれます。おそらくいくつかの異なる正規表現サブルーチンであるため、動作するのに時間がかかります。それらは次のとおりです。

tempString = ','.join(str(n) for n in coords)
tempString = re.sub(',{2,6}', '_', tempString)
tempString = re.sub("[^0-9\-\.\_]", ",", tempString)
tempString = re.sub(',+', ',', tempString)
clean1 = re.findall(('[-+]?[0-9]*\.?[0-9]+,[-+]?[0-9]*\.?[0-9]+,'
                 '[-+]?[0-9]*\.?[0-9]+'), tempString)
tempString = '_'.join(str(n) for n in clean1)
tempString = re.sub(',', ' ', tempString)

基本的には、コンマと 4 つの float/int の約 100 万から 500 万セット (両方の混合が可能) を含む長い文字列です。

-5.65500020981,6.88999986649,-0.454999923706,1,,,-5.65500020981,6.95499992371,-0.454999923706,1,,,

各セットの 4 番目の数字は必要ありません/必要ありません。基本的には、文字列をスペースで区切られた 3 つのフロートを持つリストに分割しようとしています。

上記のコードは問題なく動作しますが、ご想像のとおり、大きな文字列ではかなり時間がかかります。

私は解決策のためにここで多くの調査を行いましたが、それらはすべて単語に向けられているようです。つまり、ある単語を別の単語に置き換えています。


編集: わかりましたので、これは私が現在使用しているソリューションです:

def getValues(s):
    output = []
    while s:
        # get the three values you want, discard the 3 commas, and the 
        # remainder of the string
        v1, v2, v3, _, _, _, s = s.split(',', 6)
        output.append("%s %s %s" % (v1.strip(), v2.strip(), v3.strip()))         
    return output
coords = getValues(tempString)

これをさらに高速化するためのアドバイスはありますか? いくつかのテストを実行した後でも、私が望んでいるよりもはるかに時間がかかります。

私はnumPyをちらっと見てきましたが、正直なところ、上記を使用する方法がまったくわかりません。上記が行われ、値がクリーンアップされた後、numPyでより効率的に使用できることを理解していますが、方法がわかりませんNumPy は上記に適用できます。

上記の 50,000 セットをクリーンアップするには約 20 分かかります。100 万セットの完全なストリングでどれくらいかかるか想像できません。最初にデータをエクスポートしたプログラムが、100 万セットに対して約 30 秒しかかからなかったことは驚くべきことです。

4

2 に答える 2

2

サンプルデータに基づく:

>>> s = "-5.65500020981,6.88999986649,-0.454999923706,1,,,-5.65500020981,6.95499992371,-0.454999923706,1,,,"
>>> def getValues(s):
...     output = []
...     while s:
...         # get the three values you want, discard the 3 commas, and the 
...         # remainder of the string
...         v1, v2, v3, _, _, _, s = s.split(',', 6)
...         output.append("%s %s %s" % (v1, v2, v3))
...         
...     return output
>>> getValues(s)
['-5.65500020981 6.88999986649 -0.454999923706', '-5.65500020981 6.95499992371 -0.454999923706']

...これらの解析された値をリスト内の文字列として取得すると、他に必要なことは何でも実行できます。

または、必要に応じて、ジェネレータを使用して、リターン文字列全体を一度に作成する必要がないようにします。

>>> def getValuesGen(s):
...     while s:
...         v1, v2, v3, _, _, _, s = s.split(',', 6)
...         yield "%s %s %s" % (v1, v2, v3)
>>> for v in getValuesGen(s):
...     print v
...     
... 
-5.65500020981 6.88999986649 -0.454999923706
-5.65500020981 6.95499992371 -0.454999923706

次のように、短い文字列のセットを継続的に作成して処理するのではなく、長いリスト,,,をコンマのセットで事前に分割するアプローチを試してみることもできます。

>>> def getValues(s):
...     # split your long string into a list of chunked strings
...     strList = s.split(",,,")
...     for chunk in strList:
...         if chunk:
...         # ...then just parse apart each individual set of data values
...             vals = chunk.split(',')
...             yield "%s %s %s" % (vals[0], vals[1], vals[2])
>>> for v in getValues(s10):
...     print v
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454
-5.1  6.8  -0.454

このような巨大なデータセットを処理していて速度の問題がある場合、NumPyのようにCでハードワークを実行しているモジュールに物事をプッシュすることが理にかなっています。

于 2012-10-19T21:51:48.117 に答える
0

正規表現で何も変更せずにメモリの浪費を減らす1つの方法は、のre.finditer()代わりにメソッドを使用することですre.findall()。これは、文字列全体を単一のリストオブジェクトに読み込むのではなく、値を1つずつ繰り返し処理します。http://docs.python.org/library/re.html#re.finditer

于 2012-10-19T21:51:40.940 に答える