繁体   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