Управляйте тем, как NumPy бросает тип через пользовательскую функцию - PullRequest
3 голосов
/ 02 мая 2019

Когда вы вызываете np.array для итерируемого объекта, он пытается привести их все к одному и тому же типу. Так, например, итерация из нескольких целых чисел и одного числа с плавающей точкой будет приведена к числу с плавающей точкой.

>>> np.array([[1, 2],[3, 4.0]])
array([[1., 2.],
       [3., 4.]])

Но я хочу найти способ иметь пользовательские типы, которые определяют способ их приведения.

По существу:

    class custom():

        def __init__(self, x):
            self.x = x

        def __as_numpy_value__(self): # This is the function I want!
            return f(self.x)

        def f(self):
            # some arbitrary tranformation of x
            # into a valid input for np.array

f(self) может быть отдельным значением или списком ...

class Expandable():
    def __as_numpy_value__(self):
        return [1,2,3]

>>> x = Expandable()
>>> np.array([x, x, x, [4, 5, 6]])
array([[1, 2, 3],
        [1, 2, 3],
        [1, 2, 3],
        [4, 5, 6]])

В идеале, был бы какой-то способ просто добавить метод в мой класс. Если для этого требуется создать подкласс np.array (или его конструктор (?)), Это тоже подойдет.

РЕДАКТИРОВАТЬ: Некоторые конкретные примеры того, что я хочу сделать ...

class SpecialFraction(fractions.Fraction):

    def __as_numpy_value__(self):
        return [self.numerator, self.denominator]

>>> np.array(SpecialFraction(1/2))
array([1,2])

class SpecialTuple(tuple):

    def __as_numpy_value__(self):
        np_val = []
        for x in self:
            if x is not None:
                np_val.append(x+0j)
            else:
                np_val.append(0+1j)
        return np_val

>>> np.array(SpecialTuple((None, 1)))
array([0+1j, 1+0j])

РЕДАКТИРОВАТЬ: наиболее обобщенная версия моего вопроса

Есть ли в Numpy какие-либо встроенные средства для пользовательского определения того, как пользовательские типы обрабатываются при переносе в массив?

Другими словами ... существует ли какой-нибудь реальный эквивалент моего метода фантазии Дандер __as_numpy_value__.

...