0

我有一个花车清单。

values = [2.3, 6.4, 11.3]

我想要做的是从 size 列表中的每个值中找到一个范围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 - 15 的任何浮点数,增量为 0.5,不属于任何这些范围,因此最终输出为:

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

3 回答 3

0

我已经做了比较分析(在 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
于 2021-07-28T01:45:51.177 回答
0

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

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来检查列表中是否有任何 pre 和 post 值在ranges何时返回 True pre < y < post(即是否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)]

请注意,最后一个可能是运行速度最快的,因为追加调用非常慢并且列表理解几乎总是更快。虽然如果您还没有习惯 Python 列表理解格式,它肯定可能不是最容易一目了然的理解。

于 2021-07-28T01:55:18.667 回答
0

您可以使用区间库 intvalpy

from intvalpy import Interval
import numpy as np

values = [2.3, 6.4, 11.3]
delta = 2
intervals = values + Interval(-delta, delta)

not_in_ranges = []
for k in np.arange(0, 15, 0.5):
    if not k in intervals:
        not_in_ranges.append(k)
print(not_in_ranges)

区间是根据区间算术运算的构造定义创建的。操作员检查一个in点(或一个区间)是否包含在另一个区间内。

于 2021-08-04T13:30:34.563 回答