Bird
Raised Fist0
NumPydata~5 mins

Array protocol and __array__ in NumPy

Choose your learning style10 modes available
Introduction

The array protocol lets objects tell NumPy how to convert themselves into arrays. The __array__ method is a simple way to make your object behave like a NumPy array.

You have a custom data object and want to use NumPy functions on it easily.
You want to convert your object to a NumPy array without writing extra code.
You want your object to work smoothly with libraries that expect NumPy arrays.
You want to speed up data processing by using NumPy's fast operations on your data.
Syntax
NumPy
class YourClass:
    def __array__(self, dtype=None):
        # Return a NumPy array representation of your data
        import numpy as np
        data = ...  # your data here
        if dtype is not None:
            return np.array(data, dtype=dtype)
        else:
            return np.array(data)

The __array__ method should return a NumPy array.

The optional dtype argument lets NumPy request a specific data type.

Examples
Converts a simple list inside a custom object to a NumPy array.
NumPy
import numpy as np

class SimpleData:
    def __init__(self, values):
        self.values = values
    def __array__(self, dtype=None):
        if dtype is not None:
            return np.array(self.values, dtype=dtype)
        return np.array(self.values)

obj = SimpleData([1, 2, 3])
print(np.array(obj))
Handles the edge case where the data is empty, returning an empty array.
NumPy
import numpy as np

class EmptyData:
    def __array__(self, dtype=None):
        return np.array([])

obj = EmptyData()
print(np.array(obj))
Handles the case with only one element, returning a one-element array.
NumPy
import numpy as np

class SingleValueData:
    def __init__(self, value):
        self.value = value
    def __array__(self, dtype=None):
        return np.array([self.value], dtype=dtype) if dtype is not None else np.array([self.value])

obj = SingleValueData(42)
print(np.array(obj))
Converts a list with values at the beginning and end to a NumPy array.
NumPy
import numpy as np

class DataAtEdges:
    def __init__(self, values):
        self.values = values
    def __array__(self, dtype=None):
        return np.array(self.values, dtype=dtype) if dtype is not None else np.array(self.values)

obj = DataAtEdges([0, 1, 2, 3, 4])
print(np.array(obj))
Sample Program

This program shows how a custom object with a __array__ method can be converted to a NumPy array automatically. It prints the original data, the converted array, and calculates the mean using NumPy.

NumPy
import numpy as np

class CustomData:
    def __init__(self, data_list):
        self.data_list = data_list
    def __array__(self, dtype=None):
        # Convert internal list to numpy array
        if dtype is not None:
            return np.array(self.data_list, dtype=dtype)
        return np.array(self.data_list)

# Create an object with some data
custom_object = CustomData([10, 20, 30, 40])

# Print the object data before conversion
print('Original data in object:', custom_object.data_list)

# Convert to numpy array using the array protocol
numpy_array = np.array(custom_object)
print('Converted to numpy array:', numpy_array)

# Use numpy functions on the converted array
mean_value = np.mean(custom_object)
print('Mean of data:', mean_value)
OutputSuccess
Important Notes

The __array__ method lets NumPy know how to convert your object to an array quickly.

Time complexity depends on the size of your data because it copies data into a new array.

Space complexity is also proportional to the data size since a new array is created.

A common mistake is forgetting to handle the optional dtype argument, which can cause errors when NumPy requests a specific type.

Use __array__ when you want seamless integration with NumPy functions. For simple conversions, you might also use np.array(your_data) directly if your data is already array-like.

Summary

The __array__ method allows custom objects to behave like NumPy arrays.

It helps NumPy convert your data automatically for fast numerical operations.

Remember to handle the optional dtype argument for flexibility.

Practice

(1/5)
1. What is the main purpose of the __array__ method in a custom Python class when working with NumPy?
easy
A. To create a plot from the array data
B. To allow the object to be converted automatically into a NumPy array
C. To perform element-wise multiplication on arrays
D. To define a new data type for NumPy arrays

Solution

  1. Step 1: Understand the role of __array__

    The __array__ method is designed to let custom objects tell NumPy how to convert them into arrays.
  2. Step 2: Identify the main purpose

    This method enables automatic conversion, so NumPy can work with the data efficiently.
  3. Final Answer:

    To allow the object to be converted automatically into a NumPy array -> Option B
  4. Quick Check:

    Conversion to NumPy array [OK]
Hint: Remember: __array__ means 'convert me to array' [OK]
Common Mistakes:
  • Confusing __array__ with data type definition
  • Thinking __array__ performs calculations
  • Assuming __array__ creates plots
2. Which of the following is the correct way to define the __array__ method in a custom class to return a NumPy array?
easy
A. def __array__(self, dtype): return self.data.astype(dtype)
B. def __array__(self): return list(self.data)
C. def __array__(self): return self.data.tolist()
D. def __array__(self, dtype=None): return np.array(self.data, dtype=dtype)

Solution

  1. Step 1: Check method signature

    The __array__ method should accept an optional dtype argument for flexibility.
  2. Step 2: Verify return type

    It must return a NumPy array, so using np.array(self.data, dtype=dtype) is correct.
  3. Final Answer:

    def __array__(self, dtype=None): return np.array(self.data, dtype=dtype) -> Option D
  4. Quick Check:

    Correct signature and return type [OK]
Hint: Include dtype=None and return np.array inside __array__ [OK]
Common Mistakes:
  • Omitting dtype parameter
  • Returning list instead of np.array
  • Using tolist() which returns Python list
3. Given the code below, what will be the output of print(np.array(obj))?
import numpy as np

class MyData:
    def __init__(self):
        self.data = [1, 2, 3]
    def __array__(self, dtype=None):
        return np.array(self.data, dtype=dtype)

obj = MyData()
print(np.array(obj))
medium
A. [1 2 3]
B. [[1 2 3]]
C. TypeError: object cannot be converted to array
D. [1, 2, 3]

Solution

  1. Step 1: Understand __array__ method behavior

    The method returns a NumPy array created from the list [1, 2, 3].
  2. Step 2: Predict np.array conversion

    Calling np.array(obj) triggers obj.__array__(), returning np.array([1, 2, 3]), which prints as [1 2 3].
  3. Final Answer:

    [1 2 3] -> Option A
  4. Quick Check:

    Custom __array__ returns array [1 2 3] [OK]
Hint: np.array calls __array__, returns array, prints without commas [OK]
Common Mistakes:
  • Expecting Python list output with commas
  • Thinking output is nested array
  • Assuming TypeError due to custom class
4. What is wrong with this __array__ method implementation?
def __array__(self):
    return self.data.astype(float)
medium
A. It does not accept the optional dtype argument
B. astype cannot convert to float
C. Returning self.data directly is required
D. The method should return a list, not an array

Solution

  1. Step 1: Check method signature

    The __array__ method should accept an optional dtype argument to allow flexible conversions.
  2. Step 2: Identify missing dtype parameter

    This method lacks the dtype=None parameter, so it cannot handle dtype requests from NumPy.
  3. Final Answer:

    It does not accept the optional dtype argument -> Option A
  4. Quick Check:

    Missing dtype parameter [OK]
Hint: Always include dtype=None in __array__ method [OK]
Common Mistakes:
  • Forgetting dtype argument
  • Thinking astype cannot convert types
  • Returning list instead of array
5. You have a custom class with a __array__ method that returns a NumPy array. You want to ensure that when you call np.array(obj, dtype=np.float64), the returned array respects the requested dtype. How should you modify the __array__ method?
hard
A. def __array__(self, dtype=None): return np.array(self.data)
B. def __array__(self): return np.array(self.data, dtype=np.float64)
C. def __array__(self, dtype=None): return np.array(self.data, dtype=dtype)
D. def __array__(self, dtype): return self.data.astype(dtype)

Solution

  1. Step 1: Understand dtype propagation

    NumPy passes the requested dtype to __array__ as an argument; the method must accept it.
  2. Step 2: Implement dtype-aware conversion

    Return np.array(self.data, dtype=dtype) so the requested dtype is applied correctly.
  3. Final Answer:

    def __array__(self, dtype=None): return np.array(self.data, dtype=dtype) -> Option C
  4. Quick Check:

    Accept dtype and pass to np.array [OK]
Hint: Pass dtype argument to np.array inside __array__ method [OK]
Common Mistakes:
  • Ignoring dtype argument
  • Hardcoding dtype inside method
  • Not accepting dtype parameter
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard