我正在尝试根据一个数组中的值是否在另一个数组中来创建数组。我希望以下内容能够奏效:
A = np.fromfunction(lambda x, y: tuple(order[x,:]) in paths[y,],\
shape=((len(order), len(paths))), dtype=int)
不幸的是,这只会产生一个标量值而不是我想要的数组。我可以通过如下的for循环实现相同的目的,但由于涉及的值的数量,此选项非常慢。
A = np.zeros(shape=(len(order), len(paths)), dtype=int)
for i in np.ndindex(len(order), len(paths)):
r = i[0] # Row
c = i[1] # Column
x = r + c + (len(paths)-1)*r
if paths[c,] == None:
pass
elif tuple(order[r,:]) in paths[c,]:
np.put(A, x, 1, 'wrap')
有没有人有一种有效的方法来生成目标矩阵?非常感谢你的帮助!
\ edit:非常感谢你的提示hpaulj。我认为np.where
进入了我想要实现的目标,但无法处理两个数组的复杂性。我编辑了上面的方法,因为x = r*c if r*c != 0 else r+c
没有给我我想要的结果 - 当我的输出是胡言乱语时,我以某种方式想出来...... x = r + c + (len(paths)-1)*r
但是确实能够唯一地识别每个位置平坦的2D阵列。我在下面提供的样本应该让我更清楚我想要实现的目标。抱歉混乱!
order
[[ 73 6 3 1]
[ 73 6 3 2]
[ 6 116 3 1]
[ 6 116 3 2]
[116 45 3 1]
...10k additional lines...]
paths
[ [(12, 14, 1615, 1), (14, 156, 1615, 1), (156, 83, 1615, 1), (83, 37, 1554, 1), (37, 36, 1554, 1)]
[(12, 14, 1615, 2), (14, 156, 1615, 2), (156, 83, 1615, 2), (83, 37, 1554, 2), (37, 36, 1554, 2)]
[(12, 14, 1615, 1), (14, 156, 1615, 1), (156, 83, 1615, 1), (83, 37, 1554, 1), (37, 36, 1554, 1)]
[(12, 14, 1615, 2), (14, 156, 1615, 2), (156, 83, 1615, 2), (83, 37, 1554, 2), (37, 36, 1554, 2)]
[(12, 14, 1615, 1), (14, 156, 1615, 1), (156, 83, 1615, 1), (83, 37, 1554, 1), (37, 36, 1554, 1)]
[(12, 14, 1615, 2), (14, 156, 1615, 2), (156, 83, 1615, 2), (83, 37, 1554, 2), (37, 36, 1554, 2)]
...600 additional lines...]
目标是检查order
的每个值是否在paths
范围内,并且在行/列交叉点中放置True
或1
。所有其他交叉点应为False
/ 0
。维持行和列的顺序是至关重要的,因为矩阵然后乘以有序向量。实际上我正在研究这个(URL - 见下文,p94)算法。该矩阵应该反映特定产品(order
)对特定资源(paths
)的利用率。
答案 0 :(得分:2)
查看代码表单fromfunction
。
args = indices(shape, dtype=dtype)
return function(*args,**kwargs)
np.indices
与meshgrid
In [28]: np.indices((2,3))
Out[28]:
array([[[0, 0, 0],
[1, 1, 1]],
[[0, 1, 2],
[0, 1, 2]]])
所以np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
相当于做
In [29]: idn=np.indices((2,3))
In [31]: idn[0]+idn[1]
Out[31]:
array([[0, 1, 2],
[1, 2, 3]])
我通常使用广播:np.arange(2)[:,None] + np.arange(3)
有一个np.frompyfunc
将Python函数应用于其输入的每个元素。但它只适用于1d(虽然结构化数组周围有一些巧妙的技巧)。 np.vectorize
也使用此功能。但两者仍在迭代,因此节省的时间最多为2倍。
===============
ndindex
是另一种生成索引值的方法
In [42]: list(np.ndindex(2,3))
Out[42]: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
In [43]: list(zip(*np.ndindex(2,3)))
Out[43]: [(0, 0, 0, 1, 1, 1), (0, 1, 2, 0, 1, 2)]
使用zip
转置,我得到的值类似于nd.indices
生成的值(但是已经过了)。
======================
如果没有order
和paths
的示例值,很难想象您的功能正在做什么。或者更确切地说,只是通过阅读代码我无法描绘它正在做什么,没有样本我就无法进行测试。对于' blackbox'采用标量i,j
坐标的函数,你的方法就像它得到的一样好。为了使它快速,你必须重做函数,以便它使用直接使用np.indices
的子数组,而不是迭代。
===============
获取x
值的矢量化方法可能是
In [105]: I,J=np.indices((3,3))
In [106]: np.where(I*J,I*J,I+J)
Out[106]:
array([[0, 1, 2],
[1, 1, 2],
[2, 2, 4]])
where
在整个数组上执行x = r*c if r*c != 0 else r+c
。
布尔掩码(数组if
测试的一个好工具)的相同之处是:
In [114]: x=I*J
In [115]: mask = x==0
In [116]: x[mask]=(I+J)[mask]
In [117]: x
Out[117]:
array([[0, 1, 2],
[1, 1, 2],
[2, 2, 4]])