簡體   English   中英

如何按范圍對列表元素進行分組/計數

[英]How to group / count list elements by range

如果我的x列表和y列表是:

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

我希望返回值是一個字典,其中包含的元素數小於x值:

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

我有一個非常大的列表,所以我希望有一個更好的方法來做這個不涉及緩慢的嵌套for循環。 我看過集合.Counter和itertools似乎都沒有提供分組方式。 有沒有可以做到這一點的內置?

您可以使用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})

如果你願意使用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]))

為了使這個dict:

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

簡短回答:

dict(zip(x, [[n_y for n_y in y if n_y < n_x] for n_x in x]))

答案很長

首先,我們需要迭代y來檢查哪個成員小於某個成員。 如果我們這樣做10,我們得到這個:

>>> [n_y for n_y in y if n_y < 10]
[1, 2, 3]

然后我們需要讓'10'成為一個變量,然后拋出x:

>>> [[n_y for n_y in y if n_y < n_x] for n_x in x]
[[1, 2, 3], [1, 2, 3, 15], [1, 2, 3, 15, 22, 27]]

最后,我們需要使用原始x添加此結果。 這是拉鏈派上用場的時候:

>>> zip(x, [[n_y for n_y in y if n_y < n_x] for n_x in x])
[(10, [1, 2, 3]), (20, [1, 2, 3, 15]), (30, [1, 2, 3, 15, 22, 27])]

這給出了一個元組列表,所以我們應該在它上面輸出dict來得到最終結果:

>>> dict(zip(x, [[n_y for n_y in y if n_y < n_x] for n_x in x]))
{10: [1, 2, 3], 20: [1, 2, 3, 15], 30: [1, 2, 3, 15, 22, 27]}

如果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})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM