簡體   English   中英

列表中的元素大於或等於其他列表中的元素(沒有 for 循環?)

[英]Elements in list greater than or equal to elements in other list (without for loop?)

我有一個包含 1,000,000 個元素(數字)的列表,稱為 x,我想計算其中有多少等於或高於 [0.5,0.55,0.60,...,1]。 有沒有辦法在沒有 for 循環的情況下做到這一點?

現在我有以下代碼,它適用於 [0.5,...1] 間隔的特定值,比如說 0.5 並將其分配給 count 變量

count=len([i for i in x if i >= 0.5])

編輯:基本上我想避免的是這樣做......如果可能的話?

obs=[]
alpha = [0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1]

for a in alpha:
    count= len([i for i in x if i >= a])
    obs.append(count)

在此先感謝 最好的,米凱爾

我認為沒有循環是不可能的,但是您可以對數組x進行排序,然后您可以使用bisect模塊( doc )來定位插入點(索引)。

例如:

x = [0.341, 0.423, 0.678, 0.999, 0.523, 0.751, 0.7]
    
alpha = [0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1]

x = sorted(x)

import bisect

obs = [len(x) - bisect.bisect_left(x, a) for a in alpha]

print(obs)

將打印:

[5, 4, 4, 4, 3, 2, 1, 1, 1, 1, 0]

筆記:

sorted()具有復雜度n log(n)bisect_left() log(n)

您可以使用 numpy 和 boolean 索引:

>>> import numpy as np
>>> a = np.array(list(range(100)))
>>> a[a>=50].size
50

編輯:如果您已經在使用 NumPy,您可以簡單地執行以下操作:

import numpy as np

# Make random data
np.random.seed(0)
x = np.random.binomial(n=20, p=0.5, size=1000000) / 20
bins = np.arange(0.55, 1.01, 0.05)
# One extra value for the upper bound of last bin
bins = np.append(bins, max(bins.max(), x.max()) + 1)
h, _ = np.histogram(x, bins)
result = np.cumsum(h)
print(result)
# [280645 354806 391658 406410 411048 412152 412356 412377 412378 412378]

如果您正在處理大型 arrays 數字,您可以考慮使用NumPy 但是,如果您使用的是簡單的 Python 列表,您可以這樣做,例如:

def how_many_bigger(nums, mins):
    # List of counts for each minimum
    counts = [0] * len(mins)
    # For each number
    for n in nums:
        # For each minimum
        for i, m in enumerate(mins):
            # Add 1 to the count if the number is greater than the current minimum
            if n >= m:
                counts[i] += 1
    return counts

# Test
import random
# Make random data
random.seed(0)
nums = [random.random() for _ in range(1_000_000)]
# Make minimums
mins = [i / 100. for i in range(55, 101, 5)]
print(mins)
# [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0]
count = how_many_bigger(nums, mins)
print(count)
# [449771, 399555, 349543, 299687, 249605, 199774, 149945, 99928, 49670, 0]

即使您不使用 for 循環,內部方法也會使用它們。 但是有效地迭代它們。

您可以在 function 下方使用,而無需從您的末端進行循環。

x = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
l = list(filter(lambda _: _ > .5 , x))
print(l)

根據評論,您可以使用 numpy,因此使用np.searchsortedalpha簡單地插入到x的排序版本中。 指數將是你的計數。

如果您可以就地對x進行排序:

x.sort()
counts = x.size - np.searchsorted(x, alpha)

如果不,

counts = x.size - np.searchsorted(np.sort(x), alpha)

這些計數假設您想要x < alpha 要獲得<=添加關鍵字side='right'

np.searchsorted(x, alpha, side='right')

附言

這條線路有幾個重大問題

count = len([i for i in x if i >= 0.5])

首先,您正在創建所有匹配元素的列表,而不是僅僅計算它們。 數他們做

count = sum(1 for i in x if i >= threshold)

現在的問題是,您正在為每個 alpha 對整個數組進行線性傳遞,這是不必要的。

正如我在@Andrej Kesely 的回答下評論的那樣,假設我們有N = len(x)M = len(alpha) 您的實現是O(M * N)時間復雜度,而排序給您O((M + N) log N) 對於M << N (小alpha ),您的復雜性大約為O(N) ,優於O(N log N) 但是對於M ~= N ,你的接近O(N^2)與我的O(N log N)

暫無
暫無

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

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