Numpy Assignment Оператор Назначение - PullRequest
0 голосов
/ 20 мая 2019

Как создать переменную, связывающуюся с оператором присваивания numpy (=)?Например, мы можем присвоить равное добавление, например, op = numpy.ndarray.__iadd__, а затем вызвать его, используя op(initial_var, increment), что будет равно initial_var += increment.Однако я не могу понять, как сделать такую ​​же привязку op к оператору присваивания =.

Почему я это делаю?Просто, чтобы немного оптимизировать, в некоторых случаях мы можем избежать дополнительных затрат __add__, просто скопировав элемент numpy.ndarray вместо вызова __iadd__.Что было бы более изобразительным / уродливым способом:

if a:
 b = c
else:
 b += c

Ответы [ 2 ]

0 голосов
/ 20 мая 2019

Во-первых, давайте разберемся, почему то, что вы пытаетесь достичь, сложно.Что должна сделать функция op_assgn(a, b), которая каким-то образом заменяет присвоение a=b?Основная трудность заключается в том, что ему нужно знать имя объекта, который вызывающий объект передал в качестве аргумента a.Фактически, объект, связанный с a в данный момент времени, совершенно не имеет значения, но это то, что доступно для op_assgn.Таким образом, если бы мы были склонны к тому, чтобы заставить это работать, функция должна была бы просмотреть один кадр, найти оператор вызова, каким-то образом получить те аргументы, которые были переданы, и привязать значение к имени вне его (функции) области.Вероятно, это можно сделать, но не без значительного количества черной магии.

Так что, возможно, разумнее не трогать само задание и делать упаковку непосредственно перед этим.Вот простая реализация этой идеи.

def op1(b, c):
    return c

op2 = np.ndarray.__iadd__

c = np.array((1,2))
b = np.array((0,0))

Обратите внимание, что мы присваиваем новую переменную d просто для того, чтобы увидеть, что именно происходит.В конечном счете, вы захотите присвоить b.

# this is straight-forward
d = op1(b, c)
d is c
# True
d is b
# False
d
# array([1, 2])

# this works because .__iadd__ does the inplace op AND
# returns the modified object
d = op2(b, c)
d is c
# False
d is b
# True
d
# array([1, 2])

Итак, в основном это делает то, что вы хотите (как только вы заменили d на b), за исключением того, что это включает в себя чуть-чутьбольше ввода и его эквивалент, если предложение if будет выглядеть примерно так:

if a:
 b = c
else:
 b += c
 b = b

с этим немного уродливым избыточным назначением в последней строке.

Обратите внимание, что это в основном эстетическая проблема, так какназначение --- выполняется по ссылке --- дешево:

def f1():
    global c
    c.__iadd__(b)

def f2():
    global c
    c = c.__iadd__(b)

timeit(f1)
# 1.4087995890295133
timeit(f2)
# 1.4474492500303313
0 голосов
/ 20 мая 2019

Я предлагаю:

import numpy as np
op = lambda x,y: np.ndarray.__eq__(x, y).all()

# Examples

a = np.array([1,2,3])
b = np.array([1,2,3])
print(op(a, b)) # True


c = np.array([1,2,6])
print(op(a, c)) # False

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...