NumPy extends Python’s basic mathematical functionality in a number of different ways. The additional functionality makes Python a lot more powerful. However, using NumPy also means getting used to a lot of new functions. We often even need to approach objects in a very different way than we might expect. Error messages that seem contrary to our expectations are fairly common when getting used to NumPy. For example, what does an operands could not be broadcast together with shapes error really mean?
What is this error?
This error message can seem somewhat intimidating at first glance. However, it’s actually describing something fairly simple. A NumPy array is similar in some respects to what we find in the standard Python library. The main difference is that with NumPy we can extend an array into a new dimension and a different shape before we do matrix multiplication and other arithmetic operations. These multidimensional arrays offer a lot more power. However, they’re a little trickier to work with than a one dimensional array. When we broadcast two arrays NumPy examines the different shape of each. If they’re not compatible shapes to complete arithmetic operations then we’ll get the broadcast error.
What is causing it?
One of larger issues with NumPy arrays is that we’re suddenly in a world where things are multidimensional. We need to think of things as a matrix rather than a one dimensional array or two dimensional array. Array operations are usually going to be very picky about one smaller array that has a different size than the other larger array, making any mathematical operation such as element wise multiplication much harder than it would be with a function in just the first or second dimension. We’ll typically get a valueerror that points at a specific element in a larger array that’s causing issues. But that’s not always going to be the case.
How do I fix it?
We can typically ease these problems by reducing or expanding a multidimensional array in our code. Bringing a smaller array into a higher dimension is known as broadcasting. In this case, an array will receive an extra dimension and axes to allow for proper symmetry in your dataset. This isn’t a totally seamless and automated process though. Sometimes we’ll need to put in a little work on the matrices beforehand to make the magic happen.
We’ll take an example of two array shapes, A and B. A is incompatible with B due to incompatible dimensions- one is a one dimensional array, the other is a 2d array, so the number of axes is different. We can use NumPy’s expand_dims to expand A. For example, to add a higher dimension to A’s last axis we’d use expand_dims(A, axis=-1). Remember that Python uses negatives to work from the back of a value rather than the front. So a -1 would add the extra dimension to the last axis. At this point, the two arrays should be compatible for broadcasting. It’s also important to keep in mind that Python needs to verify that all dimensions are compatible. A complex operation with multiple broadcasts might fail even if only one part of that process is incompatible.
We don’t need to worry about the number of dimensions though. The smaller examples will simply be scaled up by the broadcast. It’s also important to keep in mind that the order of operations in an array comparison for broadcasts starts at the end, rather than the beginning, of an array. So when the Python interpreter encounters a mismatch it’ll report that problem and then stop operations with the error message. This doesn’t mean that the other elements are compatible. It simply means that the reported element triggering the message was the first to come up. As such it’s always a good idea to go over all other parts of the array when debugging a broadcast error.