Python 查找阵列的二维切片的交点
我想获得Python 查找阵列的二维切片的交点,python,arrays,numpy,intersection,Python,Arrays,Numpy,Intersection,我想获得B的行,其中: 如果A[:,0]等于B[:,0]或B[:,2],则A[:,1]必须分别等于B[:,1]或B[:,3] A[:,0]不等于B[i,0]和B[i,2] 例如: A=np.array([[101, 1], [103, 3]]) B=np.array([[100,1,101,1], [100,1,102,1], [100,1,103,3], [100,2,101,2],
B
的行,其中:
A[:,0]
等于B[:,0]
或B[:,2]
,则A[:,1]
必须分别等于B[:,1]
或B[:,3]
A[:,0]
不等于B[i,0]
和B[i,2]
A=np.array([[101, 1],
[103, 3]])
B=np.array([[100,1,101,1],
[100,1,102,1],
[100,1,103,3],
[100,2,101,2],
[100,2,103,2],
[101,1,100,3],
[101,1,103,2],
[101,4,100,4],
[101,4,103,4],
[104,5,102,3]])
R=np.array([[100,1,101,1],
[100,1,102,1],
[100,1,103,3],
[101,1,100,3],
[104,5,102,3]])
我从这里()尝试了解决方案,但出现了一个错误,因为我无法将view
用于数组的切片
谢谢你的帮助 如果我理解正确,你可以使用- 样本运行-
In [361]: A
Out[361]:
array([[101, 1],
[103, 3]])
In [362]: B
Out[362]:
array([[100, 1, 101, 1],
[100, 1, 102, 1],
[100, 1, 103, 3],
[100, 2, 101, 2],
[100, 2, 103, 2],
[101, 1, 100, 3],
[101, 1, 103, 2],
[101, 4, 100, 4],
[101, 4, 103, 4],
[104, 5, 102, 3]])
In [363]: out
Out[363]:
array([[100, 1, 101, 1],
[100, 1, 102, 1],
[100, 1, 103, 3],
[101, 1, 100, 3],
[101, 1, 103, 2],
[104, 5, 102, 3]])
我会先简化你的规则。现在忽略这些形状,让我们考虑<代码> A < /COD>和<代码> B >代码>是对的列表。那么您的要求是,如果一对中的左搭档与
a
中的左搭档之一匹配,则右搭档也必须匹配
这是的定义,写为左匹配→ 右匹配。好在
(x)→ y)
仅在为(x为假)或(y为真)
后者很容易编码。对于您来说,左匹配是x=A[…,0]==B[…,0]
,右匹配是y=A[…,1]==B[…,1]
。所以要检查x→ y
,您只需选中而不是(x)或y
,它们可以写成~x | y
要处理形状,请使用整形,使左
和右
仅沿一个轴(最后一个轴),然后广播以检查与A
中任一对的匹配,然后检查B
每行中的所有对是否满足条件。所有这些看起来都是这样的(详细说明见下文):
下面是它如何应用于您的系统
要绕过这些形状,只需很好地使用广播,然后检查上述内容是否适用于行中的所有对
a = A[None, :, None, :] # or A.reshape(1, A.shape[0], 1, A.shape[1]) to add two broadcasting axes
b = B.reshape(-1, 1, 2, 2) # this is B.reshape(10, 1, 2, 2) without needing to know 10
这为每个a
和b
提供了四个维度:(i,a\u对,b\u对,伙伴)
,也就是说,你在第一个轴上切片,沿着i
(b
中的行)移动,第二个选择a
中的(两个)对,第三个选择b
中的(两个)对,最后一步是选择每对中的两个搭档中的哪一个。要概括这一点(如果您事先不知道其中任何一个的形状),可以使用:
a = A[None, :, None, :] # or A.reshape(1, -1, 1, 2)
b = B.reshape(len(B), 1, -1, 2)
其中-1
s将允许A
和B
中任意数量的对。2
s假设我们正在讨论配对
现在,我们可以通过以下方式获得匹配数组:
m = a == b
它的形状是(10,2,2,2)
,同样代表(i,a,b,partner)
接下来,我们应用对实质含义的要求,如上所述。为了便于阅读,我们首先将所有左伙伴与右伙伴分开,然后检查条件是否保持。我们有
left = m[...,0]
right = m[...,1]
m = ~left | right
这消除了最后一个轴伙伴
,留下(i,b_对)
最后,我们希望确保该规则适用于B
的每一行中的所有对,这是由B_对
轴(2)给出的
当然,它必须符合A
中所有对的匹配(A\u对
轴为1):
把它们放在一起,并结合最后一步中的任何调用,就得到了上面的函数。我认为这与OP中的预期结果不匹配。@askewchan是的,我认为预期输出有错误。我在评论中发布了一些让我感到困惑的东西。那么,从B
中选择行时,case1
和case2
是否都必须为真。另外,在案例1
中,“then”
是否意味着“A[:,0]等于B[:,0]或B[:,2]”
和“[:,1]必须等于B[:,1]或B[:,3]”
从B中选择行时必须再次为真?@Divakar,案例1
是一个条件语句,而case2
只是一个语句。只要case2
为真,case1
则无效(如果1
中的if
为假,则支持该条件)。案例1
的前半部分并不是选择的过滤器(不管a[:,0]
是否匹配B[:,偶数]
中的一个,只要存在匹配,然后a[:,1]
匹配相应的B[:,奇数]
。因此,逻辑上可以忽略大小写2
,得到相同的行。也许@user3357979可以确认吗?@askewchan就是这样correct@user3357979,收到您的评论并注意到我的代码中有错误;它适用于您的示例,但有一个极端情况,即它错过了两对a
中的匹配可以交叉的位置。请看我的最新答案。如果[103,1101,3]
位于B
中,则应将其从输出中排除(该对[101,3]
违反了含义),但我的代码接受了它,因为它在检查含义之前将A
对组合在一起(这取决于A
对匹配)。谢谢,这是完美的工作后,您的编辑!我遇到的一个问题是关于m=m.all((1,2))
。它不断抛出一个类型错误:需要一个整数。我只是将它分为m=m.all(2)
和m=m.all(1)
可能是最近引入的功能。我用numpy 1.9.2进行了测试。如果这两个轴的形状只有两个(如示例中所示),如果速度是个问题,我建议不要对all
执行两次调用,而是执行类似m=m[…,0]| m[…,1]
的操作,这相当于m.all(-1)
(-1
和..
都给出了最后一个轴。还要确保按顺序执行
m = a == b
left = m[...,0]
right = m[...,1]
m = ~left | right
m = m.all(2)
m = m.all(1)