NumPy 秘籍中文第二版:六、特殊数组和通用函数

news2024/10/7 18:22:59

原文:NumPy Cookbook - Second Edition

协议:CC BY-NC-SA 4.0

译者:飞龙

在本章中,我们将介绍以下秘籍:

  • 创建通用函数
  • 查找勾股三元组
  • chararray执行字符串操作
  • 创建一个遮罩数组
  • 忽略负值和极值
  • 使用recarray函数创建一个得分表

简介

本章是关于特殊数组和通用函数的。 这些是您每天可能不会遇到的主题,但是它们仍然很重要,因此在此需要提及。**通用函数(Ufuncs)**逐个元素或标量地作用于数组。 Ufuncs 接受一组标量作为输入,并产生一组标量作为输出。 通用函数通常可以映射到它们的数学对等物上,例如加法,减法,除法,乘法等。 这里提到的特殊数组是基本 NumPy 数组对象的所有子类,并提供其他功能。

创建通用函数

我们可以使用frompyfunc() NumPy 函数从 Python 函数创建通用函数。

操作步骤

以下步骤可帮助我们创建通用函数:

  1. 定义一个简单的 Python 函数以使输入加倍:

    def double(a):
        return 2 * a
    
  2. frompyfunc()创建通用函数。 指定输入参数的数目和返回的对象数目(均等于1):

    from __future__ import print_function
    import numpy as np
    
    def double(a):
       return 2 * a
    
    ufunc = np.frompyfunc(double, 1, 1)
    print("Result", ufunc(np.arange(4)))
    

    该代码在执行时输出以下输出:

    Result [0 2 4 6]
    
    

工作原理

我们定义了一个 Python 函数,该函数会将接收到的数字加倍。 实际上,我们也可以将字符串作为输入,因为这在 Python 中是合法的。 我们使用frompyfunc() NumPy 函数从此 Python 函数创建了一个通用函数。 通用函数是 NumPy 类,具有特殊功能,例如广播和适用于 NumPy 数组的逐元素处理。 实际上,许多 NumPy 函数都是通用函数,但是都是用 C 编写的。

另见

  • frompyfunc() NumPy 函数的文档

查找勾股三元组

对于本教程,您可能需要阅读有关勾股三元组的维基百科页面。 勾股三元组是一组三个自然数,即a < b < c,为此,Finding Pythagorean triples

这是勾股三元组的示例:Finding Pythagorean triples

勾股三元组与勾股定理密切相关,您可能在中学几何学过的。

勾股三元组代表直角三角形的三个边,因此遵循勾股定理。 让我们找到一个分量总数为 1,000 的勾股三元组。 我们将使用欧几里得公式进行此操作:

Finding Pythagorean triples

在此示例中,我们将看到通用函数的运行。

操作步骤

欧几里得公式定义了mn索引。

  1. 创建包含以下索引的数组:

    m = np.arange(33)
    n = np.arange(33)
    
  2. 第二步是使用欧几里得公式计算勾股三元组的数量abc。 使用outer()函数获得笛卡尔积,差和和:

    a = np.subtract.outer(m ** 2, n ** 2)
    b = 2 * np.multiply.outer(m, n)
    c = np.add.outer(m ** 2, n ** 2)
    
  3. 现在,我们有许多包含abc值的数组。 但是,我们仍然需要找到符合问题条件的值。 使用where() NumPy 函数查找这些值的索引:

    idx =  np.where((a + b + c) == 1000)
    
  4. 使用numpy.testing模块检查解决方案:

    np.testing.assert_equal(a[idx]**2 + b[idx]**2, c[idx]**2)
    

以下代码来自本书代码包中的triplets.py文件:

from __future__ import print_function
import numpy as np

#A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
#a ** 2 + b ** 2 = c ** 2
#
#For example, 3 ** 2 + 4 ** 2 = 9 + 16 = 25 = 5 ** 2.
#
#There exists exactly one Pythagorean triplet for which a + b + c = 1000.
#Find the product abc.

#1\. Create m and n arrays
m = np.arange(33)
n = np.arange(33)

#2\. Calculate a, b and c
a = np.subtract.outer(m ** 2, n ** 2)
b = 2 * np.multiply.outer(m, n)
c = np.add.outer(m ** 2, n ** 2)

#3\. Find the index
idx =  np.where((a + b + c) == 1000)

#4\. Check solution
np.testing.assert_equal(a[idx]**2 + b[idx]**2, c[idx]**2)
print(a[idx], b[idx], c[idx])
      # [375] [200] [425]

工作原理

通用函数不是实函数,而是表示函数的对象。 工具具有outer()方法,我们已经在实践中看到它。 NumPy 的许多标准通用函数都是用 C 实现的 ,因此比常规的 Python 代码要快。 Ufuncs 支持逐元素处理和类型转换,这意味着更少的循环。

另见

  • outer()通用函数的文档

使用chararray执行字符串操作

NumPy 具有保存字符串的专用chararray对象。 它是ndarray的子类,并具有特殊的字符串方法。 我们将从 Python 网站下载文本并使用这些方法。 chararray相对于普通字符串数组的优点如下:

  • 索引时会自动修剪数组元素的空白
  • 字符串末尾的空格也被比较运算符修剪
  • 向量化字符串操作可用,因此不需要循环

操作步骤

让我们创建字符数组:

  1. 创建字符数组作为视图:

    carray = np.array(html).view(np.chararray)
    
  2. 使用expandtabs()函数将制表符扩展到空格。 此函数接受制表符大小作为参数。 如果未指定,则值为8

    carray = carray.expandtabs(1)
    
  3. 使用splitlines()函数将行分割成几行:

    carray = carray.splitlines()
    

    以下是此示例的完整代码:

    import urllib2
    import numpy as np
    import re
    
    response = urllib2.urlopen('http://python.org/')
    html = response.read()
    html = re.sub(r'<.*?>', '', html)
    carray = np.array(html).view(np.chararray)
    carray = carray.expandtabs(1)
    carray = carray.splitlines()
    print(carray)
    

工作原理

我们看到了专门的chararray类在起作用。 它提供了一些向量化的字符串操作以及有关空格的便捷行为。

另见

  • chararray类的文档

创建遮罩数组

遮罩数组可用于忽略丢失或无效的数据项。 numpy.ma模块中的MaskedArray类是ndarray的子类,带有遮罩。 我们将使用 Lena 图像作为数据源,并假装其中一些数据已损坏。 最后,我们将绘制原始图像,原始图像的对数值,遮罩数组及其对数值。

操作步骤

让我们创建被屏蔽的数组:

  1. 要创建一个遮罩数组,我们需要指定一个遮罩。 创建一个随机遮罩,其值为01

    random_mask = np.random.randint(0, 2, size=lena.shape)
    
  2. 使用上一步中的遮罩,创建一个遮罩数组:

    masked_array = np.ma.array(lena, mask=random_mask)
    

    以下是此遮罩数组教程的完整代码:

    from __future__ import print_function
    import numpy as np
    from scipy.misc import lena
    import matplotlib.pyplot as plt
    
    lena = lena()
    random_mask = np.random.randint(0, 2, size=lena.shape)
    
    plt.subplot(221)
    plt.title("Original")
    plt.imshow(lena)
    plt.axis('off')
    
    masked_array = np.ma.array(lena, mask=random_mask)
    print(masked_array)
    plt.subplot(222)
    plt.title("Masked")
    plt.imshow(masked_array)
    plt.axis('off')
    plt.subplot(223)
    plt.title("Log")
    plt.imshow(np.log(lena))
    plt.axis('off')
    
    plt.subplot(224)
    plt.title("Log Masked")
    plt.imshow(np.log(masked_array))
    plt.axis('off')
    
    plt.show()
    

    这是显示结果图像的屏幕截图:

    How to do it...

工作原理

我们对 NumPy 数组应用了随机的遮罩。 这具有忽略对应于遮罩的数据的效果。 您可以在numpy.ma 模块中找到一系列遮罩数组操作 。 在本教程中,我们仅演示了如何创建遮罩数组。

另见

  • numpy.ma模块的文档

忽略负值和极值

当我们想忽略负值时,例如当取数组值的对数时,屏蔽的数组很有用。 遮罩数组的另一个用例是排除极值。 这基于极限值的上限和下限。

我们将把这些技术应用于股票价格数据。 我们将跳过前面几章已经介绍的下载数据的步骤。

操作步骤

我们将使用包含负数的数组的对数:

  1. 创建一个数组,该数组包含可被三除的数字:

    triples = np.arange(0, len(close), 3)
    print("Triples", triples[:10], "...")
    

    接下来,使用与价格数据数组大小相同的数组创建一个数组:

    signs = np.ones(len(close))
    print("Signs", signs[:10], "...")
    

    借助您在第 2 章,“高级索引和数组概念”中学习的索引技巧,将每个第三个数字设置为负数。

    signs[triples] = -1
    print("Signs", signs[:10], "...")
    

    最后,取该数组的对数:

    ma_log = np.ma.log(close * signs)
    print("Masked logs", ma_log[:10], "...")
    

    这应该为AAPL打印以下输出:

    Triples [ 0  3  6  9 12 15 18 21 24 27] ...
    Signs [ 1\.  1\.  1\.  1\.  1\.  1\.  1\.  1\.  1\.  1.] ...
    Signs [-1\.  1\.  1\. -1\.  1\.  1\. -1\.  1\.  1\. -1.] ...
    Masked logs [-- 5.93655586575 5.95094223368 -- 5.97468290742 5.97510711452 --
     6.01674381162 5.97889061623 --] ...
    
    
  2. 让我们将极值定义为低于平均值的一个标准差,或高于平均值的一个标准差(这仅用于演示目的)。 编写以下代码以屏蔽极值:

    dev = close.std()
    avg = close.mean()
    inside = numpy.ma.masked_outside(close, avg - dev, avg + dev)
    print("Inside", inside[:10], "...")
    

    此代码显示前十个元素:

    Inside [-- -- -- -- -- -- 409.429675172 410.240597855 -- --] ...
    
    

    绘制原始价格数据,绘制对数后的数据,再次绘制指数,最后绘制基于标准差的遮罩后的数据。 以下屏幕截图显示了结果(此运行):

    How to do it...

    本教程的完整程序如下:

    from __future__ import print_function
    import numpy as np
    from matplotlib.finance import quotes_historical_yahoo
    from datetime import date
    import matplotlib.pyplot as plt
    def get_close(ticker):
       today = date.today()
       start = (today.year - 1, today.month, today.day)
    
       quotes = quotes_historical_yahoo(ticker, start, today)
    
       return np.array([q[4] for q in quotes])
    
    close = get_close('AAPL')
    
    triples = np.arange(0, len(close), 3)
    print("Triples", triples[:10], "...")
    
    signs = np.ones(len(close))
    print("Signs", signs[:10], "...")
    
    signs[triples] = -1
    print("Signs", signs[:10], "...")
    
    ma_log = np.ma.log(close * signs)
    print("Masked logs", ma_log[:10], "...")
    
    dev = close.std()
    avg = close.mean()
    inside = np.ma.masked_outside(close, avg - dev, avg + dev)
    print("Inside", inside[:10], "...")
    
    plt.subplot(311)
    plt.title("Original")
    plt.plot(close)
    
    plt.subplot(312)
    plt.title("Log Masked")
    plt.plot(np.exp(ma_log))
    
    plt.subplot(313)
    plt.title("Not Extreme")
    plt.plot(inside)
    
    plt.tight_layout()
    plt.show()
    

工作原理

numpy.ma模块中的函数掩盖了数组元素,我们认为这些元素是非法的。 例如,log()sqrt()函数不允许使用负值。 屏蔽值类似于数据库和编程中的NULLNone值。 具有屏蔽值的所有操作都将导致屏蔽值。

另见

  • numpy.ma模块的文档

使用recarray函数创建得分表

recarray类是ndarray的子类。 这些数组可以像数据库中一样保存记录,具有不同的数据类型。 例如,我们可以存储有关员工的记录,其中包含诸如薪水之类的数字数据和诸如员工姓名之类的字符串。

现代经济理论告诉我们,投资归结为优化风险和回报。 风险是由对数回报的标准差表示的。 另一方面,奖励由对数回报的平均值表示。 我们可以拿出相对分数,高分意味着低风险和高回报。 这只是理论上的,未经测试,所以不要太在意。 我们将计算几只股票的得分,并将它们与股票代号一起使用 NumPy recarray()函数中的表格格式存储。

操作步骤

让我们从创建记录数组开始:

  1. 为每个记录创建一个包含符号,标准差得分,平均得分和总得分的记录数组:

    weights = np.recarray((len(tickers),), dtype=[('symbol', np.str_, 16), 
        ('stdscore', float), ('mean', float), ('score', float)])
    
  2. 为了简单起见,请根据对数收益在循环中初始化得分:

    for i, ticker in enumerate(tickers):
       close = get_close(ticker)
       logrets = np.diff(np.log(close))
       weights[i]['symbol'] = ticker
       weights[i]['mean'] = logrets.mean()
       weights[i]['stdscore'] = 1/logrets.std()
       weights[i]['score'] = 0
    

    如您所见,我们可以使用在上一步中定义的字段名称来访问元素。

  3. 现在,我们有一些数字,但是它们很难相互比较。 归一化分数,以便我们以后可以将它们合并。 在这里,归一化意味着确保分数加起来为:

    for key in ['mean', 'stdscore']:
        wsum = weights[key].sum()
        weights[key] = weights[key]/wsum
    
  4. 总体分数将只是中间分数的平均值。 对总分上的记录进行排序以产生排名:

    weights['score'] = (weights['stdscore'] + weights['mean'])/2
    weights['score'].sort()
    

    The following is the complete code for this example:

    from __future__ import print_function
    import numpy as np
    from matplotlib.finance import quotes_historical_yahoo
    from datetime import date
    
    tickers = ['MRK', 'T', 'VZ']
    
    def get_close(ticker):
       today = date.today()
       start = (today.year - 1, today.month, today.day)
    
       quotes = quotes_historical_yahoo(ticker, start, today)
    
       return np.array([q[4] for q in quotes])
    
    weights = np.recarray((len(tickers),), dtype=[('symbol', np.str_, 16), 
       ('stdscore', float), ('mean', float), ('score', float)])
    
    for i, ticker in enumerate(tickers):
       close = get_close(ticker)
       logrets = np.diff(np.log(close))
       weights[i]['symbol'] = ticker
       weights[i]['mean'] = logrets.mean()
       weights[i]['stdscore'] = 1/logrets.std()
       weights[i]['score'] = 0
    
    for key in ['mean', 'stdscore']:
       wsum = weights[key].sum()
       weights[key] = weights[key]/wsum
    
    weights['score'] = (weights['stdscore'] + weights['mean'])/2
    weights['score'].sort()
    
    for record in weights:
       print("%s,mean=%.4f,stdscore=%.4f,score=%.4f" % (record['symbol'], record['mean'], record['stdscore'], record['score']))
    

    该程序产生以下输出:

    MRK,mean=0.8185,stdscore=0.2938,score=0.2177
    T,mean=0.0927,stdscore=0.3427,score=0.2262
    VZ,mean=0.0888,stdscore=0.3636,score=0.5561
    
    

分数已归一化,因此值介于01之间,我们尝试从秘籍开始使用定义获得最佳收益和风险组合 。 根据输出,VZ得分最高,因此是最好的投资。 当然,这只是一个 NumPy 演示,数据很少,所以不要认为这是推荐。

工作原理

我们计算了几只股票的得分,并将它们存储在recarray NumPy 对象中。 这个数组使我们能够混合不同数据类型的数据,在这种情况下,是股票代码和数字得分。 记录数组使我们可以将字段作为数组成员访问,例如arr.field。 本教程介绍了记录数组的创建。 您可以在numpy.recarray模块中找到更多与记录数组相关的功能。

另见

  • numpy.recarray模块的文档

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

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

相关文章

蓝桥杯之单片机学习(终)——关于之前文章的错误及更正(附:第十四届蓝桥杯单片机赛题)

文章目录零、吐槽一、关于自创模板&#xff0c;和自写模板库的问题二、关于 详解A/D、D/A、PCF8591 这篇文章一些小错误三、模板最终版本main.cds1302,hds1302.conewire.honewire.ciic.hiic.c附、第十四届蓝桥杯单片机赛题零、吐槽 今年是矩阵键盘三个协议一起调用啊。真是一年…

“AI+机器人”持续为多领域增“智”添“质”,开启效益增长飞轮

近期&#xff0c;工信部等17部门联合推出《“机器人”应用行动实施方案》&#xff0c;全面加快机器人领域应用拓展。据方案提出&#xff0c;至2025年&#xff0c;制造业机器人密度较2020年将实现翻番&#xff0c;服务机器人及特种机器人行业应用深度与广度显著提升。机器人融合…

服务器被DDoS攻击,怎么破?

文章目录前言网站受到DDoS的症状判断是否被攻击查看网络带宽占用查看网络连接TCP连接攻击SYN洪水攻击防御措施TCP/IP内核参数优化iptables 防火墙预防防止同步包洪水&#xff08;Sync Flood&#xff09;Ping洪水攻击&#xff08;Ping of Death&#xff09;控制单个IP的最大并发…

基于SpringBoot的私人健身和教练的预约管理系统源码数据库论文

目 录 第一章 概述 1.1研究背景 1.2开发意义 1.3研究现状 1.4研究内容 1.5论文结构 第二章 开发技术介绍 2.1系统开发平台 2.2平台开发相关技术 2.2.1 Javar技术 2.2.2 Mysql数据库介绍 2.2.3 Mysql环境配置 2.2.4 B/S架构 2.2.5 Springboot框架 …

主动配电网故障恢复的重构与孤岛划分统一模型研究【升级版本】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

V8引擎执行原理

v8是C编写的Google开源高性能JavaScript和WebAssembly引擎&#xff0c;它用于Chrome和Node.js等。 它实现ECMAScript和WebAssembly。 v8可独立运行&#xff0c;也可嵌入到任何C应用程序中。 parse模块 parse模块会将JavaScript代码转换成AST(抽象语法树)&#xff0c;因为解…

[LeetCode周赛复盘] 第 340 场周赛20230409

[LeetCode周赛复盘] 第 340 场周赛20230409 一、本周周赛总结二、 6361. 对角线上的质数1. 题目描述2. 思路分析3. 代码实现三、6360. 等值距离和1. 题目描述2. 思路分析3. 代码实现四、6359. 最小化数对的最大差值1. 题目描述2. 思路分析3. 代码实现五、 6353. 网格图中最少访…

【排序】排序这样写才对Ⅰ --插入排序与选择排序

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

Axios请求(对于ajax的二次封装)——Axios请求的响应结构、默认配置

Axios请求&#xff08;对于ajax的二次封装&#xff09;——Axios请求的响应结构、默认配置知识回调&#xff08;不懂就看这儿&#xff01;&#xff09;场景复现核心干货axios请求的响应结构响应格式详解实际请求中的响应格式axios请求的默认配置全局axios默认值&#xff08;了解…

Debug | wget 的安装与使用(Windows)

!wget -nc http://labfile.oss.aliyuncs.com/courses/780/WeatherData.zip 报错信息&#xff1a; wget 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 分析&#xff1a; 在jupyter notebook中做机器学习时导入数据使用!wget遇到了这个问题&#xff0c;查到…

轻松上手git代码版本管理工具--协同开发-冲突解决、线上分支合并以及使用pycharm操作git

一、协同开发 多人合作开发一个项目---->多人公用一个远程仓库 以后台项目为例: git init # git管理设置忽略文件.gitignore git add .git commit -m 第一次提交,写完了首页功能远程新建一个远程仓库(空) 创建一个origin git remote add origin git@gitee.com:xx…

穿戴规范智能识别系统 yolov7

穿戴规范智能识别系统通过yolov7python网络模型AI深度视觉学习算法&#xff0c;穿戴规范智能识别系统对工厂画面中人员穿戴行为自动识别分析&#xff0c;发现现场人员未按照规定穿戴着装&#xff0c;立即抓拍告警。YOLOv7 的发展方向与当前主流的实时目标检测器不同&#xff0c…

垃圾满溢检测系统 yolov5

垃圾满溢检测系统通过pythonyolov5网络模型技术&#xff0c;垃圾满溢检测系统对控画面中小区内的垃圾桶进行7*24小时不间断监控&#xff0c;发现垃圾桶溢满周围有堆积物立即触发预警推送给相关人员处理。YOLOv5中在训练模型阶段仍然使用了Mosaic数据增强方法&#xff0c;该算法…

kubeadm方式部署k8s最新版本V1.26.2

Kubernetes核心概念 Master主要负责资源调度&#xff0c;控制副本&#xff0c;和提供统一访问集群的入口。--核心节点也是管理节点 Node是Kubernetes集群架构中运行Pod的服务节点。Node是Kubernetes集群操作的单元&#xff0c;用来承载被分配Pod的运行&#xff0c;是Pod运行的宿…

测试7年,去过阿里也去过小公司,给你们年轻人一个忠告...

你眼中的软件测试岗位是怎样的&#xff1f;大部分人可能会给出这样的回答&#xff1a;“测试&#xff1f;简单啊&#xff0c;没什么技术含量&#xff0c;无非就是看需求、看业务手册、看设计文档、然后点点功能是否实现&#xff0c;麻烦点的就是测试下部署安装是否出现兼容性问…

分布式事务Seata原理

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能与简单易用的分布式事务服务&#xff0c;为用户提供了 AT、TCC、SAGA 和 XA 几种不同的事务模式。Seata AT模式是基于XA事务演进而来&#xff0c;需要数据库支持。AT 模式的特点就是对业务无入侵式&#xff0…

【故障定位】基于多元宇宙算法的主动配电网故障定位方法研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

LeetCode 37. 解数独

一、题目描述 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#x…

如果重回大学时光

目录如果重回大学时光1. 多参加社团活动&#xff0c;结交更多的朋友2. 认真考虑专业分流方向3. 根据兴趣和能力选择适合自己的出路4. 为未来做好准备&#xff0c;规划职业发展如果重回大学时光 当前我是一名普通的码农&#xff0c;还有几个月&#xff0c;又将有一批大学生将毕…

vue实现美观大方的动漫、cos、帖子类型网站

一、先上效果图 1.项目demo预览&#xff1a;点击预览 参照半次元的榜单-绘画榜、榜单-COS榜、榜单-写作榜、个人中心、登录注册页面&#xff0c;导航栏等&#xff0c;分别实现页面排版、数据交互、基础框架布局搭建以及自定义vue组件合理的封装及使用。在vue项目开发过程中&a…