我有数组:
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<=B
。相同行的A and B
表单对必须一起选择。
因此,输出数组将是:
For C[0] = 6
Aout = [6, 4, 5, 6]
Bout = [40, 6, 54, 7]
ForC[1] = 3
Aout = [1]
Bout = [5]
因此,最终输出看起来像:
Aout = [1, 6, 4, 5, 6]
Bout = [5, 40, 6, 54, 7]
目前我正在考虑使用numpy.where
并循环浏览C
的每个元素,但考虑到我的文件非常大A, B and C
,这似乎是一个非常低效的过程。
如果使用熊猫有更简单的方法,我会更喜欢。
答案 0 :(得分:4)
特别是如果您有非常大的A
和B
,那么循环C
的开销几乎可以忽略不计。但是,如果C
很长但A
和B
很短,那么您需要考虑一种广播方法,因为这样会导致一个巨大的开销。
mask = np.zeros(A.shape, dtype=bool)
for item in C:
mask |= (A<=item) & (B>=item)
A[mask], B[mask] # select the valid elements
mask= ((A[:, None]<=C) & (B[:, None]>=C)).max(axis=1)
A[mask], B[mask] # select the valid elements
然而,广播方法会创建大型(size= A.size * C.size
)中间数组,因此如果A
,B
和 C
很大,那么需要大量的记忆。
答案 1 :(得分:3)
预期解决方案
似乎df1.drop_duplicates(common_cols).merge(df2.drop_duplicates(common_cols))
和A
充当下边界和上边界,有点像间隔边界,我们的任务是检测来自B
的任何元素是否都在这些间隔。对于此类与边界相关的问题,通常numpy.searchsorted
可以与其可选的C
参数一起使用,该参数接受side
和left
作为输入参数。这个函数让我们得到第一个索引,其中每个要搜索的元素都存在于被赋予right
参数的一侧。因此,我们需要查找指数,其中side
和left
元素中的每一个的right
和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)