gpt4 book ai didi

python - 转让 numpy 数据的所有权

转载 作者:太空狗 更新时间:2023-10-29 18:32:58 26 4
gpt4 key购买 nike

在我的previous question ,我学会了调整子类 ndarray 的大小。整洁的。不幸的是,当我尝试调整大小的数组是计算结果时,这不再有效:

import numpy as np

class Foo(np.ndarray):
def __new__(cls,shape,dtype=np.float32,buffer=None,offset=0,
strides=None,order=None):
return np.ndarray.__new__(cls,shape,dtype,buffer,offset,strides,order)

def __array_prepare__(self,output,context):
print output.flags['OWNDATA'],"PREPARE",type(output)
return np.ndarray.__array_prepare__(self,output,context)

def __array_wrap__(self,output,context=None):
print output.flags['OWNDATA'],"WRAP",type(output)

return np.ndarray.__array_wrap__(self,output,context)

a = Foo((32,))
#resizing a is no problem
a.resize((24,),refcheck=False)

b = Foo((32,))
c = Foo((32,))

d = b+c
#Cannot resize `d`
d.resize((24,),refcheck=False)

准确的输出(包括回溯)是:

True PREPARE <type 'numpy.ndarray'>
False WRAP <class '__main__.Foo'>
Traceback (most recent call last):
File "test.py", line 26, in <module>
d.resize((24,),refcheck=False)
ValueError: cannot resize this array: it does not own its data

我认为这是因为 numpy 创建了一个新的 ndarray 并将其传递给 __array_prepare__。不过,在这个过程中的某个时刻,似乎“output”数组获取 view-casted to my Foo type ,尽管文档在这一点上似乎不是 100% 清楚/准确。无论如何,在 View 转换之后,输出不再拥有数据,因此无法就地 reshape (据我所知)。

有没有办法通过某种 numpy 巫术(__array_prepare____array__)等将数据的所有权转移到我的子类的实例?

最佳答案

这不是一个令人满意的答案,但它也不适合评论...您可以使用 ufunc 的 out 参数解决数据的所有权问题。一个愚蠢的例子:

>>> a = Foo((5,))
>>> b = Foo((5,))
>>> c = a + b # BAD
True PREPARE <type 'numpy.ndarray'>
False WRAP <class '__main__.Foo'>
>>> c.flags.owndata
False

>>> c = Foo((5,))
>>> c[:] = a + b # BETTER
True PREPARE <type 'numpy.ndarray'>
False WRAP <class '__main__.Foo'>
>>> c.flags.owndata
True

>>> np.add(a, b, out=c) # BEST
True PREPARE <class '__main__.Foo'>
True WRAP <class '__main__.Foo'>
Foo([ 1.37754085e-38, 1.68450356e-20, 6.91042737e-37,
1.74735556e-04, 1.48018885e+29], dtype=float32)
>>> c.flags.owndata
True

我认为上面的输出与 c[:] = a + b 一致大批。但是当您使用 out 参数时,这不应该发生。

由于您已经担心数学表达式中的中间存储,因此对它的处理方式进行微观管理可能并不是一件坏事。即替换

g = a + b + np.sqrt(d*d + e*e + f*f)

g = foo_like(d) # you'll need to write this function!
np.multiply(d, d, out=g)
g += e * e
g += f * f
np.sqrt(g, out=g)
g += b
g += a

可以为您节省一些中间内存,并让您拥有自己的数据。它确实把“可读性很重要”的口头禅抛到了窗外,但是……

关于python - 转让 numpy 数据的所有权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15424211/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com