![](/img/trans.png)
[英]Combine n elements in first half of list with elements in other half of a list, if number of elements in a list is greater than 2
[英]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.searchsorted
將alpha
簡單地插入到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.