2011-08-21 58 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