以pythonic方式填充2D numpy数组

时间:2017-12-13 07:58:43

标签: python arrays numpy list-comprehension

我正在尝试填充2D numpy数组。 根据我的经验,以下不适合使用数组大小​​。

x=np.array([2,3,4])
y=np.array([1,3,9,13])
mat=np.zeros((x.size,y.size))
for i in range(nx):
 for j in range(ny):
   if x[i] > y[j]:
        mat[i,j] = 1
   else:
        mat[i,j] = -1

理想情况下,我想使用列表理解之类的 如果只是1D就很简单

mat=np.asarray([foo(x_) for x_ in x])

但如何将其推广到2D np.arrays? 其他基于numpy的解决方案也适用,但效率是此处的关键指标

4 个答案:

答案 0 :(得分:2)

可以构建二维嵌套列表推导:

mat = np.array([[1 if x_ > y_ else -1 for y_ in y] for x_ in x])

然而,这可能变得非常难以理解,并且与for循环没有太大区别,因为涉及性能扩展。 Broadcasting和矢量化通常可以更好地使用更大的数组:

mat = (x[:, None] > y[None, :]) * 2 - 1

答案 1 :(得分:2)

您的mat

In [352]: mat
Out[352]: 
array([[ 1., -1., -1., -1.],
       [ 1., -1., -1., -1.],
       [ 1.,  1., -1., -1.]])

x广播y

In [353]: x[:,None]>y
Out[353]: 
array([[ True, False, False, False],
       [ True, False, False, False],
       [ True,  True, False, False]], dtype=bool)

使用where将该布尔掩码转换为1 / -1数组:

In [354]: np.where(x[:,None]>y,1,-1)
Out[354]: 
array([[ 1, -1, -1, -1],
       [ 1, -1, -1, -1],
       [ 1,  1, -1, -1]])

或者您可以将布尔值转换为0/1数组,并将其缩放以适合

(x[:,None]>y).astype(float)*2-1

两个1d数组或列表上的双循环通常可以像outer这样进行转换。

答案 2 :(得分:1)

尝试:

x=np.array([2,3,4])
y=np.array([1,3,9,13])
a = (x.reshape(x.shape[0], 1) - y) > 0  # a=(x.reshape(-1, 1) - y) > 0
a = a.astype(int)*2 -1 

答案 3 :(得分:1)

如果使用numpy:

import numpy as np
nx = x.size
ny = y.size
mat = np.sign(x * np.atleast_2d(np.ones(ny)).T - np.ones(nx) * np.atleast_2d(y).T)
mat[np.where(mat==0)] = -1
numpy将关注效率(无论这里意味着什么)。