Подклассы numpy .ndarray для принудительного объединения единиц - PullRequest
0 голосов
/ 20 февраля 2020

Я пытаюсь создать новый тип, который в основном является просто np.ndarray, но также имеет атрибут, который отслеживает единицы элементов в массиве.

При создании массив должен перевести в метри c метров (это работает нормально). Я также изменил __getattr__, чтобы он вызывал конвертацию по требованию. Однако я хочу сделать так, чтобы объединение массивов заставило их снова измениться на metri c.

например, если a в метрах и b в ангстремах, a + b должен дать правильный ответ в метрах . Могу ли я изменить __getattr__ и __new__ для достижения этой цели?

Минимальный рабочий пример ниже, спасибо за любую помощь.

import numpy as np


class TypedArray(np.ndarray):
    unit_conversion = {'m': 1.0, 'nm': 10e-9, 'ang': 10e-10}

    def __new__(cls, input_array, unit=None):
        obj = np.asarray(input_array).view(cls) * cls.unit_conversion.get(unit, 1)
        obj.unit = 'm'
        return obj

    def __array_finalize__(self, obj):
        if obj is None:
            return
        self.unit = getattr(obj, 'unit', None)

    def __str__(self):
        return f'{super().__str__()} {self.unit}'

    def __getattr__(self, item):
        self.unit = str(item)
        return self / self.unit_conversion.get(str(item), 1)


a = TypedArray([1, 2, 4], 'ang')
b = TypedArray([2, 3, 4], 'nm')

c = a + b
print(c)
>>> [2.1e-08 3.2e-08 4.4e-08] m
print(c.nm)
>>> [2.1 3.2 4.4] nm

# Should force a unit change; gives incorrect answer.
print(c.nm + c)
>>> [2.10000002 3.20000003 4.40000004] nm
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...