2011-08-21 108 views
15

是否有一个numpy函数可以将一个数组沿轴与另一个数组中的元素分开?例如,假设我有一个具有形状(l,m,n)的数组a和具有形状(m,n)的数组b。我在找的东西相当于:numpy沿轴线划分

>>> a = np.random.randn(4,3) 
array([[ 1.03116167, -0.60862215, -0.29191449], 
     [-1.27040355, 1.9943905 , 1.13515384], 
     [-0.47916874, 0.05495749, -0.58450632], 
     [ 2.08792161, -1.35591814, -0.9900364 ]]) 
>>> np.apply_along_axis(np.linalg.norm,1,a) 
array([ 1.23244853, 2.62299312, 0.75780647, 2.67919815]) 
>>> c = divide_along_axis(a,np.apply_along_axis(np.linalg.norm,1,a),0) 
>>> np.apply_along_axis(np.linalg.norm,1,c) 
array([ 1., 1., 1., 1.]) 

回答

23

对于已给出的具体实例:将一个(L,M,N)阵列由(M,),可以使用NP .newaxis:

a = np.arange(1,61, dtype=float).reshape((3,4,5)) # Create a 3d array 
a.shape           # (3,4,5) 

b = np.array([1.0, 2.0, 3.0, 4.0])    # Create a 1-d array 
b.shape           # (4,) 

a/b            # Gives a ValueError 

a/b[:, np.newaxis]        # The result you want 

你可以阅读所有关于广播规则here。如果需要,您也可以多次使用newaxis。 (例如用形状(3,5)阵列分割形状(3,4,5,6)阵列)。

根据我对文档的理解,使用newaxis + broadcast可以避免任何不必要的数组复制。

现在更详细地描述Indexing,newaxis等here。 (文件重新组织,因为这个答案第一次发布)。

0

我想你可以用numpy的通常的广播行为,这种行为:

def divide_along_axis(a,b,axis=None): 
    if axis is None: 
     return a/b 
    c = a.copy() 
    for i, x in enumerate(c.swapaxes(0,axis)): 
     x /= b[i] 
    return c 

例如,标准化向量的阵列时,这是非常有用的

In [9]: a = np.array([[1., 2.], [3., 4.]]) 

In [10]: a/np.sum(a, axis=0) 
Out[10]: 
array([[ 0.25  , 0.33333333], 
     [ 0.75  , 0.66666667]]) 

如果我解释正确。

如果希望其它轴你可以移调一切:

> a = np.random.randn(4,3).transpose() 
> norms = np.apply_along_axis(np.linalg.norm,0,a) 
> c = a/norms 
> np.apply_along_axis(np.linalg.norm,0,c) 
array([ 1., 1., 1., 1.]) 
+0

不,你没有。该方法例如以我给出的二维数组为例失败。事实证明,对于我给你的例子可以做c = a/np.apply_along_axis(np.linalg.norm,1,a)[:, np.newaxis],但是我正在寻找一些更通用的函数divide_along_axis()我在问题中定义。 – user545424

+1

转座如何(请参阅编辑答案)?或者,您可以先定义“divide_along_axis”,然后进行分割,然后转换回来。 – Owen

+1

只需为您的1d阵列添加一个新轴。 – tillsten