python - 找到数组元素的所有可能组合。不是产品

标签 python numpy vectorization combinations computational-geometry

我研究了这个问题,人们一直建议使用 np.meshgrid() 来查找数组的所有可能组合。但问题是 np.meshgrid() 不产生组合它产生产品(类似于 itertools.product())

在组合中,元素是不重复且无序的

arr = np.arange(5)
r = 3

这些是组合的样子

np.array(
    list(itertools.combinations(arr, r))
)

>>>   [[0, 1, 2],
       [0, 1, 3],
       [0, 1, 4],
       [0, 2, 3],
       [0, 2, 4],
       [0, 3, 4],
       [1, 2, 3],
       [1, 2, 4],
       [1, 3, 4],
       [2, 3, 4]]

以下不是组合

np.array(
    list(itertools.product(arr, arr, arr))
)

>>>   [[0, 0, 0],
       [0, 0, 1],
       [0, 0, 2],
       [0, 0, 3],
       [0, 0, 4],
       [0, 1, 0],
       [0, 1, 1],
       [0, 1, 2],
       ....,
       [4, 3, 2],
       [4, 3, 3],
       [4, 3, 4],
       [4, 4, 0],
       [4, 4, 1],
       [4, 4, 2],
       [4, 4, 3],
       [4, 4, 4]])
np.array(
    np.meshgrid(arr, arr, arr)
).transpose([2, 1, 3, 0]).reshape(-1, r)

>>>   [[0, 0, 0],
       [0, 0, 1],
       [0, 0, 2],
       [0, 0, 3],
       [0, 0, 4],
       [0, 1, 0],
       [0, 1, 1],
       [0, 1, 2],
       ....,
       [4, 3, 2],
       [4, 3, 3],
       [4, 3, 4],
       [4, 4, 0],
       [4, 4, 1],
       [4, 4, 2],
       [4, 4, 3],
       [4, 4, 4]])

对于 r = 2,我找到了一种寻找组合的巧妙方法

np.array(
    np.triu_indices(len(arr), 1)
).T

>>>   [[0, 1],
       [0, 2],
       [0, 3],
       [0, 4],
       [1, 2],
       [1, 3],
       [1, 4],
       [2, 3],
       [2, 4],
       [3, 4]]

但我很难为 r > 2 找到任何矢量化方法

NOTE: even if my array is not [0, 1, 2, 3, 4] i could use the above answers as indices.

如果有助于想象,

对于 r = 2,要求的答案是大小为 len(arr) 的方阵的右上三角形的索引,忽略对角线。

对于 r = 3 所需的答案是大小为(你猜对了)的 3d 数组的右上四面体(图像中的中间一个)的索引 len(arr ),忽略对角线的 3d 等价物。

enter image description here

最佳答案

这类似于您对 3-D 的想法:

n = 5
r = 3
a = np.argwhere(np.triu(np.ones((n,)*r),1))
a[a[:,0]<a[:,1]]

输出:

[[0 1 2]
 [0 1 3]
 [0 1 4]
 [0 2 3]
 [0 2 4]
 [0 3 4]
 [1 2 3]
 [1 2 4]
 [1 3 4]
 [2 3 4]]

对于 4-D(等等)你可以像这样扩展(不确定性能):

n = 5
r = 4
a = np.argwhere(np.triu(np.ones((n,)*r),1))
a[(a[:,0]<a[:,1]) & (a[:,1]<a[:,2])]

输出:

[[0 1 2 3]
 [0 1 2 4]
 [0 1 3 4]
 [0 2 3 4]
 [1 2 3 4]]

如果这是您的目标,Itertools 似乎更快:

def m1(n):
  r = 3
  a = np.argwhere(np.triu(np.ones((n,)*r),1))
  return a[a[:,0]<a[:,1]]

def m2(n):
  r = 3
  return combinations(np.arange(n),r)

in_ = [5,10,100,200]

enter image description here

关于python - 找到数组元素的所有可能组合。不是产品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62867210/

相关文章:

python - 与颜色不同的两个图像进行模板匹配

Python:二进制二维数组中的轮廓

python - 在 numpy 中创建这个 block 矩阵

c++ - 仅当循环中更新的变量是本地变量时才优化计算

python - BeautifulSoup 将主表中的多个表分组

python - os.system() 返回错误代码 32512 - Python

python - 有没有更快的方法来分离两个数组的最小值和最大值?

python - numpy loadtxt 函数使用转换器和 mdates 引发语法错误

python - numpy.sum() 在大数组上给出奇怪的结果

r - 从每个案例的创建时间开始计算未结案例的更有效方法