【发布时间】:2015-11-01 00:32:05
【问题描述】:
背景
我有两个 numpy 数组,我想用它们以最有效/最快速的方式执行一些比较操作。两者都只包含无符号整数。
pairs 是一个 n x 2 x 3 数组,其中包含一长串成对的 3D 坐标(对于某些命名法,pairs 数组包含一组对...) - 即
# full pairs array
In [145]: pairs
Out[145]:
array([[[1, 2, 4],
[3, 4, 4]],
.....
[[1, 2, 5],
[5, 6, 5]]])
# each entry contains a pair of 3D coordinates
In [149]: pairs[0]
Out[149]:
array([[1, 2, 4],
[3, 4, 4]])
positions 是一个 n x 3 数组,其中包含一组 3D 坐标
In [162]: positions
Out[162]:
array([[ 1, 2, 4],
[ 3, 4, 5],
[ 5, 6, 3],
[ 3, 5, 6],
[ 6, 7, 5],
[12, 2, 5]])
目标
我想创建一个数组,它是 pairs 数组的子集,但仅包含最多一对在位置数组中的条目 - 即不应该有两个对都位于位置数组中的对。对于某些域信息,每对将在位置列表中至少有一个对位置。
目前尝试的方法
我最初的幼稚方法是循环遍历pairs 数组中的每一对,并从positions 向量中减去这两个对位置中的每一个,确定在这两种情况下我们是否找到了由两者中都存在的 0 表示的匹配项来自减法运算的向量:
if (~(positions-pair[0]).any(axis=1)).any() and
(~(positions-pair[1]).any(axis=1)).any():
# both members of the pair were in the positions array -
# these weren't the droids we were looking for
pass
else:
# append this set of pairs to a new matrix
这很好用,并利用了 some 矢量化,但可能有更好的方法来做到这一点?
对于这个程序的其他一些对性能敏感的部分,我用 Cython 重写了一些东西,这带来了巨大的加速,但在这种情况下(至少基于一个简单的嵌套 for 循环实现),这会稍微慢一些比上面概述的方法。
如果人们有任何建议,我很乐意进行分析并反馈(我已设置所有分析基础架构)。
【问题讨论】:
-
stackoverflow.com/a/31889183/901925 中使用的方法应该可以工作。它扩展了维度(或一个或两个数组),因此您可以逐个元素进行比较,然后使用
all将结果合并到一个或多个维度上。或者在你的情况下,我会使用sum为 1 的“行”。我稍后会详细说明。
标签: python performance numpy cython