1

最近、Pythonを使用して数百万サイズのリストを処理しています。

ここにリストEがあります。これには1,470,000個の要素があり、各要素は2つの整数を持つリストです。

Eは次のようになります:[[1、3]、[2、4]、[4、7] ...]

最初の列と2番目の列の最大数をそれぞれ取得したいと思います。

リスト内包表記を使用して取得できます

m1 = max([e[0] for e in E])
m2 = max([e[1] for e in E])
return (m1, m2)

もう1つの方法は、zipを使用することです。

list(map(max, zip(*E)))

リスト内包表記は大きなリストを作成するので(さらに2回)、最初の考えでは2番目の方法の方が速いはずだと思います。しかし、リスト内包表記は非常に高速であり、zipを使用する方法は(cProfileを使用して)約10〜20倍遅くなります。

zipはそれほど遅くすべきではないと思います(さらに、リスト内包表記をそれほど速くするにはどうすればよいでしょうか?)誰かが理由を教えてもらえますか?

私はPython3.2を使用しています

PS Windowsタスクマネージャーを使用すると、Pythonが新しいリストを作成したことを示すメモリトレースも表示されません。黒魔術があるに違いない。

4

1 に答える 1

6

Python 2.7.3 と 3.3.0 の両方を使用してさまざまな方法をテストしましたが、結果を再現できません。

次のタイミングは Python 2.7.3 のものです (3.3.0 の結果も同様です)。

In [31]: E = [(random.randrange(0,1000),random.randrange(0,1000)) for _ in range(1470000)]

In [32]: %timeit max([e[0] for e in E]), max([e[1] for e in E])
1 loops, best of 3: 319 ms per loop

In [33]: %timeit max(e[0] for e in E), max(e[1] for e in E)
1 loops, best of 3: 343 ms per loop

In [36]: %timeit max(E, key=operator.itemgetter(0)), max(E, key=operator.itemgetter(1))
1 loops, best of 3: 314 ms per loop

In [38]: %timeit list(map(max, zip(*E)))
1 loops, best of 3: 307 ms per loop

私がテストしたすべてのメソッドのパフォーマンスはほぼ同じです。

パフォーマンスが気になる場合は、NumPy の使用を検討する必要があります。

In [39]: import numpy as np

In [40]: EE = np.array(E)

In [46]: %timeit EE.max(axis=0)
100 loops, best of 3: 3.21 ms per loop

ご覧のとおり、このデータ セットnumpy.max()では、私が試した純粋な Python メソッドよりも約 100 倍高速です。

于 2012-12-18T09:08:03.783 に答える