首页 > 编程问答 >为什么 NumPy 标量与自定义序列相乘而不与列表相乘?

为什么 NumPy 标量与自定义序列相乘而不与列表相乘?

时间:2024-07-20 22:31:16浏览次数:7  
标签:python numpy

我有一个问题要问 NumPy 专家。考虑一个 NumPy 标量: c = np.arange(3.0).sum() 如果我尝试将它与自定义序列相乘,例如

class S:
    
    def __init__(self, lst):
        self.lst = lst
        
    def __len__(self):
        return len(self.lst)
    
    def __getitem__(self, s):
        return self.lst[s]

c = np.arange(3.0).sum()
s = S([1, 2, 3])

print(c * s)

,它会起作用并且我得到: array([3., 6., 9.])

但是,我不能用列表来做到这一点。例如,如果我从 list 继承 S 并尝试它,这不再起作用

class S(list):
    
    def __init__(self, lst):
        self.lst = lst
        
    def __len__(self):
        return len(self.lst)
    
    def __getitem__(self, s):
        return self.lst[s]

c = np.arange(3.0).sum()
s = S([1, 2, 3])

print(c * s)

并且我得到“无法将序列乘以‘numpy.float64’类型的非 int”。

那么 NumPy 是如何做到的区分这两种情况?

我问是因为我想防止我的“S”类出现这种行为而不从列表继承。


这是一个关于 NumPy 如何与其自身以外的对象交互的好问题。

答案在于 NumPy 在执行乘法等操作时如何处理 Python 对象。当使用 * 运算符时,NumPy 不会自动将的自定义类转换为 NumPy 数组。相反,它会依赖于 鸭子类型 运算符重载

在的第一个示例中, class S 定义了 __len__ __getitem__ 。这些方法允许 NumPy 像序列一样对待 S 的实例。NumPy 本质上会遍历 S ,将标量值 c 乘以从 __getitem__ 返回的每个元素。

但是,当从 list 继承 class S 时,会引入 NumPy 已经知道如何处理的行为。列表有自己的 * 运算符实现,用于 标量 ,它只执行列表的重复(这就是为什么收到错误的原因,因为它无法将浮点数乘以列表)。由于继承自 list ,NumPy 会默认使用列表的行为,从而导致冲突。

要防止这种行为而不从 list 继承,可以实现 __rmul__ 特殊方法。此方法控制当 NumPy 标量位于右侧时会发生什么。以下是修改后的代码:

import numpy as np

class S:
    def __init__(self, lst):
        self.lst = lst

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

    def __getitem__(self, s):
        return self.lst[s]

    def __rmul__(self, other):
        return NotImplemented

c = np.arange(3.0).sum()
s = S([1, 2, 3])

print(c * s)  # 这将引发 TypeError

通过从 __rmul__ 返回 NotImplemented ,表示的类不支持此特定操作,从而导致 TypeError ,类似于在尝试将列表与 NumPy 浮点数相乘时获得的错误。

此修改可确保的 S 类与 NumPy 标量的交互一致,无论它是否继承自 list

标签:python,numpy
From: 78773004

相关文章

  • 在 python 中写入 %appdata% 时出现奇怪的行为
    我试图将一些数据写入%appdata%。一切似乎都像Script1的输出中所示的那样工作。正在创建新目录并保存文件,并且也成功检索数据。但尝试查看文件资源管理器中的数据时,该文件夹不存在!CMD也找不到文件和目录。后来我手动创建了文件,检查了一下,发生了什么。CMD现在可以找到该文......
  • 使用 selenium 在 python 中打开 chrome 中的链接
    通过此链接https://bancadatistatisticaoas.inail.it/analytics/saw.dll?Dashboard&PortalPath=%2Fshared%2FBDS%2F_portal%2FINF_Definiti_Industria_e_Servizi我需要单击“FCostruzioni”,然后单击F41COSTRUZIONIED埃迪菲西。这是我的代码,但它不起作用。我做错了......
  • 七大排序算法的Python实现
    七大排序算法的Python实现1.冒泡排序(BubbleSort)算法思想冒泡排序通过重复交换相邻的未按顺序排列的元素来排序数组。每次迭代都将最大的元素“冒泡”到数组的末尾。复杂度分析时间复杂度:O(n^2)空间复杂度:O(1)defbubble_sort(arr):n=len(arr)for......
  • python反序列化
    之前hgame中遇到python反序列化,这次正好借分享会来尽可能详细学习一下python反序列化基础知识什么是序列化?反序列化?在很多时候为了方便对象传输,我们往往会把一些内容转化成更方便存储、传输的形式。我们把“对象->字符串”的翻译过程称为“序列化”;相应地,把“字符串->对......
  • 我在 python 项目中不断收到“无法识别图像文件中的数据”错误
    我正在尝试向我的TK窗口添加一个图标,但我不断收到一条错误消息:Traceback(mostrecentcalllast):File"C:\Users\roger\source\repos\PythonApplication\PythonApplication.py",line7,in<module>windowIcon=tk.PhotoImage(file="C:/Users/roger/Downloa......
  • Python学习笔记41:游戏篇之外星人入侵(二)
    前言在上一篇文章,我们已经创建好了项目目录,在今天,我们主要编写入口模块的功能。mainmain.py模块是我们游戏程序的入口,所有我们需要在模块中编写游戏主启动以及主页面相关的代码。当前我们的main模块是这样的,这是我们创建项目时默认生成一些代码,接下来我们就要进行我们......
  • Python学习笔记39:进阶篇(二十八)pygame的使用之按键映射及按键失效问题解决
    前言基础模块的知识通过这么长时间的学习已经有所了解,更加深入的话需要通过完成各种项目,在这个过程中逐渐学习,成长。我们的下一步目标是完成pythoncrashcourse中的外星人入侵项目,这是一个2D游戏项目。在这之前,我们先简单学习一下pygame模块。私信我发送消息python资料,......
  • Python学习笔记40:游戏篇之外星人入侵(一)
    前言入门知识已经学完,常用标准库也了解了,pygame入门知识也学了,那么开始尝试小游戏的开发。当然这个小游戏属于比较简单的小游戏,复杂的游戏需要长时间的编写累计开发经验,同时也需要一定的时间才能编写出来。现在的话还是嫩了点。从基础的简单的开始,学习实践,慢慢的成长才......
  • Python学习笔记37:进阶篇(二十六)pygame的使用之输入处理
    前言基础模块的知识通过这么长时间的学习已经有所了解,更加深入的话需要通过完成各种项目,在这个过程中逐渐学习,成长。我们的下一步目标是完成pythoncrashcourse中的外星人入侵项目,这是一个2D游戏项目。在这之前,我们先简单学习一下pygame模块。私信我发送消息python资料,......
  • Python学习笔记38:进阶篇(二十七)pygame的使用之时间与帧数控制
    前言基础模块的知识通过这么长时间的学习已经有所了解,更加深入的话需要通过完成各种项目,在这个过程中逐渐学习,成长。我们的下一步目标是完成pythoncrashcourse中的外星人入侵项目,这是一个2D游戏项目。在这之前,我们先简单学习一下pygame模块。私信我发送消息python资料,......