I have a library function that returns a pair of two numbers like this
def library_function(x0, x1):
return x0**2 + x1**2, 10*x0*x1 + 1
(Actually, it is a function that returns predicted probabilities of two classes for some object, but it doesn't matter, so I created an artificial one.) I want to draw contours where the difference between two numbers returned by library_function
is zero. To do so, I have to create a two-dimensional list (or array) with the differences.
I have the following possibilities:
X0 = np.linspace(-10, 10, 200)
X1 = np.linspace(-10, 10, 200)
results = [[(lambda u: u[0]-u[1])(library_function(x0, x1))
for x0 in X0] for x1 in X1]
plt.contour(X0, X1, results, [0])
This approach is concise but I have to introduce lambda
which seem to be considered not so Pythonic.
Another way:
values = [[library_function(x0, x1) for x0 in X0] for x1 in X1]
results = [[a-b for a, b in row] for row in values]
I have to introduce temporary two-dimensional list and this approach is longer.
Are there any ideas how to do it better (more concise and readable)?
2 Answers 2
Since you are using NumPy, you should deal with grids the NumPy way instead of performing list comprehensions.
def probability_diff(x0, x1):
probs = library_function(x0, x1)
return probs[0] - probs[1]
results = np.vectorize(probability_diff)(X0[:, np.newaxis], X1)
I wouldn't try to get too clever with the lambdas.
Also, since the grid happens to be a square, you could use X0
again instead of defining X1
.
-
\$\begingroup\$ Good point about
np.vectorize
, didn't know about it, and a good reference to SO answer. \$\endgroup\$Ilya V. Schurov– Ilya V. Schurov2016年11月26日 14:48:48 +00:00Commented Nov 26, 2016 at 14:48
I think using list comprehensions is generally considered Pythonic. As an improvement, you can opt to use generators for your values
variable.
values = ((library_function(x0, x1) for x0 in X0) for x1 in X1)
results = [[a-b for a, b in row] for row in values]
By using a generator, you're using a constant amount of space for the values
variable. I also think that using more descriptive variable names would be helpful.
Explore related questions
See similar questions with these tags.
library_function
that returns a pair? Perhaps it would be better as two functions? I think I would like to see what your reallibrary_function
is. \$\endgroup\$activate()
and compare it with 0. (Oh, I just discovered that I can just use the first component and compare it with 1/2, which will work if my outputs are probabilites...) \$\endgroup\$