Как передать контейнеры пользовательских массивов в np.where? ⇐ Python

Программы на Python
Anonymous
Как передать контейнеры пользовательских массивов в np.where?

Сообщение Anonymous »

Я пытаюсь использовать np.ndarrays в своем пользовательском классе в качестве одного из атрибутов (myClass.data) и следую этому руководству в документации NumPy https://numpy.org/devdocs/user/basics.dispatch. html для написания пользовательских контейнеров массивов. Мне удалось зарегистрировать реализации array_function для np.sum, np.mean, np.std, однако я не могу понять, как это сделать для np.where, что приводит к ошибкам RecursionErrors.Это макет моего текущего подхода с соответствующей информацией о классе. В основном это результат следования руководству, поэтому array, array_ufunc и array_function взяты оттуда с небольшими изменениями, чтобы адаптировать их к моему классу.< /p>

Код: Выделить всё

from numpy.typing import ArrayLike
import numpy as np
import pandas as pd
import numpy.lib.mixins
from numbers import Number

HANDLED_FUNCTIONS = {}

def implements(np_function):
def decorator(func):
HANDLED_FUNCTIONS[np_function] = func
return func
return decorator

class myClass(numpy.lib.mixins.NDArrayOperatorsMixin):
def __init__(self, name, data: ArrayLike, index: ArrayLike):
self.name = name
self.data = data
self.index = index

def __array__(self, dtype=None, copy=None):
if copy is False:
raise ValueError(
"`copy=False` isn't supported. A copy is always created."
)
return self.data

def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
if method == '__call__':
_index = None
scalars = []
for input in inputs:
if isinstance(input, Number):
scalars.append(input)
elif isinstance(input, self.__class__):
scalars.append(input.data)
if _index is not None:
if _index != input.index:
raise TypeError("inconsistent sizes")
else:
_index = input.index
else:
return NotImplemented
return self.__class__(self.name, ufunc(*scalars, **kwargs), _index)
else:
return NotImplemented

def __array_function__(self, func, types, args, kwargs):
if func not in HANDLED_FUNCTIONS:
return NotImplemented
if not all(issubclass(t, self.__class__) for t in types):
return NotImplemented
return HANDLED_FUNCTIONS[func](*args, **kwargs)

@implements(np.mean)
def mean(arr):
return np.mean(arr.data)

@implements(np.sum)
def sum(arr):
return np.sum(arr.data)

@implements(np.where)
def where(condition, x, y):
if isinstance(x, myClass):
x = x.data
if isinstance(y, myClass):
y = y.data
return np.where(condition, x, y)

Код: Выделить всё

The error when trying to call this like np.where(myclassobj > 1, 0, 1) is:
File ~test.py:74, in where(condition, x, y)
72 if isinstance(y, myClass):
73     y = y.data
---> 74 return np.where(condition, x, y)

File ~test.py:53, in myClass.__array_function__(self, func, types, args, kwargs)
51 if func not in HANDLED_FUNCTIONS:
52     return NotImplemented
---> 53 if not all(issubclass(t, self.__class__) for t in types):
54     return NotImplemented
55 return HANDLED_FUNCTIONS[func](*args, **kwargs)

RecursionError: maximum recursion depth exceeded
Есть ли у кого-нибудь опыт реализации np.where для пользовательских массивов? Я посмотрел на dask и cupy, чтобы увидеть их реализацию, но понять это сложно.
Py3.10, numpy 1.26.4

Подробнее здесь: https://stackoverflow.com/questions/790 ... o-np-where

Вернуться в «Python»