Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 给定2个整数列表,如何找到不重叠的范围?_Python_List_Pandas_Numpy_Range - Fatal编程技术网

Python 给定2个整数列表,如何找到不重叠的范围?

Python 给定2个整数列表,如何找到不重叠的范围?,python,list,pandas,numpy,range,Python,List,Pandas,Numpy,Range,给定 目标是迭代x_i,找到大于x_i但不大于x_i+1的y值 假设两个列表都已排序且所有项目都是唯一的,给定x和y的所需输出为: x = [5, 30, 58, 72] y = [8, 35, 53, 60, 66, 67, 68, 73] 我试过: [(5, 8), (30, 35), (58, 60), (72, 73)] def per_窗口(顺序,n=1): """ 从…起http://stackoverflow.com/q/42220614/610569 >>>列表(每个窗口([

给定

目标是迭代
x_i
,找到大于
x_i
但不大于
x_i+1的
y

假设两个列表都已排序且所有项目都是唯一的,给定
x
y
的所需输出为:

x = [5, 30, 58, 72]
y = [8, 35, 53, 60, 66, 67, 68, 73]
我试过:

[(5, 8), (30, 35), (58, 60), (72, 73)]
def per_窗口(顺序,n=1):
"""
从…起http://stackoverflow.com/q/42220614/610569
>>>列表(每个窗口([1,2,3,4],n=2))
[(1, 2), (2, 3), (3, 4)]
>>>列表(每个窗口([1,2,3,4],n=3))
[(1, 2, 3), (2, 3, 4)]
"""
开始,停止=0,n
seq=列表(顺序)
停止XI和YJ <席普斯1:
r、 附加((xi,yj))
打破
#对于最后一个x值。
#对于最后一个x值。
对于枚举(y)中的j,yj:
如果yj>xiplus1:
r、 追加((xiplus1,yj))
打破

但是有没有一种更简单的方法可以用
numpy
pandas
或其他东西来实现同样的效果呢?

你可以使用
numpy.searchsorted
side='right'
找到
y
中大于
x
的第一个值的索引,然后用该索引提取元素;假设
y
中总有一个值大于
x
中任何元素的简单版本可以是:

def per_window(sequence, n=1):
    """
    From http://stackoverflow.com/q/42220614/610569
        >>> list(per_window([1,2,3,4], n=2))
        [(1, 2), (2, 3), (3, 4)]
        >>> list(per_window([1,2,3,4], n=3))
        [(1, 2, 3), (2, 3, 4)]
    """
    start, stop = 0, n
    seq = list(sequence)
    while stop <= len(seq):
        yield tuple(seq[start:stop])
        start += 1
        stop += 1

x = [5, 30, 58, 72]
y = [8, 35, 53, 60, 66, 67, 68, 73]

r = []

for xi, xiplus1 in per_window(x, 2):
    for j, yj in enumerate(y):
        if yj > xi and yj < xiplus1:
            r.append((xi, yj))
            break

# For the last x value.
# For the last x value.
for j, yj in enumerate(y):
    if yj > xiplus1:
        r.append((xiplus1, yj))
        break

给定的
y
已排序:

x = np.array([5, 30, 58, 72])
y = np.array([8, 35, 53, 60, 66, 67, 68, 73])

np.column_stack((x, y[np.searchsorted(y, x, side='right')]))
#array([[ 5,  8],
#       [30, 35],
#       [58, 60],
#       [72, 73]])
返回
y
中的第一个值的索引,该索引大于
x
中的相应值(列表1,列表2):
np.searchsorted(y, x, side='right')
# array([0, 1, 3, 7])
最终=[] 对于范围内的i(len(列表1)): pos=0 尝试: 尽管如此:
如果i+1==len(list1)和list1[i],则可以通过迭代自身压缩的
x
来构造一个新列表——由1个索引偏移,并附加
y
的最后一个元素,然后迭代y,检查每个过程的条件并中断最内部的循环

def find(list1,list2):
    final = []
    for i in range(len(list1)):
        pos=0
        try:
            while True:
                if i+1==len(list1) and list1[i]<list2[pos]:
                    final.append((list1[i],list2[pos]))
                    raise Exception
                if list1[i]<list2[pos] and list1[i+1]>list2[pos]:
                    final.append((list1[i],list2[pos]))
                    raise Exception
                pos+=1
        except: pass
    return final
out=[]
对于拉链中的x_低,x_高(x,x[1:+y[-1:]):
对于y中的yy:

如果(yy>x_-low)和(yy我们可以在列表中使用
pd.DataFrame
direction=forward,即

out = []
for x_low, x_high in zip(x, x[1:]+y[-1:]):
    for yy in y:
        if (yy>x_low) and (yy<=x_high):
            out.append((x_low,yy))
            break

out
# returns:
[(5, 8), (30, 35), (58, 60), (72, 73)]
如果不需要精确匹配来匹配,则需要通过
允许精确匹配=False
来合并

输出:

new = pd.merge_asof(pd.DataFrame(x,index=x), pd.DataFrame(y,index=y),on=0,left_index=True,direction='forward')
out = list(zip(new[0],new.index))

当你在
y
中有超过1个介于
x[i]
x[i+1]
之间的数字时,你希望发生什么?以第一个为例。实际上,最近的数字可能无法满足OP的需要,因为当你得到
y=[8,35,53,57,60,66,67,68,73]
插入哪个
57
,它不会得到预期的结果,我看我们可以使用forward如果你使用forward,当
x=[5,30,58,59,72]
时它可能不起作用。是的,现在我看到了缺点。@Tangfeifan我想情况就是问题评论中的意思,不是吗。
[(5, 8), (30, 35), (58, 60), (72, 73)]