我研究了这个问题,人们一直建议使用 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 等价物。
最佳答案
这类似于您对 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]
关于python - 找到数组元素的所有可能组合。不是产品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62867210/