numpy分配运算符分配

时间:2019-05-20 13:53:58

标签: python numpy

如何创建链接到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 :(得分:0)

我建议:

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

答案 1 :(得分:0)

首先,让我们弄清楚为什么您要实现的目标很困难。以某种方式代替分配op_assgn(a, b)的功能a=b需要做什么?主要困难在于,它将需要知道调用者为参数a传递的对象的 name 。实际上,此时绑定到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