簡體   English   中英

遍歷范圍並返回不在任何范圍內的范圍?

[英]Iterate through ranges and return those not in any range?

我有一個浮動列表。

values = [2.3, 6.4, 11.3]

我想要做的是從大小delta = 2列表中的每個值中找到一個范圍,然后遍歷另一個范圍的浮點數並將每個浮點數與每個范圍進行比較,然后返回不屬於任何范圍的浮點數。

到目前為止我所擁有的是,

not_in_range =[]
for x in values:
        pre = float(x - delta)
        post = float(x + delta)
        for y in numpy.arange(0,15,0.5):
                if (pre <= y <= post) == True:
                        pass
                else:
                        not_in_range.append(y)

但顯然,這有幾個原因不起作用:冗余,不一次檢查所有范圍等。我是編碼新手,我正在努力抽象地思考以解決這個問題。 在制定行動計划方面的任何幫助將不勝感激。

編輯為了清楚起見,我想要的是每個值(或者可能是一個numpy數組?)的范圍列表

[0.3, 4.3]
[4.4, 8.4]
[9.3, 13.3]

並以 0.5 為增量返回 0 - 15 之間不屬於任何這些范圍的任何浮點數,因此最終輸出將是:

not_in_ranges = [0, 8.5, 9, 13.5, 14, 14.5] 

我已經做了比較分析(在 jupyter notebook 中)。 看看結果。

# First cell
import numpy as np
values = np.random.randn(1000000)
values.shape

# Second cell
%%time
not_in_range =[]
for x in values:
        pre = float(x - 2)
        post = float(x + 2)
        for y in np.arange(0,15,0.5):
                if (pre <= y <= post) == True:
                        pass
                else:
                        not_in_range.append(y)
# Second cell output - Wall time: 37.2 s

# Third cell
%%time
pre = values - 2
post = values + 2

whole_range = np.arange(0,15,0.5)
whole_range

search_range = []
for pr, po in zip(pre, post):
    pr = (int(pr) + 0.5) if (pr%5) else int(pr) 
    po = (int(po) + 0.5) if (po%5) else int(po) 
    search_range += list(np.arange(pr, po, 0.5))
    
whole_range = set(whole_range)
search_range = set(search_range)
print(whole_range.difference(search_range))

# Third cell output - Wall time: 3.99 s

要生成范圍列表,您可以進行快速列表理解:

ranges = [[x-2, x+2] for x in values]

## [[0.3, 4.3], [4.4, 8.4], [9.3, 13.3]]

然后,要返回任何不屬於任何范圍的從 0 到 15(以 0.5 為增量)的浮點數,您可以使用:

not_in_ranges = []
for y in numpy.arange(0, 15, 0.5):      # for all desired values to check
  if not any(pre < y and y < post for pre, post in ranges):
    not_in_ranges.append(y)             # if it is in none of the intervals, append it

## [0.0, 8.5, 9.0, 13.5, 14.0, 14.5]

說明:這會循環遍歷每個可能的值,如果它不在任何間隔中,則將其附加到not_in_ranges列表中。 為了檢查它是否在間隔中,我使用內置的 python 函數any來檢查列表ranges中是否有任何 pre 和 post 值在pre < y < post時返回 True (即如果y在任何一個間隔中) . 如果這是False ,則它不適合任何間隔,因此將添加到此類值的列表中。


或者,如果您只需要結果(而不是兩個列表),則可以將兩者與以下內容結合使用:

not_in_ranges = []
for y in numpy.arange(0, 15, 0.5):
  if not any(x-2 < y and y < x+2 for x in values):
    not_in_ranges.append(y)

你甚至可以再次使用列表理解,給出非常pythonic的外觀:

not_in_ranges = [y for y in numpy.arange(0, 15, 0.5) if not any(x-2 < y and y < x+2 for x in values)]

請注意,最后一個可能是運行最快的,因為 append 調用非常慢並且列表理解幾乎總是更快。 盡管如果您還沒有習慣 Python 列表推導格式,它肯定不是最容易一目了然的。

暫無
暫無

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

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