python: Use your own class for numpy ndarray

You can refer to https://numpy.org/doc/stable/user/basics.subclassing.html#module-numpy.doc.subclassing (official).

Below is a simple implementation example.

class Element:
    def __init__(self, r, c):
        self.r = r
        self.c = c
        
    def __repr__(self):
        return f'Element({self.r},{self.c})'

Suppose you want to use Element (r, c) in the r row and c column of the above self-made class as an element of a 2D ndarray.

Create the MyNdarray class by inheriting np.ndarray as follows.

import numpy as np

class MyNdarray(np.ndarray):
    def __new__(cls, dimension):
        shape = (dimension, dimension)
        return super().__new__(cls, shape, dtype=Element)

    def __init__(self, dimension):
        for r in range(dimension):
            for c in range(dimension):
                self[r, c] = Element(r, c)

Create a numpy ndarray instance with shape (dimension * dimension) with __new__, and perform the initial operation (constructor) with __init__.

a = MyNdarray(3)
>> MyNdarray([[Element(0,0), Element(0,1), Element(0,2)],
           [Element(1,0), Element(1,1), Element(1,2)],
           [Element(2,0), Element(2,1), Element(2,2)]], dtype=object)
a[0, 0]
>> Element(0,0)

It would be nice to be able to use the slicing operation and transpose function of ndarray as it is.

a[:, 0:2]
>> MyNdarray([[Element(0,0), Element(0,1)],
           [Element(1,0), Element(1,1)],
           [Element(2,0), Element(2,1)]], dtype=object)
a.T
>> MyNdarray([[Element(0,0), Element(1,0), Element(2,0)],
           [Element(0,1), Element(1,1), Element(2,1)],
           [Element(0,2), Element(1,2), Element(2,2)]], dtype=object)


Also, if you want to add an attribute to the MyNdarray class, use the __array_finalize__ function.

import numpy as np

class MyNdarray(np.ndarray):
    def __new__(cls, dimension):
        shape = (dimension, dimension)
        obj = super().__new__(cls, shape, dtype=Element)
        obj.dimension = dimension
        return obj
    
    def __init__(self, dimension):
        for r in range(dimension):
            for c in range(dimension):
                self[r, c] = Element(r, c)
                
    def __array_finalize__(self, obj):
        if obj is None:
            return
        self.dimension = getattr(obj, 'dimension', None)
a = MyNdarray(3)
a.dimension
>>> 3

Recommended Posts

python: Use your own class for numpy ndarray
Easily use your own functions in Python
[Python] Implement your own list-like class using collections.UserList
Don't use readlines () in your Python for statement!
How to access data with object ['key'] for your own Python class
Use data class for data storage of Python 3.7 or higher
Use the CASA Toolkit in your own Python environment
[Road to intermediate Python] Define in in your own class
[Python] Make your own LINE bot
[Python] logging in your own module
[Introduction to Python] <numpy ndarray> [edit: 2020/02/22]
Next, use Python (Flask) for Heroku!
Beginners use Python for web scraping (4) ―― 1
Create your own graph structure class and its drawing in python
Try docker: Create your own container image for your Python web app
Specify your own class in class argument and return type annotation in Python
[Introduction to Python] How to use class in Python?
Create your own Linux commands in Python
Use DeepL with python (for dissertation translation)
[LLDB] Create your own command in Python
[Python] Package and distribute your own modules
Make your own PC for deep learning
Use a scripting language for a comfortable C ++ life 4-Use your own C ++ library from a scripting language-
[Python] Register your own library on PyPI
[Python] Organizing how to use for statements
Until you install your own Python library
Use Numpy
How to use "deque" for Python data
[Python] It was very convenient to use a Python class for a ROS program.
Get your own IP address in Python
[Python] matplotlib: Format the diagram for your dissertation
Use logger with Python for the time being
Make your own module quickly with setuptools (python)
Python: Prepare a serializer for the class instance:
Import your own modules in Grasshopper's Python development
Wrap C ++ with Cython for use from Python
How to make Python faster for beginners [numpy]
2016-10-30 else for Python3> for:
My Numpy (Python)
python [for myself]
"Kanrika" python class
#Python basics (#Numpy 1/2)
#Python basics (#Numpy 2/2)
[Numpy] Shuffle ndarray
Python class, instance
Python #Numpy basics
#Python basics (class)
[Python] Numpy memo
[For beginners] How to use say command in python!
Beginners can use Python for web scraping (1) Improved version
Memo to create your own Box with Pepper's Python
Make your python CUI application an app for mac
[Introduction to Udemy Python 3 + Application] 66. Creating your own exceptions
Convert NumPy array "ndarray" to lilt in Python [tolist ()]
Take your own peak memory usage on Linux & Python
Create your own Random Dot Stereogram (RDS) in Python.
Try to improve your own intro quiz in Python
[Python] 2 Create a risk-return map for your asset portfolio
Use Python installed with pyenv for PL / Python execution environment
Use urlparse.urljoin instead of os.path.join for Python URL joins
[Blender × Python] Create your own function & summary so far