【问题标题】:Python - how to implement a custom class compatible with NumPy functions?Python - 如何实现与 NumPy 函数兼容的自定义类?
【发布时间】:2017-09-15 12:53:33
【问题描述】:

我正在尝试实现我自己的自定义类来存储数据。我想让它与 NumPy 兼容,这样我就可以像这样调用 NumPy 函数:

np.sin(my_object)

我知道有一本名为__array_interface__ 的字典,但是我在尝试使用它时遇到了很多奇怪的错误。

import numpy as np
import pandas as pd

class TDF:
    __array_interface__ = {'typestr': '|i1', 'version': 1}

    def __init__(self):
        self.ddata = pd.DataFrame([1, 2, 3])
        self.shape = self.ddata.shape

    def __iter__(self):
        return iter(self.ddata)

    def __len__(self):
        return len(self.ddata)

    def __getitem__(self, key):
        return self.ddata.__getitem__(key)

if __name__ == '__main__':
    tdf1 = TDF()
    tdf = np.sin(tdf1)

上面的代码给了我一个运行时错误:

ValueError: setting an array element with a sequence.

我错过了什么? 另一方面,pandas 的源代码(哪些类与 NumPy 兼容)没有明确使用 array_interface dict...

【问题讨论】:

    标签: python arrays class numpy interface


    【解决方案1】:

    一个简单的解决方法是实施

    def __array__(self):
        return self.ddata
    

    【讨论】:

    • 谢谢。是的——这就是我们所需要的。如果你想让一个 numpy 函数的结果是你的自定义类型,你还必须添加方法 array_wrap
    • 有时还有__array_prepare__。即将来到您附近的 numpy:__array_ufunc__,它比 __array_wrap__ 做得更好
    【解决方案2】:

    您没有访问存储在对象中的数据。变量tdf1 只是TDF 实例,但数据存储在tdf1.ddata 中。尝试拨打np.sin(tdf1.ddata)

    【讨论】:

    • 很好。这确实是解决办法
    • 但重点是无缝访问存储在对象中的数据,而不是直接指向它。在pandas对象上使用numpy函数时,不需要指定pandas内部存储数据的变量
    • @Tomasz R:试试def __array__(self): return np.array(self.ddata)
    • @Grr:如果您有__array_interface__ 属性,则永远不会调用__array__。但是,意识到这不是@Tomasz R 想要的,它只是从pandas.columnnp.array 的类型转换。至于现在,我认为这是最接近的解决方案。
    • 谢谢大家。是的,array就够了,不能和array_interface放在一起。如果你希望返回的值是你的自定义类型,你还必须实现 array_wrap
    猜你喜欢
    • 1970-01-01
    • 2023-02-17
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2023-04-07
    相关资源
    最近更新 更多