Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.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 检测元素是否在成对的间隔限制内_Python_Performance_Pandas_Numpy - Fatal编程技术网

Python 检测元素是否在成对的间隔限制内

Python 检测元素是否在成对的间隔限制内,python,performance,pandas,numpy,Python,Performance,Pandas,Numpy,我将数组设置为: A = np.array([1, 6, 4, 4, 5, 6]) B = np.array([5, 40, 4, 6, 54,7]) #same size as A but every element of B is greater than corresponding element of A C = np.array([6, 3]) 我想找到A和B的所有行,这样C>=A和C,特别是如果A和B非常大,通过C循环的开销几乎可以忽略。然而,如果C很长,但A和B很短,那么您需要

我将数组设置为:

A = np.array([1, 6,  4, 4, 5, 6])
B = np.array([5, 40, 4, 6, 54,7]) #same size as A but every element of B is greater than corresponding element of A
C = np.array([6, 3])

我想找到A和B的所有行,这样C>=A和C,特别是如果A和B非常大,通过C循环的开销几乎可以忽略。然而,如果C很长,但A和B很短,那么您需要考虑一种广播方法,因为这样python循环将引入大量开销

显式循环的simple方法 广播方式
然而,广播方法将创建大尺寸=A.size*C.size中间数组,因此如果A、B和C很大,这将需要大量内存。

特别是如果A和B非常大,通过C循环的开销几乎可以忽略。然而,如果C很长,但A和B很短,那么您需要考虑一种广播方法,因为这样python循环将引入大量开销

显式循环的simple方法 广播方式 然而,广播方法将创建大尺寸=A.size*C.size中间阵列,因此如果A、B和C很大,则需要大量内存。

预期解决方案

看起来A和B是上下边界,有点像区间边界,我们的任务是检测C中的任何元素是否在这些区间中。对于这样的边界相关问题,通常可以与其可选的side参数一起使用,该参数接受left和right作为输入参数。这个函数让我们获得第一个索引,其中每个要搜索的元素都存在于提供给side参数的那一侧。因此,我们需要寻找索引,其中A和B元素对的左侧和右侧匹配索引分别出现。这些相同的情况表明,元件位于边界限制的同一侧,即不在该对的边界限制内。因此,我们需要寻找不平等作为最终衡量标准

因此,执行工作将是非常重要的-

def ingrps_searchsorted(A, B, C):    
    # searchsorted needs the first input to be sorted
    S = np.sort(C)

    # Use searchsorted and look for     
    return np.searchsorted(S, A, 'left') != np.searchsorted(S, B, 'right')
这将给我们一个掩码,比如说m,我们需要在a和B上屏蔽,以获得最终输出:a[m]和B[m]

运行时测试

其他办法-

# MSeifert's soln1
def ingrps_loop(A, B, C):
    mask = np.zeros(A.shape, dtype=bool)
    for item in C:
        mask |= (A<=item) & (B>=item)
    return mask

# MSeifert's soln2
def ingrps_broadcasting(A, B, C):  
    return ((A[:, None]<=C) & (B[:, None]>=C)).max(axis=1)   
远景方案

看起来A和B是上下边界,有点像区间边界,我们的任务是检测C中的任何元素是否在这些区间中。对于这样的边界相关问题,通常可以与其可选的side参数一起使用,该参数接受left和right作为输入参数。这个函数让我们获得第一个索引,其中每个要搜索的元素都存在于提供给side参数的那一侧。因此,我们需要寻找索引,其中A和B元素对的左侧和右侧匹配索引分别出现。这些相同的情况表明,元件位于边界限制的同一侧,即不在该对的边界限制内。因此,我们需要寻找不平等作为最终衡量标准

因此,执行工作将是非常重要的-

def ingrps_searchsorted(A, B, C):    
    # searchsorted needs the first input to be sorted
    S = np.sort(C)

    # Use searchsorted and look for     
    return np.searchsorted(S, A, 'left') != np.searchsorted(S, B, 'right')
这将给我们一个掩码,比如说m,我们需要在a和B上屏蔽,以获得最终输出:a[m]和B[m]

运行时测试

其他办法-

# MSeifert's soln1
def ingrps_loop(A, B, C):
    mask = np.zeros(A.shape, dtype=bool)
    for item in C:
        mask |= (A<=item) & (B>=item)
    return mask

# MSeifert's soln2
def ingrps_broadcasting(A, B, C):  
    return ((A[:, None]<=C) & (B[:, None]>=C)).max(axis=1)   

为了澄清-你想得到A和B的所有元素,这样就有一个j满足A[i],你不需要找到C的最大值,然后与A和C的最小值进行比较,再与B进行比较。为什么第一个例子中的1不是要澄清-你想得到A和B的所有元素,这样就有一个j满足A[i]难道你不需要找到C的最大值并与A和C的最小值进行比较以与B进行比较吗?为什么在第一种情况下1不是1?这将进一步缩短解决方案的时间,因为我的C已排序。这将进一步缩短解决方案的时间,因为我的C已排序。
def ingrps_searchsorted(A, B, C):    
    # searchsorted needs the first input to be sorted
    S = np.sort(C)

    # Use searchsorted and look for     
    return np.searchsorted(S, A, 'left') != np.searchsorted(S, B, 'right')
# MSeifert's soln1
def ingrps_loop(A, B, C):
    mask = np.zeros(A.shape, dtype=bool)
    for item in C:
        mask |= (A<=item) & (B>=item)
    return mask

# MSeifert's soln2
def ingrps_broadcasting(A, B, C):  
    return ((A[:, None]<=C) & (B[:, None]>=C)).max(axis=1)   
In [342]: # Setup inputs so that around 20% matches exist
     ...: A = np.random.randint(0,50,(10000))
     ...: B = A + np.random.randint(0,50,(10000))
     ...: C = np.random.randint(0,100,(10000))
     ...: 

In [343]: np.allclose(ingrps_loop(A, B, C), ingrps_broadcasting(A, B, C))
Out[343]: True

In [344]: np.allclose(ingrps_loop(A, B, C), ingrps_searchsorted(A, B, C))
Out[344]: True

In [345]: %timeit ingrps_loop(A, B, C)
     ...: %timeit ingrps_broadcasting(A, B, C)
     ...: %timeit ingrps_searchsorted(A, B, C)
     ...: 
10 loops, best of 3: 101 ms per loop
10 loops, best of 3: 102 ms per loop
1000 loops, best of 3: 1.79 ms per loop

In [346]: # Setup inputs so that around 20% matches exist
     ...: A = np.random.randint(0,50,(100000))
     ...: B = A + np.random.randint(0,50,(100000))
     ...: C = np.random.randint(0,100,(100000))
     ...: 

In [347]: %timeit ingrps_loop(A, B, C)
     ...: %timeit ingrps_searchsorted(A, B, C)
     ...: 
1 loops, best of 3: 8.18 s per loop
10 loops, best of 3: 26.5 ms per loop

In [348]: 8180/26.5 # Speedup number with proposed solution over loopy one
Out[348]: 308.6792452830189