📖 Scenario: Imagine you have a list of temperatures in Celsius and you want to convert them to Fahrenheit. Normally, you might write a loop or use a simple function. But what if you want to do this conversion very fast on large arrays? That's where custom ufuncs in NumPy help.
🎯 Goal: You will create a simple custom universal function (ufunc) in NumPy to convert Celsius temperatures to Fahrenheit. Then you will apply it to a NumPy array and see the fast, easy result.
📋 What You'll Learn
Create a NumPy array with exact Celsius temperatures
Define a Python function to convert Celsius to Fahrenheit
Create a custom ufunc from the Python function using NumPy's frompyfunc
Apply the custom ufunc to the NumPy array
Print the resulting Fahrenheit temperatures
💡 Why This Matters
🌍 Real World
Scientists and engineers often need to apply custom calculations on large datasets quickly. Custom ufuncs let them do this efficiently with NumPy arrays.
💼 Career
Data scientists and analysts use custom ufuncs to speed up data transformations and apply complex functions element-wise in their data pipelines.
Progress0 / 4 steps
1
Create a NumPy array of Celsius temperatures
Import NumPy as np and create a NumPy array called celsius_temps with these exact values: 0, 20, 37, 100.
NumPy
Hint
Use np.array([...]) to create the array.
2
Define a Python function to convert Celsius to Fahrenheit
Define a function called c_to_f that takes one argument c and returns the Fahrenheit temperature using the formula c * 9 / 5 + 32.
NumPy
Hint
Remember to use def to define the function and return the converted value.
3
Create a custom ufunc from the Python function
Use np.frompyfunc to create a universal function called c_to_f_ufunc from the c_to_f function. Specify it takes 1 input and returns 1 output.
NumPy
Hint
Use np.frompyfunc(function, nin, nout) where nin is number of inputs and nout is number of outputs.
4
Apply the custom ufunc and print the result
Apply the c_to_f_ufunc to the celsius_temps array and store the result in fahrenheit_temps. Then print fahrenheit_temps.
NumPy
Hint
Use fahrenheit_temps = c_to_f_ufunc(celsius_temps) and then print(fahrenheit_temps).
Practice
(1/5)
1. Why do custom ufuncs matter in numpy?
easy
A. They let you apply your own functions element-wise on arrays easily.
B. They are used to create plots from arrays.
C. They replace the need for Python loops in all cases.
D. They automatically fix errors in array data.
Solution
Step 1: Understand the purpose of custom ufuncs
Custom ufuncs allow you to apply your own math or logic functions element-wise on numpy arrays, making operations simpler.
Step 2: Compare with other options
The other options describe unrelated or incorrect uses of custom ufuncs.
Final Answer:
They let you apply your own functions element-wise on arrays easily. -> Option A
Hint: Custom ufuncs = your function applied to each array item [OK]
Common Mistakes:
Thinking custom ufuncs create plots
Believing they fix data errors automatically
Confusing them with general Python loops
2. Which of the following is the correct way to create a custom ufunc using np.vectorize?
easy
A. ufunc = np.vectorize(my_function())
B. ufunc = np.vectorize[my_function]
C. ufunc = np.vectorize(my_function)
D. ufunc = np.vectorize{my_function}
Solution
Step 1: Recall the syntax of np.vectorize
The correct syntax to create a vectorized function is np.vectorize(function_name) without brackets after the function name.
Step 2: Analyze each option
ufunc = np.vectorize(my_function) uses parentheses correctly. ufunc = np.vectorize[my_function] uses square brackets which is invalid. ufunc = np.vectorize{my_function} uses curly braces which is invalid. ufunc = np.vectorize(my_function()) calls the function immediately, which is incorrect.
Final Answer:
ufunc = np.vectorize(my_function) -> Option C
Quick Check:
np.vectorize(function) uses parentheses [OK]
Hint: Use parentheses with np.vectorize, not brackets or braces [OK]
The function squares the input and adds 1: x**2 + 1.
Step 2: Apply function to each array element
For arr = [1, 2, 3]: 1**2+1=2, 2**2+1=5, 3**2+1=10.
Final Answer:
[2 5 10] -> Option A
Quick Check:
Square plus one applied element-wise = [2 5 10] [OK]
Hint: Apply function to each element: square then add one [OK]
Common Mistakes:
Forgetting to add 1 after squaring
Confusing output with original array
Mixing up element-wise operation
4. Identify the error in this code that tries to create a custom ufunc:
import numpy as np
def add_three(x):
return x + 3
ufunc = np.vectorize(add_three())
arr = np.array([1, 2, 3])
print(ufunc(arr))
medium
A. Missing import statement for numpy.
B. Calling add_three() inside np.vectorize instead of passing the function.
C. Using np.vectorize instead of np.frompyfunc.
D. Array arr is not defined.
Solution
Step 1: Check how np.vectorize is called
np.vectorize expects a function, but add_three() calls the function immediately, passing its result instead.
Step 2: Understand the impact of the error
Calling add_three() returns an integer, not a function, causing np.vectorize to fail or behave incorrectly.
Final Answer:
Calling add_three() inside np.vectorize instead of passing the function. -> Option B
Quick Check:
Pass function name, don't call it inside np.vectorize [OK]
Hint: Pass function name to np.vectorize, don't call it [OK]
Common Mistakes:
Calling function inside np.vectorize
Confusing function call with function reference
Ignoring error messages about wrong argument type
5. You want to create a custom ufunc that returns the sign of each element in an array: -1 if negative, 0 if zero, and 1 if positive. Which code correctly creates and applies this ufunc to np.array([-2, 0, 3])?
hard
A. def sign_func(x):
if x <= 0:
return 1
else:
return -1
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3])))
B. def sign_func(x):
return x > 0
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3])))
C. def sign_func(x):
return x
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3])))
D. def sign_func(x):
if x < 0:
return -1
elif x == 0:
return 0
else:
return 1
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3])))
Solution
Step 1: Understand the sign function requirements
The function must return -1 for negative, 0 for zero, and 1 for positive values.
Step 2: Check each option's logic
def sign_func(x):
if x < 0:
return -1
elif x == 0:
return 0
else:
return 1
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3]))) correctly implements the conditions. def sign_func(x):
return x > 0
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3]))) returns True/False, not -1/0/1. def sign_func(x):
return x
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3]))) returns the value itself, not the sign. def sign_func(x):
if x <= 0:
return 1
else:
return -1
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3]))) reverses sign logic and misses zero case.
Final Answer:
def sign_func(x):
if x < 0:
return -1
elif x == 0:
return 0
else:
return 1
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3]))) -> Option D
Quick Check:
Correct sign logic with if-elif-else = def sign_func(x):
if x < 0:
return -1
elif x == 0:
return 0
else:
return 1
sign_ufunc = np.vectorize(sign_func)
print(sign_ufunc(np.array([-2, 0, 3]))) [OK]
Hint: Use if-elif-else to cover negative, zero, positive cases [OK]
Common Mistakes:
Returning boolean instead of -1,0,1
Ignoring zero case
Reversing sign conditions
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.