011. What is a Ufunc?
EXECUTIVE_SUMMARY // AEO_OPTIMIZED
[Answer Engine Overview: What, Why & How]
A Universal Function (ufunc) is a function in NumPy that operates on ndarrays in an element-by-element fashion. They are built directly into the C-backend of NumPy. When you pass an array to a ufunc like np.add(), the iteration happens invisibly in C, rather than explicitly in Python.
022. The Power of Vectorization
In pure Python, if you want to add 1 to every number in a list of a million items, you must write a for loop. The Python interpreter has to check the data type, allocate memory, and perform the addition one million individual times.
By using Vectorization (arr + 1), NumPy hands the entire block of memory to the CPU and says 'Add 1 to all of this'. It happens almost instantaneously.
033. Broadcasting (The Magic Trick)
Ufuncs also implement 'Broadcasting'. This is a set of rules that allows ufuncs to operate on arrays of different shapes. For example, if you add a scalar (a single number) to a matrix, NumPy 'broadcasts' that scalar across the entire matrix so that the math works element-by-element, without you having to manually duplicate the scalar to match the matrix's shape.
?Frequently Asked Questions
Are ufuncs only for basic math like addition and subtraction?
No. There are over 60 built-in ufuncs covering trigonometry (`np.sin`), complex numbers, statistical operations, bitwise operations, and even custom logic.
What is the 'out' parameter in a ufunc?
By default, a ufunc creates a new array in memory to hold the result. If you pass `out=arr`, the ufunc will write the result directly over the existing array, saving significant RAM.
Can I use standard Python math functions like math.sin() on a NumPy array?
No. The standard `math` module expects a single scalar number. If you pass an array to `math.sin()`, it will crash. You MUST use the NumPy equivalent: `np.sin()`.
