2015-09-14 133 views
2

當numpy.apply_along_axis將1d數組作爲輸入時會發生什麼?當我用它維數組上,我看到了一些奇怪的事情:1d陣列上的numpy apply_along_axis

y=array([1,2,3,4]) 

首先嚐試:

apply_along_axis(lambda x: x > 2, 0, y) 
apply_along_axis(lambda x: x - 2, 0, y) 

回報:

array([False, False, True, True], dtype=bool) 
array([-1, 0, 1, 2]) 

然而,當我嘗試:

apply_along_axis(lambda x: x - 2 if x > 2 else x, 0, y) 

我收到一個錯誤:

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

我當然可以使用列表解析,然後轉換回陣列代替,但似乎令人費解,我覺得當應用於一維數組像我失去了一些東西約apply_along_axis。

UPDATE:按照傑夫G公司的回答,我的困惑來自一個事實,即只有一個軸一維數組,什麼被傳遞給函數實際上是在一維數組本身,而不是單個元素造成的。

「numpy.where」顯然對我所選擇的例子更好(也不需要apply_along_axis),但我的問題實際上是將每個普通函數(需要一個標量並返回一個標量)應用於每個函數一個數組的元素(除了列表理解),類似於pandas.Series.apply(或map)。我知道'向量化',但它似乎不比列表理解更難處理。

回答

4

我不清楚你是否在問如果y必須是1-D(答案是否定的,它可以是多維的),或者如果你問到傳入apply_along_axis的函數。對此,答案是肯定的:你傳遞的函數必須採用一維數組。 (這明確表示爲in the function's documentation)。

在您的三個示例中,typex始終是一維數組。前兩個例子工作的原因是因爲Python隱式地沿着該陣列廣播了>-運算符。

你的第三個例子失敗了,因爲在if/else這個陣列上沒有這樣的廣播。爲了與apply_along_axis一起工作,您需要傳遞一個需要一維數組的函數。 numpy.where將爲此工作:

>>> apply_along_axis(lambda x: numpy.where(x > 2, x - 2, x), 0, y) 
array([1, 2, 1, 2]) 

P.S.在所有這些例子中,由於廣播,apply_along_axis是不必要的。你可以實現這些相同的結果:

>>> y > 2 
>>> y - 2 
>>> numpy.where(y > 2, y - 2, y) 
+0

謝謝 - 我已經編輯了我的問題稍微更確切,但你確實回答了我的問題。不過,我有一個後續的時間太長了,所以我也在上面添加了UPDATE。 –

1

這個答案解決了更新的增編你原來的問題:

numpy.vectorize將採取的elementwise功能,並返回一個新的功能。新功能可以應用於整個陣列。這就像map,但它使用numpy的廣播規則。

f = lambda x: x - 2 if x > 2 else x # your elementwise fn 
fv = np.vectorize(f) 
fv(np.array([1,2,3,4])) 
# Out[5]: array([1, 2, 1, 2])