Систематически превращать (numpy) 1d-массив размером 1 в скалярPython

Программы на Python
Anonymous
Систематически превращать (numpy) 1d-массив размером 1 в скаляр

Сообщение Anonymous »

Я ломал голову над этим последний час.
Представьте, что у меня есть функция, которая принимает в качестве аргумента число или массив до измерения 1. Я бы хотелось бы, чтобы он возвращал скаляр (а не массив 0d) в первом случае и массив той же формы во втором случае, как это делает ufuncs.
Текущая реализация моей функции делает что-то вроде

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

def func(x: Real | np.ndarray, arr: np.ndarray):
"""Illustrate an actually more complicated  function"""
return arr @ np.sin(arr[:, None] * x)
и я знаю, что arr — это одномерный массив. Его повышают до 2d, чтобы не было проблем с широковещательной передачей при поэлементном умножении. Проблема в том, что систематически возвращается массив 1d. Удобство в том, что
  • x скаляр и len(arr) == 1;
  • x скаляр и len (arr) > 1 ;
  • x массив и len(arr) == 1 ;
  • x массив и len(arr) >= 1 и (len(x) != len(arr) или len(x) == len(arr))
покрываются однострочным ( последнее тавтологическое утверждение здесь для акцента).
Я пробовал

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

@np.vectorize
def func(x, arr):
return arr @ np.sin(arr * x)
который также постоянно возвращает массив 1d и, вероятно, не самый лучший с точки зрения производительности.
Я посмотрел functools.singledispatch, что приводит к большому дублированию , и я, вероятно, забыл бы о некоторых крайних случаях.
Решением было бы

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

def func(x, arr):
res = arr @ np.sin(arr[:, None] * x)
if len(res) == 1:
return res.item()
return res
но у меня много таких функций, и это не кажется питоническим? Я могу написать декоратор для записи этой проверки,

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

def give_me_a_scalar(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
res = f(*args, **kwargs)
if len(res) == 1:
return res.item()
return res
return wrapper
Кажется, я делаю то, что хочу, но мне трудно поверить, что ничего подобного еще не существует. Я упускаю что-то более простое?


Подробнее здесь: https://stackoverflow.com/questions/786 ... -to-scalar

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