CQF预备知识:Python相关库 -- NumPy 基础知识 - 通用函数

news2025/6/2 10:02:22

文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。

通用函数

另请参阅 通用函数(ufunc)

通用函数(或简称 ufunc)是一种对 ndarrays 进行逐元素操作的函数,支持数组广播、类型转换以及一些其他标准特性。也就是说,ufunc 是一个“向量化”的包装器,用于包装一个接受固定数量特定输入并产生固定数量特定输出的函数。

在 NumPy 中,通用函数是 numpy.ufunc 类的实例。许多内置函数都是用编译后的 C 代码实现的。基本的 ufunc 操作标量,但也有一种泛化的 ufunc,其基本元素是子数组(向量、矩阵等),并且广播是在其他维度上进行的。最简单的例子是加法运算符:

>>> np.array([0,2,3,4]) + np.array([1,1,-1,2])
array([1, 3, 2, 6])

还可以使用 numpy.frompyfunc 工厂函数创建自定义的 numpy.ufunc 实例。

Ufunc 方法

所有 ufunc 都有四个方法。这些方法可以在 Methods 中找到。然而,这些方法仅适用于接受两个输入参数并返回一个输出参数的标量 ufunc。尝试在其他 ufunc 上调用这些方法将导致 ValueError

所有类似 reduce 的方法都接受一个 axis 关键字、一个 dtype 关键字和一个 out 关键字,且数组的维度必须大于等于 1。axis 关键字指定数组的哪个轴将执行归并操作(负值表示反向计数)。通常它是一个整数,但对于 numpy.ufunc.reduce,它也可以是一个 int 的元组,以同时在多个轴上进行归并,或者为 None,以在所有轴上进行归并。例如:

>>> x = np.arange(9).reshape(3,3)
>>> x
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> np.add.reduce(x, 1)
array([ 3, 12, 21])
>>> np.add.reduce(x, (0, 1))
36

dtype 关键字允许你管理在使用 ufunc.reduce 时经常出现的一个常见问题。有时你可能有一个特定数据类型的数组,并希望将所有元素相加,但结果却无法放入数组的数据类型中。这通常发生在你有一个单字节整数数组时。dtype 关键字允许你改变归并操作的数据类型(以及因此输出的数据类型)。因此,你可以确保输出是一个精度足够大的数据类型来处理你的输出。改变归并类型的责任主要由你承担。有一个例外:如果在“加”或“乘”操作的归并中没有给出 dtype,那么如果输入类型是整数(或布尔)数据类型且小于 numpy.int_ 数据类型的大小,它将被内部提升为 int_(或 numpy.uint)数据类型。在前面的例子中:

>>> x.dtype
dtype('int64')
>>> np.multiply.reduce(x, dtype=float)
array([ 0., 28., 80.])

最后,out 关键字允许你提供一个输出数组(或对于多输出 ufunc 的输出数组元组)。如果给出了 out,那么 dtype 参数仅用于内部计算。考虑前面例子中的 x

>>> y = np.zeros(3, dtype=int)
>>> y
array([0, 0, 0])
>>> np.multiply.reduce(x, dtype=float, out=y)
array([ 0, 28, 80])

Ufuncs 还有一个第五种方法,numpy.ufunc.at,它允许使用高级索引进行原地操作。在使用高级索引的维度上不会使用缓冲区,因此高级索引可以多次列出同一个项,并且该操作将在该项的前一个操作的结果上执行。

输出类型确定

Ufunc(及其方法)的输出不一定是 ndarray,如果所有输入参数都不是 ndarrays。实际上,如果任何输入定义了 __array_ufunc__ 方法,则将完全将控制权移交给该函数,即 ufunc 被覆盖。

如果没有任何输入覆盖了 ufunc,则所有输出数组将传递给输入的 __array_wrap__ 方法(除了 ndarrays 和标量之外)定义它 并且 具有比其他输入到通用函数更高的 __array_priority__ndarray 的默认 __array_priority__ 是 0.0,子类型的默认 __array_priority__ 也是 0.0。矩阵的 __array_priority__ 等于 10.0。

所有 ufunc 也可以接受输出参数,这些参数必须是数组或子类。如果需要,结果将被强制转换为提供的输出数组(或子类)的数据类型。
如果输出具有 __array_wrap__ 方法,则将调用它,而不是在输入中找到的那个。

广播(Broadcasting)

另请参阅 广播基础知识

每个通用函数(ufunc)都接受数组输入,并通过对输入进行逐元素操作来产生数组输出(这里的元素通常是一个标量,但对于泛化的 ufunc,它可以是一个向量或更高阶的子数组)。标准的广播规则会被应用,以便即使输入的形状不完全相同,仍然可以有效地进行操作。

根据这些规则,如果输入数组在某个维度上的大小为 1,那么该维度的第一个数据元素将被用于该维度上的所有计算。换句话说,ufunc 的步进机制将不会沿着该维度进行步进(该维度的步长将为 0)。

类型转换规则

每个 ufunc 的核心是一个一维的步进循环,该循环为特定的类型组合实现了实际的函数。当创建 ufunc 时,会为其提供一个静态的内部循环列表和一个对应的类型签名列表,ufunc 机制使用这个列表来确定特定情况下使用哪个内部循环。你可以通过检查特定 ufunc 的 .types 属性来查看哪些类型组合有定义的内部循环以及它们产生哪种输出类型(出于简洁性,使用字符代码表示输出类型)。

当 ufunc 没有为提供的输入类型提供核心循环实现时,必须对一个或多个输入进行类型转换。如果找不到输入类型的实现,则算法会搜索一个所有输入都可以“安全地”转换到的类型签名的实现。它会在其内部循环列表中找到的第一个这样的实现被选中并执行,在执行所有必要的类型转换之后。请注意,ufunc 中的内部拷贝(即使是类型转换时)也受到内部缓冲区大小(用户可设置)的限制。

注意

NumPy 中的通用函数足够灵活,可以拥有混合类型签名。因此,例如,可以定义一个通用函数,它既适用于浮点数又适用于整数值。请参见 numpy.ldexp 以获取示例。

根据上述描述,类型转换规则本质上是由何时可以将一种数据类型“安全地”转换为另一种数据类型来决定的。可以通过函数调用 can_cast(fromtype, totype) 在 Python 中确定此问题的答案。下面的示例显示了作者的 64 位系统上 24 种内部支持类型的调用结果。你可以使用示例中给出的代码为你自己的系统生成此表。

示例

显示 64 位系统的“可以安全转换”表的代码片段。通常,输出取决于系统;你的系统可能会得出不同的表格。

>>> mark = {False: ' -', True: ' Y'}
>>> def print_table(ntypes):
...     print('X ' + ' '.join(ntypes))
...     for row in ntypes:
...         print(row, end='')
...         for col in ntypes:
...             print(mark[np.can_cast(row, col)], end='')
...         print()
...
>>> print_table(np.typecodes['All'])
X ? b h i l q n p B H I L Q N P e f d g F D G S U V O M m
? Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y - Y
b - Y Y Y Y Y Y Y - - - - - - - Y Y Y Y Y Y Y Y Y Y Y - Y
h - - Y Y Y Y Y Y - - - - - - - - Y Y Y Y Y Y Y Y Y Y - Y
i - - - Y Y Y Y Y - - - - - - - - - Y Y - Y Y Y Y Y Y - Y
l - - - - Y Y Y Y - - - - - - - - - Y Y - Y Y Y Y Y Y - Y
q - - - - Y Y Y Y - - - - - - - - - Y Y - Y Y Y Y Y Y - Y
n - - - - Y Y Y Y - - - - - - - - - Y Y - Y Y Y Y Y Y - Y
p - - - - Y Y Y Y - - - - - - - - - Y Y - Y Y Y Y Y Y - Y
B - - Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y - Y
H - - - Y Y Y Y Y - Y Y Y Y Y Y - Y Y Y Y Y Y Y Y Y Y - Y
I - - - - Y Y Y Y - - Y Y Y Y Y - - Y Y - Y Y Y Y Y Y - Y
L - - - - - - - - - - - Y Y Y Y - - Y Y - Y Y Y Y Y Y - -
Q - - - - - - - - - - - Y Y Y Y - - Y Y - Y Y Y Y Y Y - -
N - - - - - - - - - - - Y Y Y Y - - Y Y - Y Y Y Y Y Y - -
P - - - - - - - - - - - Y Y Y Y - - Y Y - Y Y Y Y Y Y - -
e - - - - - - - - - - - - - - - Y Y Y Y Y Y Y Y Y Y Y - -
f - - - - - - - - - - - - - - - - Y Y Y Y Y Y Y Y Y Y - -
d - - - - - - - - - - - - - - - - - Y Y - Y Y Y Y Y Y - -
g - - - - - - - - - - - - - - - - - - Y - - Y Y Y Y Y - -
F - - - - - - - - - - - - - - - - - - - Y Y Y Y Y Y Y - -
D - - - - - - - - - - - - - - - - - - - - Y Y Y Y Y Y - -
G - - - - - - - - - - - - - - - - - - - - - Y Y Y Y Y - -
S - - - - - - - - - - - - - - - - - - - - - - Y Y Y Y - -
U - - - - - - - - - - - - - - - - - - - - - - - Y Y Y - -
V - - - - - - - - - - - - - - - - - - - - - - - - Y Y - -
O - - - - - - - - - - - - - - - - - - - - - - - - Y - -
M - - - - - - - - - - - - - - - - - - - - - - - Y Y Y -
m - - - - - - - - - - - - - - - - - - - - - - - Y Y - Y

你应该注意,尽管为了完整性而包含在表中,‘S’、‘U’ 和 ‘V’ 类型不能被 ufunc 操作。同样要注意,在 32 位系统上,整数类型可能具有不同的大小,这将导致表格略有变化。

对于混合标量 - 数组操作,使用了一套不同的类型转换规则,以确保标量不能“提升”数组,除非标量是与数组根本不同种类的数据(即,在数据类型层次结构中处于不同的层次)。此规则使你可以在代码中使用标量常量(作为 Python 类型,在 ufunc 中相应地进行解释),而不必担心标量常量的精度是否会提升你的大(小精度)数组。

内部缓冲区的使用

在内部,缓冲区用于处理未对齐的数据、字节序交换的数据以及需要从一种数据类型转换为另一种数据类型的场景。内部缓冲区的大小可以根据线程进行设置。最多可以创建 2 ( n i n p u t s + n o u t p u t s ) 2 (n_{\mathrm{inputs}} + n_{\mathrm{outputs}}) 2(ninputs+noutputs) 个指定大小的缓冲区,用于处理 ufunc 的所有输入和输出数据。默认的缓冲区大小是 10,000 个元素。每当基于缓冲区的计算需要进行时,但如果所有输入数组的大小都小于缓冲区大小,那么这些行为不端或类型不正确的数组将在计算开始前被复制。因此,调整缓冲区的大小可能会改变各种 ufunc 计算完成的速度。一个简单的接口可以通过函数 numpy.setbufsize 来设置这个变量。

错误处理

通用函数可能会触发硬件中的特殊浮点状态寄存器(例如除以零)。如果在你的平台上可用,这些寄存器将在计算过程中定期检查。错误处理是按线程进行控制的,可以使用函数 numpy.seterrnumpy.seterrcall 进行配置。

覆盖 ufunc 行为

类(包括 ndarray 子类)可以通过定义某些特殊方法来覆盖 ufunc 对它们的操作方式。具体细节,请参见 标准数组子类。

风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2393515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于ELK的分布式日志实时分析与可视化系统设计

目录 一、ELK平台介绍 1.ELK概述 2.Elasticsearch 3.Logstash 4.Kibana 二、部署ES群集 1.资源清单 2.基本配置 3.安装Elasticsearch(elk1上、elk2上、elk3上) 4.安装logstash(elk1上) 5.Filebeat 6.安装Kibana&#x…

酒店管理系统设计与实现

本科毕业设计(论文) 设计(论文)题目 酒店管理系统设计与实现 学生姓名 学生学号 所在学院 专业班级 校内指导教师 李建 企业指导教师 毕业设计(论文)真实性承诺及声明 学生对毕业设计(论文)真实性承诺 本人郑重声明:所提交的毕业设计(论文)作品是本人在指导教师的指…

OpenCV---pointPolygonTest

一、基本概念与用途 pointPolygonTest 是 OpenCV 中用于判断点与多边形关系的重要函数,常用于: 目标检测:判断像素点是否属于检测到的轮廓区域碰撞检测:检测物体是否重叠图像分割:确定点是否在分割区域内几何分析&am…

Qt 的简单示例 -- 地址簿

这个工程里有两个窗口,都是QWidget派生的窗口 主窗口: 1. 运用了布局,按钮控件,单行编辑框,富文本编辑框等窗口部件; 2. 运用了 QMap 类; 3. 实现了点击按钮弹出子窗口的功能,这里子…

什么是DevOps的核心目标?它如何解决传统开发与运维之间的冲突?​

在当今数字化转型加速的时代,DevOps 已成为软件开发领域备受瞩目的明星理念。今天,本文将聚焦于 DevOps 的核心目标,并深入探讨它如何巧妙化解传统开发与运维之间的冲突,为大家揭开 DevOps 的神秘面纱并分享实用经验。本次介绍的与…

Android studio 查看aar源码出现/* compiled code */

如图查看aar源码时看不到具体实现,在排除是sdk版本导致的问题后,下面说解决方法 打开设置,找到插件 输入decompiler 搜索 这个是自带的反编译工具,启用就好了

用HTML5+JavaScript实现汉字转拼音工具

用HTML5JavaScript实现汉字转拼音工具 前一篇博文(https://blog.csdn.net/cnds123/article/details/148067680)提到,当需要将拼音添加到汉字上面时,用python实现比HTML5JavaScript实现繁琐。在这篇博文中用HTML5JavaScript实现汉…

基于Java,SpringBoot,Vue,UniAPP医院预约挂号买药就诊病例微信小程序系统设计

摘要 随着医疗信息化的不断推进以及“互联网医疗”模式的广泛普及,传统医院挂号流程中存在的排队时间长、资源分配不均等问题日益凸显,急需通过数字化手段加以解决。本研究设计并实现了一套基于Java、SpringBoot、Vue与UniAPP技术栈的医院预约挂号微信小…

ONNX模型的动态和静态量化

引言  通常我们将模型转换为onnx格式之后,模型的体积可能比较大,这样在某些场景下就无法适用。最近想在移动端部署语音识别、合成模型,但是目前的效果较好的模型动辄几个G,于是便想着将模型压缩一下。本文探索了两种压缩方法&…

如何用Python抓取Google Scholar

文章目录 [TOC](文章目录) 前言一、为什么要抓取Google Scholar?二、Google Scholar 抓取需要什么三、为什么代理对于稳定的抓取是必要的四、一步一步谷歌学者抓取教程4.1. 分页和循环4.2. 运行脚本 五、完整的Google Scholar抓取代码六、抓取Google Scholar的高级提…

Wireshark对usb设备进行抓包找不到USBPcap接口的解决方案

引言 近日工作需要针对usb设备进行抓包,但按照wireshark安装程序流程一步步走,即使勾选了安装USBPcap安装完成后开启wireshark依然不显示USBPcap接口,随设法进行解决。 最终能够正常显示USBPcap接口并能够正常使用进行抓包 解决方案&#x…

Socket 编程 UDP

目录 1. UDP网络编程 1.1 echo server 1.1.1 接口 1.1.1.1 创建套接字 1.1.1.2 绑定 1.1.1.3 bzero 1.1.1.4 htons(主机序列转网络序列) 1.1.1.5 inet_addr(主机序列IP转网络序列IP) 1.1.1.6 recvfrom(让服务…

Jenkins实践(8):服务器A通过SSH调用服务器B执行Python自动化脚本

Jenkins实践(8):服务器A通过SSH调用服务器B执行Python自动化脚本 1、需求: 1、Jenkins服务器在74上,Python脚本在196服务器上 2、需要在服务器74的Jenkins上调用196上的脚本执行Python自动化测试 2、操作步骤 第一步:Linux Centos7配置SSH免密登录 Linux Centos7配置S…

lua的注意事项2

总之,下面的返回值不是10,a,b 而且

前端八股之HTML

前端秘籍-HTML篇 1. src和href的区别 src 用于替换当前元素,href 用于在当前文档和引用资源之间确立联系。 (1)src src 是 source 的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置&#xff1…

鲲鹏Arm+麒麟V10,国产化信创 K8s 离线部署保姆级教程

Rainbond V6 国产化部署教程,针对鲲鹏 CPU 麒麟 V10 的离线环境,手把手教你从环境准备到应用上线,所有依赖包提前打包好,步骤写成傻瓜式操作指南。别说技术团队了,照着文档一步步来,让你领导来都能独立完成…

【C++ Qt】认识Qt、Qt 项目搭建流程(图文并茂、通俗易懂)

每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论​: 本章将开启Qt的学习,Qt是一个较为古老但仍然在GUI图形化界面设计中有着举足轻重的地位,因为它适合嵌入式和多种平台而被广泛使用…

IoT/HCIP实验-1/物联网开发平台实验Part2(HCIP-IoT实验手册版)

文章目录 概述产品和设备实例的产品和设备产品和设备的关联单个产品有多个设备为产品创建多个设备产品模型和物模型设备影子(远程代理) 新建产品模型定义编解码插件开发编解码插件工作原理消息类型与二进制码流添加消息(数据上报消息&#xf…

Replacing iptables with eBPF in Kubernetes with Cilium

source: https://archive.fosdem.org/2020/schedule/event/replacing_iptables_with_ebpf/attachments/slides/3622/export/events/attachments/replacing_iptables_with_ebpf/slides/3622/Cilium_FOSDEM_2020.pdf 使用Cilium,结合eBPF、Envoy、Istio和Hubble等技术…

数学建模之最短路径问题

1 问题的提出 这个是我们的所要写的题目,我们要用LINGO编程进行编写这个题目,那么就是需要进行思考这个怎么进行构建这个问题的模型 首先起点,中间点,终点我们要对这个进行设计 2 三个点的设计 起点的设计 起点就是我们进去&am…