I'm trying to apply a vectorized function over a 2-d array in numpy row-wise, and I'm encountering ValueError: setting an array element with a sequence.
import numpy as np
X = np.array([[0, 1], [2, 2], [3, 0]], dtype=float)
coeffs = np.array([1, 1], dtype=float)
np.apply_along_axis(
np.vectorize(lambda row: 1.0 / (1.0 + np.exp(-coeffs.dot(row)))),
0, X
)
I don't totally know how to interpret this error. How am I setting an array element with a sequence?
When I test the lambda function on a single row, it works and returns a single float. Somehow it's failing within the scope of this vectorized function, which leads me to believe that either the vectorized function is wrong or I'm not using apply_along_axis
correctly.
Is it possible to use a vectorized function in this context? If so, how? Can a vectorized function take an array or am I misunderstanding the documentation?
In v 1.12
vectorize
docs says:In your attempt:
apply_along_axis
iterates on all axes except0
, and feeds the resulting 1d array to its function. So for 2d it will iterate on 1 axis, and feed the other.Divakar
shows it iterating on the 0 axis, and feeding rows. So it's basically the same as the list comprehension with an array wrapper.apply_along_axis
makes more sense with 3d or higher inputs, where it's more fiddly to iterate on 2 axes and feed the third to your function.Writing your lambda as a function:
Given an array (row) it returns a scalar:
But given a scalar, it returns an array:
That explains the
sequence
error message.vectorize
expected your function to return a scalar, but it got an array.signature
In v 1.12
vectorize
adds asignature
parameter, which lets us feed something bigger than a scalar to the function. I explored it in:https://stackoverflow.com/a/44752552/901925
Using the
signature
I getvectorize
to work with:the same thing as this:
timings
list comprehension is fastest,
vectorize
slowest.You are sum-reducing the second axis of
X
against the only axis ofcoeffs
. So, you could simply usenp.dot(X,coeffs)
forsum-reductions
.Thus, a vectorized solution would be -
Sample run -
The correct way to use
np.apply_along_axis
would be to dropnp.vectorize
and apply it along the second axis ofX
, i.e. every row ofX
-