Arrays 两个numpy数组的笛卡尔积,带条件

Arrays 两个numpy数组的笛卡尔积,带条件,arrays,performance,numpy,vectorization,Arrays,Performance,Numpy,Vectorization,给定下面的1d数组w和x,我可以使用以下代码形成笛卡尔积 import numpy as np w = np.array([1, 2, 3, 4]) x = np.array([1, 2, 3, 4]) V1 = np.transpose([np.repeat(w, len(x)), np.tile(x, len(w))]) print(V1) [[1 1] [1 2] [1 3] [1 4] [2 1] [2 2] [2 3] [2 4] [3 1] [3 2] [3

给定下面的1d数组w和x,我可以使用以下代码形成笛卡尔积

import numpy as np

w = np.array([1, 2, 3, 4])
x = np.array([1, 2, 3, 4])

V1 = np.transpose([np.repeat(w, len(x)), np.tile(x, len(w))])
print(V1)

[[1 1]
 [1 2]
 [1 3]
 [1 4]
 [2 1]
 [2 2]
 [2 3]
 [2 4]
 [3 1]
 [3 2]
 [3 3]
 [3 4]
 [4 1]
 [4 2]
 [4 3]
 [4 4]]
但是,我希望输出V1只包含w的数组行(如下所示)。我可以用循环来实现这一点,但我希望能更快一点

[[1 2]
 [1 3]
 [1 4]
 [2 3]
 [2 4]
 [3 4]]
方法#1

如果只给出w的数组行,这将用于成对组合,这里有一种方法可以实现相同的效果-

In [81]: r,c = np.nonzero(w[:,None]<x) # or np.less.outer(w,x)

In [82]: np.c_[w[r], x[c]]
Out[82]: 
array([[1, 2],
       [1, 3],
       [1, 4],
       [2, 3],
       [2, 4],
       [3, 4]])
标杆管理 使用相对较大的阵列:

In [8]: np.random.seed(0)
   ...: w = np.random.randint(0,1000,(1000))
   ...: x = np.random.randint(0,1000,(1000))

In [9]: %%timeit
   ...: r,c = np.nonzero(w[:,None]<x)
   ...: np.c_[w[r], x[c]]
11.3 ms ± 24.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [10]: %%timeit
    ...: mask = np.less.outer(w,x)
    ...: s = (len(w), len(x))
    ...: np.c_[np.broadcast_to(w[:,None], s)[mask], np.broadcast_to(x, s)[mask]]
10.5 ms ± 275 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [11]: import itertools

# @Akshay Sehgal's soln
In [12]: %timeit [i for i in itertools.product(w,x) if i[0]<i[1]]
105 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
[8]中的
:np.random.seed(0)
…w=np.random.randint(01000,(1000))
…x=np.random.randint(01000,(1000))
[9]中:%%timeit

…:r,c=np。非零(w[:,None]使用itertools尝试此单线方法-

import itertools

w = np.array([1, 2, 3, 4])
x = np.array([1, 2, 3, 4])

[i for i in itertools.product(w,x) if i[0]<i[1]]

Itertools速度非常快,内存效率也非常高。它应该非常快。

您还可以通过以下方式过滤您自己的解决方案:

V1 = np.transpose([np.repeat(w, len(x)), np.tile(x, len(w))])
V1[V1[:,0]<V1[:,1]]
V1=np.transpose([np.repeat(w,len(x)),np.tile(x,len(w)))

V1[V1[:,0]非常好,而且速度很快!我对numpy很陌生,很感激有两种解决方案可以学习。不知道为什么benchit绘图对你来说这么小。它们在保存之前可以全屏显示吗?如果不能,你可以使用
figsize
参数和
plot
使其变大吗?我假设你希望它们变大,至少是拉伸更横向。@Divakar您的软件包工作得很好,再次感谢:)。我只是裁剪它们并调整它们的大小,因为我认为它更紧凑,更适合在这里演示。
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
V1 = np.transpose([np.repeat(w, len(x)), np.tile(x, len(w))])
V1[V1[:,0]<V1[:,1]]
#@Proposed solution here
def m1(x):
  V1 = np.transpose([np.repeat(w, len(x)), np.tile(x, len(w))])
  return V1[V1[:,0]<V1[:,1]]

#@Divakar's approach 1
def m2(x):
  r,c = np.nonzero(w[:,None]<x) # or np.less.outer(w,x)
  return np.c_[w[r], x[c]]

#Divakar's approach 2
def m3(x):
  mask = np.less.outer(w,x)
  s = (len(w), len(x))
  return np.c_[np.broadcast_to(w[:,None], s)[mask], np.broadcast_to(x, s)[mask]]

in_ = [np.arange(n) for n in [10,100,1000]]
w = x.copy()