我有两个二元组列表,我想找出第一个二元组中的哪些元素位于第二个二元组中.例如:

elements = [
     (903, 468),
     (913, 468),
     (926, 468),
     (833, 470),
     (903, 470),
     (917, 470),
     (833, 833),
     (903, 833),
     (913, 833),
     (917, 833),
]
    
test_elements = [
    (903, 468), 
    (913, 468), 
    (833, 470), 
    (903, 470), 
    (833, 833), 
    (903, 833),
]

我想为elements中存在于test_elements中的元素返回布尔屏蔽.我不明白为什么NP.isin没有给出正确的结果:

list(map(np.all, np.isin(elements, test_elements)))
>>> [True, True, False, True, True, False, True, True, True, False]

这意味着(913, 833)应该在test_elements中,但事实并非如此

然而,这个expesssion(我在这里从another post找到)返回正确的面具:

list((np.array(elements)[:,None] == np.array(test_elements)).all(2).any(1))
>>> [True, True, False, True, True, False, True, True, False, False]

np.isin(或者np.allmap)我缺少什么?

推荐答案

np.isin(elements, test_elements)是布尔值的2D数组(n行2列),表示test_elements中是否有一个纯量.

向每一行添加all(顺便说一句,您应该使用numpy:np.isin(elements, test_elements).all(axis=1)来判断两个元素是否都是True,但并不能按照您的要求进行.它不会因为同一行而判断它们是否都为真.

np.isin([(913, 833)], test_elements)就是[[True, True]],因为913和833都在test_elements中.所以np.isin([(913, 833)], test_elements).all(axis=1)是真的,但这并不能证明你想要什么.

你无法用isin个来实现你想要的.首先,elements的行不是tuple,可以像Python中那样进行索引和比较.它们是一堆数据(numpy与Python的二元组不同).其次,无论如何,isin文档表明test_elements即使不是1D也是扁平的.因此isin仅判断单个纯量值.

如果你想用纯numpy来做到这一点(但不确定这是一个好主意),你基本上需要进行交互(但以numpy的方式).

(np.array(elements)[:,None,:] == np.array(test_elements)[None,:,:])

是一个3D数组,其元素[x,y,z]表示elements行x的列z是否等于test_elements行y的列z

所以

(np.array(elements)[:,None,:] == np.array(test_elements)[None,:,:]).all(axis=2)

是一个2D数组,其元素[x,y]表示elements行x的两列是否等于test_elements行y的两列.

所以

(np.array(elements)[:,None,:] == np.array(test_elements)[None,:,:]).all(axis=2).any(axis=1)

是一个1D数组,其元素[x]表示elemnts行x的两列是否与test_elements行的任何行的两列相等.

这就是你想要的.

再说一次,不确定这是一个好主意.尤其是从Python二元组开始. 如果列表很小,那么无意中听说将所有这些翻译成numpy数组的风险比在集中进行纯Python搜索更大,例如:

S=set(test_elements)
[row in S for row in elements]

(它利用了二元组在集合 struct 中是可排序、可哈希、可比较等的事实)

如果列表更大,那么,当然,numpy的负担变得可以忽略,并且O(n.m.c)算法(其中n和m是两个列表的行数,c是列数)将尽快实现. 但是,它仍然是一个O(n.m.c)算法,而set版本可能是一个O(n.log(m))算法.当然,即使我对set场表演很天真,一些临时方法也可以击败它.(就像四叉树一样,因为这就像在平面中寻找匹配点一样)

无论哪种方式,这并不是一个真正适合numpy one-liners的工作(您可以用numpy tho实现四叉树库,但那是另一回事了).

TL;博士

  • isin做不到
  • 不要试图用麻木的俏皮话来做到这一点.
  • 但如果你无论如何坚持这样做,那么 (np.array(elements)[:,None,:] == np.array(test_elements)[None,:,:]).all(axis=2).any(axis=1)是一行台词
  • 如果elements不是太大,就用pony的集合
S=set(test_elements)
[row in S for row in elements]
  • 如果这些都是巨大的列表,那么请找到一个临时代码来搜索2D元素.就像四叉树一样.或者是一个具有指数化的 pyramid .

Python相关问答推荐

将嵌套列表的字典转换为数据框中的行

如何编写一个正规表达式来查找序列中具有2个或更多相同辅音的所有单词

在matplotlib动画gif中更改配色方案

使用from_pandas将GeDataFrame转换为polars失败,ArrowType错误:未传递numpy. dype对象

通过交换 node 对链接列表进行 Select 排序

如何在Python中使用时区夏令时获取任何给定本地时间的纪元值?

pandas滚动和窗口中有效观察的最大数量

我们可以为Flask模型中的id字段主键设置默认uuid吗

无法使用DBFS File API路径附加到CSV In Datricks(OSError Errno 95操作不支持)

python中字符串的条件替换

如何使用Pandas DataFrame按日期和项目汇总计数作为列标题

名为__main__. py的Python模块在导入时不运行'

Polars asof在下一个可用日期加入

解决调用嵌入式函数的XSLT中表达式的语法移位/归约冲突

将scipy. sparse矩阵直接保存为常规txt文件

跳过嵌套JSON中的级别并转换为Pandas Rame

为什么常规操作不以其就地对应操作为基础?

如何检测鼠标/键盘的空闲时间,而不是其他输入设备?

使用Openpyxl从Excel中的折线图更改图表样式

如果有2个或3个,则从pandas列中删除空格