2016-08-31 9 views
0

いくつかの配列処理を最適化する方法を理解し、postgis互換のデータ型を対象にしています。入力されたデータは、次のようになります。これは出力されnumpyでリストの理解力を列挙しますか?

import json 
import numpy 
import ppygis 
import time 

start_time = time.time() 
with open('example.json') as fp: 
    d = json.load(fp) 

print "file load time:" 
print time.time() - start_time 

""" 
standard python 
""" 

start_time = time.time() 
py_array = d['items'][0]['coords'] 

print "array creation:" 
print time.time() - start_time 

start_time = time.time() 
a = [' '.join(map(str, c)) for c in py_array] 
b = '(' + ') ('.join(map(str, a)) + ')' 

print "python array string processing time:" 
print time.time() - start_time 

start_time = time.time() 
c = [ppygis.Point(p[0], p[1], p[2]) for p in py_array] 

print "python array ppygis:" 
print time.time() - start_time 

""" 
numpy 
""" 

start_time = time.time() 
numpy_array = numpy.array(d['items'][0]['coords']) 

print "numpy array creation:" 
print time.time() - start_time 

start_time = time.time() 
a = [' '.join(map(str, c)) for c in numpy_array] 
b = '(' + ') ('.join(map(str, a)) + ')' 

print "numpy array string processing time:" 
print time.time() - start_time 

start_time = time.time() 
c = [ppygis.Point(p[0], p[1], p[2]) for p in numpy_array] 

print "numpy array ppygis:" 
print time.time() - start_time 

file load time: 
8.29696655273e-05 
array creation: 
2.86102294922e-06 
python array string processing time: 
1.09672546387e-05 
python array ppygis: 
8.10623168945e-06 
numpy array creation: 
1.31130218506e-05 
numpy array string processing time: 
0.000116109848022 
numpy array ppygis: 
3.60012054443e-05 

のでnumpyのアレイを使用して操作しているのはなぜ

ここ
{ 
    "items": [ 
     { 
      "id": 10000, 
      "coords": [[644, 1347, 1], [653, 1353, 1], [637, 1358, 1], [633, 1362, 1]] 
     } 
] 
} 

は、私が試したものです通常のpython配列よりもはるかに遅いですか?

答えて

0

一般的に、numpy配列の反復操作はリストの同等操作よりも遅くなります。リストから配列を作成するには、最初の作成であろうと中間的なステップであろうと、時間がかかるからです。 Numpy配列は、コンパイルされたオペレーションを実行するときにスピードの利点を得ます。つまり、反復は、解釈されたスピードではなくコンパイルされたスピードで行われます。あなたの例では

は、辞書ソースは

In [372]: arr = d['items'][0]['coords'] 
In [373]: arr 
Out[373]: [[644, 1347, 1], [653, 1353, 1], [637, 1358, 1], [633, 1362, 1]] 
In [374]: narr=np.array(arr) 
In [375]: narr.shape 
Out[375]: (4, 3) 
In [376]: narr 
Out[376]: 
array([[ 644, 1347, 1], 
     [ 653, 1353, 1], 
     [ 637, 1358, 1], 
     [ 633, 1362, 1]]) 

は、すべての値に1を加算する簡単なタスクを取る重要ではありません。

In [379]: timeit narr+1 # compiled operation 
The slowest run took 16.25 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 2.09 µs per loop 
In [380]: timeit [[i+1 for i in j] for j in arr] 
100000 loops, best of 3: 5.67 µs per loop 
In [381]: timeit np.array([[i+1 for i in j] for j in narr]) 
The slowest run took 28.05 times longer than the fastest. This could mean that an intermediate result is being cached. 
10000 loops, best of 3: 32.3 µs per loop 

あなたの文字列の書式の場合:

In [383]: a=[' '.join(map(str, c)) for c in arr] 
In [384]: a 
Out[384]: ['644 1347 1', '653 1353 1', '637 1358 1', '633 1362 1'] 
In [385]: b='('+') ('.join(map(str,a)) + ')' 
In [386]: b 
Out[386]: '(644 1347 1) (653 1353 1) (637 1358 1) (633 1362 1)' 

または地図の代わりにリスト内包表記:

In [396]: '(%s)'%') ('.join([' '.join([str(i) for i in c]) for c in arr]) 
Out[396]: '(644 1347 1) (653 1353 1) (637 1358 1) (633 1362 1)' 

narr.tolist()でこの同じ処理を実行すると、ほぼ同じくらい良く、narrを直接処理するよりも優れています。

[c for c on narr]は4つの配列のリストを生成します。 [str(i) for i in c]は、これらのサブ配列のそれぞれに対して反復処理が必要です。

numpy配列からPointオブジェクトのリストを作成することは、この構造の使い方が悪いことです。

structuredの配列を作成し、ポイントのセット全体に対して 'x'値にアクセスできます。これは、構造全体、または少なくとも行と列全体で作業したいときに使用するキー配列です。

In [436]: parr = narr.view([('x', '<i4'), ('y', '<i4'), ('z', '<i4')]).squeeze() 

In [437]: parr 
Out[437]: 
array([(644, 1347, 1), (653, 1353, 1), (637, 1358, 1), (633, 1362, 1)], 
     dtype=[('x', '<i4'), ('y', '<i4'), ('z', '<i4')]) 

In [438]: parr[0] 
Out[438]: (644, 1347, 1) 

In [439]: parr['x'] 
Out[439]: array([644, 653, 637, 633]) 
+0

詳細情報をお寄せいただきありがとうございます。私はまだパフォーマンスは得られていませんが、進歩しているように感じています。 – jfarr

+0

閉鎖についてどう思いますか?リンクされた質問は役に立ちますか?どのようなパフォーマンスが期待されますか?あなたのケースの1つは、文字列の書式設定です。もう1つはオブジェクトの作成です。どちらも、コンパイルされた配列の機能を大いに活用しません。 – hpaulj

+0

私はこれに取り組んでいる間に要件が変更されました。私のソースデータはシェイプファイルになります:)私はいつか個人的な開発のためにこれに戻りたいと思いますが、今は帯域幅がありません。このスレッドを更新します。私はこの作業を再びやっています。助けてくれてありがとう! – jfarr

関連する問題