2

次のように、互いに対応するリストがいくつかあります。

ID_number = [1, 2, 3, 4, 5, 6, ...]
x_pos = [43.2, 53.21, 34.2, ...]
y_pos = [32.1, 42.1, 8.2, ...]
z_pos = [1.3, 67.1, 24.3, ...]

ID_number に基づいてデータの並べ替え、プル、および操作を実行できるようにしたいので、これらのリストから次のように辞書を作成します。

dictionary = {'id1':[x_pos1, y_pos1, z_pos1], 'id2':[x_pos2, y_pos2, z_pos2], ...}

ここで、キーは ID 番号で、値はその ID 番号に対応するデータを含むリストです。Pythonでこれを効率的に行うにはどうすればよいですか?

4

3 に答える 3

4

2 回使用zip:

>>> ids = [1,2,3,4]
>>> x_pos = [1.32, 2.34, 5.56, 8.79]
>>> y_pos = [1.2, 2.3, 3.4, 4.5]
>>> z_pos = [3.33, 2.22, 10.98, 10.1]
>>> dict(zip(ids, zip(x_pos, y_pos, z_pos)))
{1: (1.32, 1.2, 3.33), 2: (2.34, 2.3, 2.22), 3: (5.56, 3.4, 10.98), 4: (8.79, 4.5, 10.1)}

genexp とのタイミング比較:

>>> import timeit
>>> timeit.timeit('dict(zip(ids, zip(x_pos, y_pos, z_pos)))', 'from __main__ import ids, x_pos, y_pos, z_pos')
1.6184730529785156
>>> timeit.timeit('dict((x[0], x[1:]) for x in zip(ids, x_pos, y_pos, z_pos))', 'from __main__ import ids, x_pos, y_pos, z_pos')
2.5186140537261963

したがって、zip2 回使用すると、ジェネレーター式を使用するよりも約 1.5 倍高速になります。明らかに、結果はイテラブルのサイズに依存しますが、 double を使用するzipと、少なくとも CPython 2 では常に明示的なループよりも高速になるという事実に自信を持っています。ジェネレーターの例外またはforループは、 への 1 回の呼び出しよりもはるかに多くの作業をインタープリターに必要としzipます。これにより、反復プロセスからいくらかのオーバーヘッドが取り除かれます。

itertools.izip代わりに使用zipしてもタイミングはあまり変わりませんが、大きなデータセットのメモリ効率が大幅に向上します。

于 2013-04-22T20:55:10.313 に答える
2

zip()これを達成するのに非常に便利です。例えば:

>>> ID_number = [1,2,3]
>>> x_pos = [43.2, 53.21, 34.2]
>>> y_pos = [32.1, 42.1, 8.2]
>>> z_pos = [1.3, 67.1, 24.3]
>>> dict((x[0], x[1:]) for x in zip(ID_number, x_pos, y_pos, z_pos))
{1: (43.200000000000003, 32.100000000000001, 1.3), 2: (53.210000000000001, 42.100000000000001, 67.099999999999994), 3: (34.200000000000003, 8.1999999999999993, 24.300000000000001)}

データ セットが非常に大きい場合は、代わりにzip()を使用して、 がデータ セット全体のまったく新しいコピーを作成することを回避できますitertools.izip()。この関数は、新しい構造全体をメモリに保持するのではなく、要求時に圧縮された各要素を提供するイテレータを返します。(結果は同じになりますが、大規模なデータ セットでは高速になるはずです。)

>>> import itertools
>>> dict((x[0], x[1:]) for x in itertools.izip(ID_number, x_pos, y_pos, z_pos))
{1: (43.200000000000003, 32.100000000000001, 1.3), 2: (53.210000000000001, 42.100000000000001, 67.099999999999994), 3: (34.200000000000003, 8.1999999999999993, 24.300000000000001)}
于 2013-04-22T20:51:52.067 に答える
0
dictionary = {'id' + str(i): [x, y, z]
              for i, x, y, z in zip(ID_number, x_pos, y_pos, z_pos)}

大規模なデータセットの場合、おそらくitertools'を使用すると高速になりizip()ます。

于 2013-04-22T20:55:29.257 に答える