如何覆盖 NumPy 的 ndarray 和我的类型之间的比较?

2024-04-04

在 NumPy 中,可以使用 __array_priority__ 属性来控制作用于 ndarray 和用户定义类型的二元运算符。例如:

class Foo(object):
  def __radd__(self, lhs): return 0
  __array_priority__ = 100

a = np.random.random((100,100))
b = Foo()
a + b # calls b.__radd__(a) -> 0

然而,同样的事情似乎不适用于比较运算符。例如,如果我将以下行添加到Foo,那么它永远不会从表达式中调用a < b:

def __rlt__(self, lhs): return 0

我意识到__rlt__并不是真正的 Python 特殊名称,但我认为它可能有效。我尝试了所有__lt__, __le__, __eq__, __ne__, __ge__, __gt__有或没有前面的r, plus __cmp__,也是,但我永远无法让 NumPy 调用它们中的任何一个。

这些比较可以被推翻吗?

UPDATE

为了避免混淆,这里有一个更长的 NumPy 行为描述。对于初学者来说,《NumPy 指南》一书的内容如下:

If the ufunc has 2 inputs and 1 output and the second input is an Object array
then a special-case check is performed so that NotImplemented is returned if the
second input is not an ndarray, has the array priority attribute, and has an
r<op> special method.

我认为这就是+起作用的规则。这是一个例子:

import numpy as np
a = np.random.random((2,2))


class Bar0(object):
  def __add__(self, rhs): return 0
  def __radd__(self, rhs): return 1

b = Bar0()
print a + b # Calls __radd__ four times, returns an array
# [[1 1]
#  [1 1]]



class Bar1(object):
  def __add__(self, rhs): return 0
  def __radd__(self, rhs): return 1
  __array_priority__ = 100

b = Bar1()
print a + b # Calls __radd__ once, returns 1
# 1

正如你所看到的,没有__array_priority__,NumPy 将用户定义的对象解释为标量类型,并在数组中的每个位置应用该操作。那不是我想要的。我的类型是类似数组的(但不应从 ndarray 派生)。

下面是一个更长的示例,展示了定义所有比较方法时如何失败:

class Foo(object):
  def __cmp__(self, rhs): return 0
  def __lt__(self, rhs): return 1
  def __le__(self, rhs): return 2
  def __eq__(self, rhs): return 3
  def __ne__(self, rhs): return 4
  def __gt__(self, rhs): return 5
  def __ge__(self, rhs): return 6
  __array_priority__ = 100

b = Foo()
print a < b # Calls __cmp__ four times, returns an array
# [[False False]
#  [False False]]

看来我自己可以回答这个问题了。np.set_numeric_ops可以如下使用:

class Foo(object):
  def __lt__(self, rhs): return 0
  def __le__(self, rhs): return 1
  def __eq__(self, rhs): return 2
  def __ne__(self, rhs): return 3
  def __gt__(self, rhs): return 4
  def __ge__(self, rhs): return 5
  __array_priority__ = 100

def override(name):
  def ufunc(x,y):
    if isinstance(y,Foo): return NotImplemented
    return np.getattr(name)(x,y)
  return ufunc

np.set_numeric_ops(
    ** {
        ufunc : override(ufunc) for ufunc in (
            "less", "less_equal", "equal", "not_equal", "greater_equal"
          , "greater"
          )
    }
  )

a = np.random.random((2,2))
b = Foo()
print a < b
# 4
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何覆盖 NumPy 的 ndarray 和我的类型之间的比较? 的相关文章

  • 如何在 Debian 上的 virtualenv 中安装 numpy?

    注 参见这另一篇文章 https stackoverflow com questions 6442754 how to install h5py numpylibhdf5 as non root on a debian linux syst
  • 如何(重新)命名 pandas 数据框中的空列标题而不导出到 csv

    我有一个熊猫数据框df1带有一个索引列和一系列未命名的值 我想为未命名的系列指定一个名称 到目前为止 我知道的唯一方法是导出到df1 csv using df1 to csv df1 csv header Signal 然后使用以下命令重新
  • 在Python中,如何将矩阵逆时针旋转90度?

    gt gt gt def rotate matrix k List List int For example if I have m 1 2 3 2 3 3 5 4 3 rotate matrix m should give me 3 3
  • str.translate 与 str.replace - 何时使用哪一个?

    何时以及为什么使用前者而不是后者 反之亦然 目前尚不完全清楚为什么有些人使用前者以及为什么有些人使用后者 它们有不同的目的 translate只能用任意字符串替换单个字符 但一次调用可以执行多次替换 它的参数是一个特殊的表 它将单个字符映射
  • 键入的完整命令行

    我想获得输入时的完整命令行 This join sys argv 在这里不起作用 删除双引号 另外 我不想重新加入已解析和拆分的内容 有任何想法吗 你太迟了 当键入的命令到达 Python 时 您的 shell 已经发挥了它的魔力 例如 引
  • 来自 pandas 数据帧的烛台图,用日期替换索引

    此代码给出了带有移动平均线的烛台图 但 x 轴位于索引中 我需要 x 轴位于日期中 需要做什么改变 import numpy as np import pandas as pd import matplotlib pyplot as plt
  • 将 Python Pandas DataFrame 写入 Word 文档

    我正在努力创建一个使用 Pandas DataFrames 的 Python 生成的报告 目前我正在使用DataFrame to string 方法 但是 这会作为字符串写入文件 有没有办法让我实现这一目标 同时将其保留为表格 以便我可以使
  • 类型错误:“datetime.datetime”和“str”的实例之间不支持“>”

    我是 python 日期和时间类型的新手 我有一个日期值 date 2018 11 10 10 55 31 00 00 我需要检查该日期值是否超过 90 天 我试过 from datetime import datetime from da
  • 使用 NumPy 编写一个函数来计算具有特定公差的积分

    我想编写一个自定义函数来以特定容差对表达式 python 或 lambda 函数 进行数字积分 我知道与scipy integrate quad人们可以简单地改变epsabs但我想使用 numpy 自己编写该函数 From 这篇博文 htt
  • 带有 mkdocs 的本地 mathjax

    我想在无法访问互联网的计算机上使用 MathJax 和 Mkdocs 因此我不能只调用 Mathjax CDN Config mkdocs yml site name My Docs extra javascript javascripts
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • 查找与另一列 Pandas 中的唯一值关联的列中的值的交集

    如果我有一个像这样的数据框 非常小的例子 col1 col2 0 a 1 1 a 2 2 b 1 3 b 2 4 b 4 5 c 1 6 c 2 7 c 3 我想要所有的交集col2当价值观与其独特性相关时col1值 因此在这种情况下 交集
  • Py2exe - Pmw WindowsError:[错误 3]

    我正在尝试使用 Py2exe 构建独立的可执行文件 我已经导入了 Pmw 类 当我运行独立可执行文件时 出现以下错误 Traceback most recent call last File py line 9 in
  • 高级描述熊猫

    有没有像 pandas 那样更高级的功能 通常我会继续这样 r pd DataFrame np random randn 1000 columns A r describe 我会得到一份很好的总结 就像这样 A count 1000 000
  • 类型错误:此 COM 对象无法自动执行 makepy 过程 - 请为此对象手动运行 makepy

    这是什么错误 回溯错误 C Users DELL PycharmProjects MyNew venv Scripts python exe C Users DELL PycharmProjects MyNew agaaaaain py T
  • Python-验证我的文档 xls 中是否存在工作表

    我正在尝试在空闲时间设计一个小程序 加载 xls 文件 然后在要扫描的文档中选择一张纸 步骤1 用户导入 xls文件 导入程序后检查文件是否存在 我能做到的 第 2 步 我要求用户提供要分析的文档表 xls 的名称 这就是它停止的地方 该程
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • 如何创建用于霍夫曼编码和解码的树?

    对于我的作业 我将对霍夫曼树进行编码和解码 我在创建树时遇到问题 并且陷入困境 不要介意打印语句 它们只是让我测试并查看函数运行时的输出是什么 对于第一个 for 循环 我从主块中用于测试的文本文件中获取了所有值和索引 在第二个 for 循
  • Python 相当于 Scala 案例类

    Python 中是否有与 Scala 的 Case Class 等效的东西 就像自动生成分配给字段而无需编写样板的构造函数一样 当前执行此操作的现代方法 从 Python 3 7 开始 是使用数据类 https www python org
  • MoviePY 无法在 Windows 上检测 ImageMagick 二进制文件

    我刚买了一台新笔记本电脑 想要设置MoviePY在那新的Windows 64x Python3 7 0 机器 我对所有内容都进行了三次检查 但是当涉及到我的代码的文本部分时 它向我抛出了这个错误 OSError MoviePy Error

随机推荐