4

私のxリストとyリストが次の場合:

x = [10,20,30]
y = [1,2,3,15,22,27]

戻り値を x 値よりも少ない要素の数を持つ辞書にしたい:

{
    10:3,
    20:1,
    30:2,
}

私は非常に大きなリストを持っているので、遅いネストされた for ループを含まない、より良い方法があることを望んでいました。collections.Counter と itertools を見てきましたが、どちらもグループ化の方法を提供していないようです。これを行うことができる組み込みはありますか?

4

4 に答える 4

8

bisectモジュールとcollections.Counter以下を使用できます。

>>> import bisect
>>> from collections import Counter
>>> Counter(x[bisect.bisect_left(x, item)] for item in y)
Counter({10: 3, 30: 2, 20: 1})
于 2013-09-13T17:05:04.777 に答える
5

numpy を使用する場合は、基本的にヒストグラムを求めています。

x = [10,20,30]
y = [1,2,3,15,22,27]

np.histogram(y,bins=[0]+x)
#(array([3, 1, 2]), array([ 0, 10, 20, 30]))

これを辞書にするには:

b = np.histogram(y,bins=[0]+x)[0]
d = { k:v for k,v in zip(x, b)}

短いリストの場合、これは価値がありませんが、リストが長い場合は次のようになります。

In [292]: y = np.random.randint(0, 30, 1000)

In [293]: %%timeit
   .....: b = np.histogram(y, bins=[0]+x)[0]
   .....: d = { k:v for k,v in zip(x, b)}
   .....: 
1000 loops, best of 3: 185 µs per loop

In [294]: y = list(y)

In [295]: timeit Counter(x[bisect.bisect_left(x, item)] for item in y)
100 loops, best of 3: 3.84 ms per loop

In [311]: timeit dict(zip(x, [[n_y for n_y in y if n_y < n_x] for n_x in x]))
100 loops, best of 3: 3.75 ms per loop
于 2013-09-13T17:05:33.840 に答える
0

の値の間のステップxが常にの場合、次の10ようにします。

>>> y = [1,2,3,15,22,27]
>>> step = 10
>>> from collections import Counter
>>> Counter(n - n%step + step for n in y)
Counter({10: 3, 30: 2, 20: 1})
于 2013-09-13T17:50:21.537 に答える