创建并发布您自己的 Python 包
关于如何 pip 安装您定制的软件包的简短指南
这些鸟是从源头安装的 pip(图片由詹姆斯·温斯科特在 Unsplash 上提供)
您可能对 requests、Pandas、Numpy 和许多其他可以用 pip 安装的包很熟悉。现在是时候创建自己的包了!在这篇文章中,我们将通过所需的步骤来打包和发布您的 Python 代码,供全世界进行 pip 安装。首先,我们将看看如何打包您的代码,然后我们如何发布它,使其易于访问。
(你更愿意和像同事这样的少数人分享你的代码吗?也可以允许人们从私有库 中 pip 安装包。甚至当 将你的包放入 Docker 容器时也是如此!T22)
目标和准备
在本文中,我创建了几个真正重要的函数,希望与大家分享。让我们创建一个名为“ mikes_toolbox 的包,人们只需通过pip install mikes_toolbox
就可以使用它。
首先,我们将概述一下安装过程是如何工作的:如果有人调用pip install mikes_toolbox
,代码必须来自某个地方。Pip 在 PyPi 上搜索具有该名称的包;Python 包索引。你可以把这个想象成 Python 包的 YouTube。首先我们将代码打包,然后上传到 PyPi,这样其他人就可以找到我们的包,下载并安装它。
包装
首先,我们将封装我们的代码。我们将创建一个名为“toolbox_project”的项目目录,其中包含以下目录和文件:
toolbox_project
mikes_toolbox
__init__.py
functions.py
decorators.py
LICENSE.txt
README.md
setup.cfg
setup.py
项目文件夹的内容由两部分组成:mikes_toolbox 文件夹和 4 个附加文件。该文件夹是我们包含源代码的实际包。这 4 个附加文件包含如何安装软件包的信息和一些附加信息。
一个包含我们的代码并附有安装说明的包(图片由 Christopher Bill 在 Unsplash 上拍摄)
包文件夹
mikes_toolbox 是我们实际的包,包含了我们所有的源代码。请确保将该文件夹命名为您想要的包名。在我的案例中,它包含以下内容:
- mikes_toolbox/function.py 和 decorators.py 这是我的源代码。Function.py 包含了一个函数比如叫做 weirdCase();一个可以让字符串完全不可读的函数。
- mikes_toolbox/init。py 这个文件是必需的。它告诉 python mikes _ toolbox 是一个 Python 包文件夹。你可以让它空着。您可以选择在这里包含 import 语句,以便更容易地从您的包中导入代码。一个例子:
包括from functions import weirdCase
。这样一来,人们就不必在软件包安装完毕后进行from mikes_toolbox.functions import weirdCase
,而是直接from mikes_toolbox import weirdCase
。
LICENSE.txt
描述人们如何使用您的许可证。从这个站点中选择一个,然后将内容粘贴到这个文件中。
README.md
这个文件包含关于这个包的信息:它是做什么的?它有什么特点?如何安装使用?在此查看示例或在此查看示例。
这个文件是用标记写的。在这个站点上查看一个已经包含一些示例标记的编辑器;只需根据您的需求进行编辑即可。
setup.cfg
这是一个简单的文件,只包含下面的代码。参考 README.md。
[metadata]
description-file = README.md
setup.py
该文件确保软件包正确安装。复制下面的代码,并在需要的地方进行修改。大多数条目都是符合逻辑的,但 download_url 需要一点解释(见下文):
下载 _ 网址
当你pip install pandas
pip 在 PyPi 上搜索熊猫时。一旦找到,PyPi 就告诉 pip 在哪里可以下载这个包。大多数情况下,这是 git 存储库中的一个文件。download_url 关键字指的是这个文件的位置。为了获得一个 URL,我们首先把源代码放在 pip 可以到达的地方。最好的方法是将您的代码上传到 GitHub repo 并创建一个版本。这个过程超级简单,步骤如下:
- 创建一个存储库(名称不必与包名相匹配,但更有序)。
- 在你的回购中,在右边;单击“创建新版本”
- 填写“标签版本”与 setup.py 中的相同(版本关键字)
- 给发布一个标题和描述。这并没有反映在包装中,这纯粹是为了在您的回购中保持一个概览
- 点击“发布发布”
- 复制“源代码(tar.gz)”的链接地址
- 将复制的链接地址作为下载 url 的值粘贴在 setup.py 中
就是这样!您的软件包现在可以下载和安装了。下一步是处理分销。
分配
到目前为止,我们所做的唯一一件事就是打包我们的代码并上传到 GitHub,pip 仍然不知道我们的包的存在。因此,让我们确保 pip 可以找到我们的软件包,以便人们可以安装它。
PyPi 帐户
如果你想在 YouTube 上发布视频,你需要先创建一个帐户。如果你想上传软件包到 PyPi,你也需要先创建一个帐户。去 PyPi 注册一个账号。继续之前,请确认您的电子邮件地址。
创建源分布
这将创建一个 tar.gz 文件,其中包含运行包所需的所有内容。打开一个终端,cd 到您的项目目录并执行下面的命令:
python setup.py sdist
(对终端不熟悉?查看 本 文章为绝对基础知识)
上传
我们准备好上传我们的包了!首先,我们需要 pip 安装 Twine,这将有助于我们上传。简单来说就是pip install twine
。
最后一步是实际上传包。在终端中,如果您还不在项目目录中,请转到该目录并执行
python -m twine upload dist/*
Twine 会要求您提供 PyPi 凭证,但在此之后,您的包应该会被上传!
测试
创建一个新的 python 项目,并(可选地)启动一个新的虚拟环境。然后pip install mikes_toolbox
。通过调用来测试代码
from mikes_toolbox import weirdCase
print(weirdCase("This function is essential and very important"))
更新您的包
如果你更新你的包,你需要确保更新 setup.py 中的版本,并在 GitHub 上创建一个带有相同标签的新版本。此外,更新 setup.py 中的 download _ URL。
一旦完成,用户就可以使用
pip install mikes_toolbox --upgrade
结论
在这些简单的步骤中,你已经学会了如何使用 PyPi 和 pip 打包你的代码并发布给全世界。此外,您还创建了一个存放代码的中心位置,可用于跟踪 bug、发布问题或请求新功能。不再通过邮件共享代码
我希望我已经阐明了很多创建和分发 Python 包的过程。如果你有建议/澄清,请评论,以便我可以改进这篇文章。同时,查看我的其他关于各种编程相关主题的文章。编码快乐!
—迈克
页(page 的缩写)学生:比如我正在做的事情?跟我来!
https://mikehuls.medium.com/membership
使用 Python 创建和读取二维码
如何使用 python 制作和读取二维码的简单分步指南
什么是二维码?
QR 码是机器可读的二维像素化条形码,可用于存储各种信息。二维码中的 QR 代表快速反应。二维码是由汽车制造商电装波的日本工程师 Masahiro Hara 于 1994 年发明的,用于追踪汽车零部件的运动。
2010 年代后期,随着手机光学功能的改善和广泛采用,二维码越来越受欢迎。
如今,二维码正被广泛用于各种应用,如在线支付、查看酒店菜单、共享 wifi 密码、获取产品价格和其他详细信息等。二维码已经变得如此流行,以至于现在每部新的智能手机都内置了二维码阅读器。
在这篇文章中,我们将学习如何使用 python 来读取和生成 QR 码。
生成二维码
安装二维码模块 我们将使用二维码包生成二维码。
第一步是使用 pip 命令安装软件包。
pip install qrcode
软件包的完整文档可以在软件包的 PYPI 主页中获得。
简单二维码
使用 qrcode 的 make 函数,将数据作为参数传递,可以生成一个简单的 qr 码。下面的代码生成一个二维码,上面写着“你好,世界”
#Import Library
import qrcode#Generate QR Code
img=qrcode.make('Hello World')
img.save('hello.png')
Hello World 的二维码(图片由作者提供)
你可以用你的智能手机阅读上面的代码。
注意:不要使用手机读取随机二维码,因为它可能包含恶意代码/链接。
高级二维码
可使用 QRCode 对象定制 QR 码,该对象具有以下参数:
一、版本 :
二维码有 40 个版本,控制码的大小。
1 为最小,40 为最大。
版本 1 将创建一个 21X21 矩阵二维码。
二。误差修正 :
该参数控制用于二维码的误差修正。误差修正率从 7%到 30%不等,如下所示。
错误 _ 更正 _L:高达 7%
错误 _ 更正 _M:高达 15%
错误 _ 更正 _Q:高达 25%
错误 _ 更正 _H:高达 30%
三世。box_size :
该参数控制二维码每个方框中的像素数
四。边框 :
该参数控制边框的粗细。默认边框为 4 像素厚。
QRCode 对象具有以下功能,可用于创建 QR 码。
*一、*添加数据
二维码的内容可以作为参数传递给这个函数。
二。制作
如果不确定使用哪个版本的二维码,可以通过以下方式自动设置版本:
a. 设置版本参数为无和
b. 设置的适合参数使到为真。
*三。*制作图像
该功能生成二维码。它还可用于使用 fill_color 和 back_color 参数设置二维码的填充颜色和背景颜色。
下面的代码生成一个指向我的中等个人资料的 QR 码。
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data("[https://abhijithchandradas.medium.com/](https://abhijithchandradas.medium.com/)")
qr.make(fit=True)img = qr.make_image(fill_color="red", back_color="black")
img.save("medium.png")
高级二维码(图片由作者提供)
读取二维码
我们将使用 OpenCV 读取二维码。如果没有安装软件包,可以按如下方式安装:
pip install cv2
二维码可以使用 OpenCV 的 QRCodeDetector 对象的 detectAndDecode 函数进行解码。
import cv2img=cv2.imread("medium.png")
det=cv2.QRCodeDetector()
val, pts, st_code=det.detectAndDecode(img)
print(val)Output:
[https://abhijithchandradas.medium.com/](https://abhijithchandradas.medium.com/)
detectAndDecode 函数返回 QR 码的内容、盒子角的坐标和二进制化的 QR 码。关于使用 OpenCV 读取二维码的更多信息,您可以参考 OpenCV QRCodeDetector 类参考。
资源:
教程的代码可以在我的 GitHub Repo 中找到。
成为会员
我希望你喜欢这篇文章,我强烈推荐 注册中级会员 来阅读更多我写的文章或成千上万其他作者写的各种主题的故事。
你的会员费直接支持我和你看的其他作家。你也可以完全接触到 Medium 上的每个故事。
相关文章:
从你的个人数据中创造美丽的艺术
我的跑步之旅;作者图片
教程-数据即艺术-亲和力
一步一步的教程来创造美丽的艺术使用数据工具和亲和力设计
大家好,我是 Gregor,一名数据科学家,一名热情的非竞赛跑步者。我也喜欢摄影艺术,与此同时——和其他一切一样——我仍在学习。
1.介绍
我在全职工作之外保持创造性的策略之一是写数据科学。我最近写了一篇关于如何提取和可视化我的智能手表收集的数据的文章。这是我最喜欢分享的技术和知识。但是最近,我读了一篇来自切斯卡·柯克兰的文章,她在文章中描述了她如何在封锁阶段收集个人数据,以及她如何利用这些数据创作出漂亮的海报,我当时就知道我被忽悠了。我也对数据艺术有所了解,我从乔治·诺比尔和斯蒂芬妮·波萨维克的亲爱的数据项目中找到了美好的灵感。
请跟随我从数据中创造个人艺术的旅程。在这篇文章中,我将向你展示我的设置,包括数据和工具,如何执行创建艺术的步骤,以及如何使用它的想法。
2.设置
为了创造一些与我平时创作完全不同的东西,我使用了不同于其他作品的工具。这里有一个我用过的工具的列表,但是你可以自由地做出你自己的选择。
- 数据本身
- 数据可视化工具 rawgraphs.io
- affinity Designer(Adobe Illustrator 的替代产品)
- 额外的图形资源(如纸质背景)
运行数据;作者图片
数据 在我的情况下,我利用了我的 Garmin sport-/智能手表在过去十年中收集的跑步数据。请随意 阅读我的颇具技术性的文章《如何检索和清理此类数据 》。该数据最重要的属性包括日期时间信息以及关于跑步距离的信息。
但是任何数据都可以。正如我在介绍中提到的,我的目标是从个人数据中创造个性化的艺术。这可能包括健身数据(Garmin connect、Strava、Apple Watch)、营养数据(如卡路里摄入量、水消耗量)、健康数据(体重测量、每日步数)。尽管如此,请随意使用您喜欢的任何数据。
https://rawgraphs.io 上可用图表概述(图片由作者提供)
数据可视化工具
但我最近发现了一个名为 rawgraps.io 的免费在线服务,它允许你创建大量不同的数据图表(取决于你的数据类型)。按照我的理解,它在你的浏览器中工作,但是数据没有上传到他们的后端;在你的电脑上,所有的东西都可以在你的浏览器中运行。
RAW Graphs 是一个开源的数据可视化框架,旨在使复杂数据的可视化表示对每个人来说都很容易。RAW Graphs 主要是为设计师和 vis 极客设计的工具,旨在提供电子表格应用程序(如 Microsoft Excel、Apple Numbers、OpenRefine)和矢量图形编辑器(如 Adobe Illustrator、Inkscape、Sketch)之间缺少的链接。— rawgraphic 的网站
他们提供了广泛的图表类型。有些很常见,比如条形图、箱线图、折线图。我发现最有趣的是不属于 MS Excel 或典型数据科学包的图表,如等值线图、桑基图或蜂群图。
卢卡斯·拉克,CC BY-SA 4.0<https://creativecommons.org/licenses/by-sa/4.0,通过维基共享
亲和设计师 如上所述,亲和设计师是 Adobe Illustrator 的替代品。这是一个矢量图形编辑器,它允许你 创建概念艺术、印刷项目、标志、图标、UI 设计、实体模型和更多 。
它适用于所有平台。与 Adobe 不同,Affinity 产品只需一次性付款,无需任何订阅。它目前减价 50%。如果你正在寻找一个免费/开源的 vector 应用,请尝试一下 Inkscape 。
附加图形资源 我直接从 Affinity 购买了一些纸质的背景。它叫做“ 涂抹水彩&洗 ”。我可以想象,你也可以在网上找到有趣的选择。
3.程序
在接下来的段落中,我将概述我所采取的步骤。
第一步:raw graphs . io
T22 首先,请前往 rawgraphs.io 。在这里,您可以选择将您的数据上传或复制粘贴到网站上(或者在浏览器中)。
截图自 rawgraphs.io(作者提供 gif)
其次,选择一个有趣的情节或图表。在我的例子中,我选择了蜂群图。但是请随意使用你喜欢的任何图表。第三,请向下滚动,直到你到达映射部分。对于 x 轴,我选择了我的日期栏,对于尺寸栏我选择了跑步距离、,对于颜色,我选择了跑步的年份。
当您进一步向下滚动时,图表会自动呈现在您面前。您可以在这里进一步定制。我选择将色标从顺序更改为发散,并更改了配色方案。同样,请随意使用提供给您的选项。最后,将您的图表作为 SVG 文件导出到您的计算机上。
第二步:亲缘关系设计者
首先,我创建一个新文件,长宽比为 5:4 横向(宽:3000 像素,高:2400 像素)。
在关联性设计器中创建新文件;作者图片
其次,我打开左侧的资产窗口,选择涂抹纸。对于我的图像,我选择了纸张#9,并将其拖到屏幕中间的空白画布上。我用手柄来定位它,这样它就覆盖了整个画布。
选择纸质背景;作者图片
第三,我应用一个颜色调整到纸张背景。你可以在菜单栏Layer > New Adjustment > Recolor
下找到。我将色调改为 50,饱和度改为 50,和亮度改为 9。
对背景应用重新着色调整;作者图片
第四,您可以导入之前创建的 svg 图。将文件从文件浏览器拖到画布中,或者使用File > Place ... > select your image
。您可以使用左侧的裁剪工具来调整大小和裁剪。
将图表放入画布;作者图片
接下来,我们将混合模式从正常更改为线性燃烧。你可以在右边的图层面板中实现。只要确保您首先选择了图形图层。
混合模式和标题图表的更改;作者图片
然后,我使用框架文本工具(快捷键 T)在图表上方放置一个文本框架。我把我的图表命名为跑步十年。在图表下方,我添加了一个带有年份和更多信息的图例。随意使用字体、颜色和文本大小。
添加图例;作者图片
当然,在图表中加入一些个人亮点。我发现传统的图表框架几乎不可能做到这一点。
添加个人详细信息;作者图片
第三步:尝试一些变化
这里,完成的定义是什么?我猜每当这个作品被送到印刷厂:-)。我尝试了这个版本的一些变化。为此,我推荐使用画板功能。如果你想了解更多关于 Affinity Designer 的知识,请看看他们的教程。
人像替代;作者图片
在第一个版本之后,我创造了一个肖像的替代品。我还添加了我自己的另一张照片来填补一些空白(在我不常跑步的几年里)。请注意,我为这张额外的图片使用了变暗混合模式。接下来,我对照片进行了一些模糊处理,这样就不会影响到图表,同时也降低了不透明度。
背景照片模糊;作者图片
接下来,我在风景模式下尝试了一个等高线图。我还改变了一些字体和颜色。
等高线图替代;作者图片
Martin Péchy 在 Unsplash 和 Kam Idris 在 Unsplash 的照片;由作者修改
4.结论
在这篇文章中,我向你展示了我从跑步数据中创造个性化艺术的尝试。很明显,我已经超出了我的能力范围,但是它让我尝试了一些新的东西,我肯定可以学到更多关于矢量编辑器的知识。
我将打印并装裱一个版本——希望——说服我的妻子把它挂在我们家的墙上。
你怎么想呢?你有什么反馈给我吗?
如有任何问题和意见,请随时联系我。谢谢你。点击此处查看我的更多文章:
- 了解我如何为媒体设计文章
- 了解我如何获得和分析我的 Garmin 跑步数据
- 了解如何为您的 Python 代码设置日志记录
- 了解如何使用链接(或管道)在 Python 中编写干净的代码
- 学习如何使用 R 分析你的 LinkedIn 数据
- 学习如何使用图形语法在 Python 中以描述性的方式创建图表
Gregor Scheithauer 是一名顾问、数据科学家和研究员。他专门研究流程挖掘、业务流程管理和分析。你可以在LinkedInTwitter上和他联系,或者在 Medium 上这里。谢谢大家!
使用 Excel 和 Tableau 创建定制的投资分析仪表板
投资、数据分析、Excel 和 Tableau
使用 Excel 的 STOCKHISTORY 函数获取股票价格数据和 Tableau 来构建投资分析仪表板
纽约的纽约证券交易所。照片由 Unsplash 上的 David Vives 提供。
“对知识的投资回报最高。” —本杰明·富兰克林
介绍
昨晚,当我回顾我的投资和当天的股市新闻时,一篇关于九月效应的文章引起了我的注意。人们用这个词来描述 9 月份股市低回报的假定历史趋势。在浏览了几篇关于这个话题的文章后,我进一步研究了它,以了解它是否准确,以及它是否会影响我 9 月份的股票投资。
我在我的经纪人网站、谷歌和雅虎上研究股票图表。这些网站提供了令人难以置信的投资分析工具,但没有一个能提供我所需要的东西来更好地理解九月效应的可能模式。所以,我做了我自己的仪表板,而且很有效。仪表板回答了我关于 9 月份股市是否总体持续下跌的问题。
本文将演示如何使用 Microsoft Excel 获取股票价格数据,并在 Tableau 中构建一个九月效应仪表板。您可以使用这里描述的工具和技术来执行各种其他投资分析和跟踪投资。
来自《走向数据科学》编辑的注释: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
九月效应数据分析项目概述
下面是我制作的“纽约证券交易所综合价格和九月效应”Tableau 仪表板的截图,它帮助我了解九月效应以及它是否真的存在。用 Excel 和 Tableau Public 构建不到两个小时。它应该作为未来定制投资分析项目的坚实基础。
九月效应仪表板。图片由作者提供。
以下是构建仪表板的步骤概述:
- 在 Excel 中,使用 STOCKHISTORY 函数检索每个月第一天纽约证券交易所(NYSE)综合指数的价格。例如,获取从 1966 年 1 月到 2021 年 7 月的价格数据。
- 在 Excel 中,计算每个月的价格变化和价格变化率。Excel 计算比率如下:比率=(month 2 price-month 1 price)/month 1 price。例如,1966 年 1 月 1 日的价格是 533.33 美元,1966 年 2 月 1 日的价格是 524.56 美元。因此,1966 年 1 月的变化率为-0.0165533853,百分比变化为-1.64%。
- 打开 Tableau 桌面或 Tableau 公共桌面应用程序。然后,将 Tableau 连接到上面步骤 1 和 2 中创建的 Excel 电子表格和工作表。
- 在 Tableau 中,创建一个九月效应工作表,显示一段时间内 NYSE 指数的价格和每月的价格变化百分比。此外,创建一个工作表,显示按月排序的每月平均价格变化百分比(不包括年份)。最后,创建另一个月度变化工作表,但按价格变化百分比排序。
- 组装一个包含上述三个工作表的 Tableau 仪表板。
- 将 Tableau 仪表板发布到 Tableau 服务器或 Tableau 公共服务器(在我的例子中)以与最终用户共享。
使用 Microsoft 365 中的股票历史功能
Excel 股票历史功能概述
我使用 Excel 已经很多年了,但是直到昨晚我在谷歌搜索“股票历史”来研究九月效应时,我才听说过它的股票历史功能。发现这个功能促使我建立了投资仪表板。该函数返回指定时间范围内几乎任何股票、ETF、共同基金和一些证券指数的价格历史。
请注意,在作为微软 365 订阅产品一部分的 Excel 的联网版本中,STOCKHISTORY 函数仅在 和 有效。例如,我订阅了微软 365 系列,所以我立即将 STOCKHISTORY 投入使用。
选择用于股票历史的综合股票指数
STOCKHISTORY 将投资工具(股票、ETF 或共同基金)或综合指数股票作为其第一个参数。我最初想用标准普尔 500(标准普尔 500)综合指数价格来分析九月效应。但是 STOCKHISTORY 只返回了过去十年的月值。因此,在对综合指数做了一些研究后,我选定了纽约证券交易所(NYSE)的综合指数。
纽约证券交易所是一家美国证券交易所,于 1792 年获得了第一笔交易证券。到目前为止,全球最大的证券交易所,其上市公司的市值在 2018 年 2 月达到 30.1 万亿美元。投资者每个交易日都在交易所交易数十亿美元。
纽约证券交易所在 20 世纪 60 年代中期建立了它的综合指数(股票代码:NYA)。1965 年 12 月 31 日开市时,该交易所给该指数的初始值为 50 点。2003 年,纽约证交所将该指数重新设定为 5000 点,接近 2002 年的收盘点位。
今天,纽约证券交易所列出了 2000 多种股票。其中大约 1600 家是美国公司,其余的是外国公司。因此,该指数很好地代表了股票市场。与它的规模相比,标准普尔 500 综合指数列出了 500 家大公司,道琼斯工业平均指数(DJIA)列出了 30 家著名公司。
基于纽约证交所的规模和历史,它似乎很适合我的需求。另外,与标准普尔 500 综合指数不同,STOCKHISTORY 函数返回纽约证券交易所指数从 1966 年 1 月到 2021 年 7 月的月度价格。
利用股票历史获取纽约证券交易所综合指数价格
虽然许多 Excel 函数可以访问多个工作表单元格中的数据,但它们通常在单个单元格中写入和显示数据。另一方面,STOCKHISTORY 可以将数据“溢出”到其他单元格中。例如,查看下面的截图。STOCKHISTORY 函数检索 NYA 股票交易所(NYSE 综合指数)55 年来的月度价格数据。因此,即使函数驻留在单元格 A2 中,其结果也会溢出到区域 A2:B69 中。
在 Excel 中使用股票历史函数。图片由作者提供。
出于我的目的,我将 STOCKHISTORY 调用如下:
=股票历史(" NYA “,” 1–1–1966 “,” 9–1–2021 ",2,0)
从左至右,以下是其参数的含义:
- 股票 —股票、电子资金转账、共同基金、其他证券或指数的代码。在这种情况下,“NYA”是纽约证券交易所综合指数的股票代码。
- 开始日期 —所需日期范围的第一天。在这种情况下,该值为“1–1–1966”
- 结束日期 —所需日期范围的最后一天。在这种情况下,该值为“9–1–2021”
- 间隔 —每个数值代表的时间间隔。允许的值为 0(每天)、1(每周)和 2(每月)。我选择 2(每月),因为我需要按月计算值的变化。
有关 STOCKHISTORY 函数及其参数的更多信息,请参见下面“了解更多”一节中的链接。
“我将告诉你如何变得富有。关上门。当别人贪婪的时候要恐惧。在别人恐惧的时候贪婪。” —沃伦·巴菲特
创建 Excel 电子表格
为了获取纽约证券交易所综合指数(股票代码 NYW)值数据并准备在 Tableau 中使用,我创建了一个名为“NYSE _ June . xlsx”的 Excel 电子表格,其中有一个名为“NYA”的工作表。完成后,它将在四列中包含计划的 Tableau 九月效果仪表板所需的所有数据。
按照以下步骤重新创建 NYA 工作表:
- 在第 1 行的 A 到 D 列中,输入“日期”、“价格”、“下个月的价格”和“变化”的列名
- 在单元格 A2 中,按照上一节所述输入此公式:=股票历史(" NYA “,” 1–1–1966 “,” 9–1–2021 ",2,0)
- 在单元格 A2 中,按[Enter]键。如果函数正常工作,日期和价格数据应该填充 A 列和 B 列到 69 行。如果没有,请确保您拥有有效的 Microsoft 365 订阅,并且您的计算机已连接到 Internet。
- 将 A 列中的每个日期格式化为日期值。为此,右击单元格并点击[单元格格式…]。一个对话框将显示可能的格式列表。单击[日期],然后单击[确定]。
- 将此公式输入单元格 C2: =B3 。然后,将公式复制并粘贴到单元格 C3 到 C69 中。虽然这一栏是必要的,但可能并不明显。总之,它的存在确保了单元格 C2 到 C69 中的公式拥有计算其值所需的所有值。
- 将此公式输入单元格 D2: =(B3-B2)/B2 。然后,将此公式复制并粘贴到单元格 D3 至 D69 中。对于每个月,该公式计算从当月到下月的价格变化率。
- 保存电子表格文件。
该电子表格应该类似于下图所示。请注意列名右侧的向下箭头符号。它们是我添加的过滤器,用来帮助我检查数据。
纽约证券交易所综合指数数据电子表格样本。图片由作者提供。
创建 Tableau 可视化和仪表板
纽约证券交易所综合指数数据已经获得、准备并存储在一个 Excel 文件中。以下总结步骤描述了在 Tableau Public desktop 中连接文件和构建可视化效果。虽然我使用 Tableau 已经超过五年了,但它需要一些尝试和错误。因此,描述创建仪表板的每个步骤的教程超出了本文的目的。
此外,如果您想使用免费的 Tableau Public 而不是整个 Tableau,请注意,您只能将您的工作保存到 Tableau Public 网站。这使得你的可视化可以被世界上的任何人使用。所以,一定要排除网站上的机密信息。
安装 Tableau
若要执行以下步骤,您需要安装 Tableau Desktop 或 Tableau Public Desktop 的副本。要安装 Tableau Public Desktop,请按照 Tableau Public 主页上的说明进行操作,并下载本文末尾“了解更多”一节中列出的链接。Tableau 公共桌面应用程序和 Tableau 公共网站上的发布是免费的。
连接到数据
打开 Tableau 桌面或 Tableau 公共桌面应用程序。然后,按照下面列出的步骤连接到 Excel 电子表格和工作表。参考截图中的例子。
- 在“连接”标题下,单击[Excel]。
- 在“打开”对话框中,导航到存储 NYSE 综合指数电子表格文件的文件夹。
- 单击电子表格的名称,然后单击[打开]。
使用 Tableau 连接到 Excel 文件。图片由作者提供。
月度指数价格数据应该显示在“数据源”窗口中,如下所示。
Excel 中的数据已成功加载到 Tableau 中。图片由作者提供。
构建工作表和控制板
Tableau 项目包含一个名为“纽约证券交易所和九月效应”的仪表板它包括三个工作表,称为“九月效应”、“月度变化”和“月度变化等级”仪表板讲述了“九月效应”的部分故事,至少使用了 1966 年开始的纽约证券交易所综合指数数据。
如上所述,我不会提供组装工作表和仪表板的详细说明。取而代之的是,每张照片的截图会提供它们是如何制作的想法。
Tableau Public 入门
如果您是 Tableau 的新手,我建议您按照以下步骤开始学习如何使用该工具:
- 安装免费的 Tableau 公共桌面应用程序。请参阅本文末尾“了解更多”一节中的链接。
- 创建一个免费的 Tableau 公共帐户,以便您可以将可视化效果保存并发布到 Tableau 公共网站。
- 观看免费的 Tableau 在线培训视频。有关更多信息,请参见下面“了解更多”部分中的培训资源链接。
创建工作表
Tableau 公共桌面应用程序中的“九月效应”工作表如下所示。蓝色线条图描绘了纽约证券交易所综合指数的月值。条形图显示了指数的月度变化(增加或减少)。
纽约证券交易所和九月效应可视化。纽约证券交易所和九月效应可视化。图片由作者提供。
下面显示的“每月变化”工作表以条形图显示了指数每月的平均百分比变化。
纽约证券交易所综合指数月平均变化条形图。图片由作者提供。
如下所示的“月度变化等级”工作表与“月度变化”工作表相同,只是条形图按月度变化百分比降序排列。
纽约证券交易所综合指数月度平均变化条形图,按变化百分比降序排列。图片由作者提供。
创建工作表后,我将它们组装到一个仪表板中,如下所示。请注意,三个图表的时间窗口受位于右下角的“日期范围”过滤器的影响。
Tableau 公共桌面应用程序中的九月效果 Tableau 仪表板。图片由作者提供。
将仪表板发布到 Tableau Public
在改进和测试仪表板及其底层工作表后,我将其发布在 Tableau 公共网站上。你可以在这里看到完成的项目并与之互动。
结论
用 Excel 及其 STOCKHISTORY 功能获取纽约证券交易所综合指数数据的项目以及“九月效应”Tableau 仪表板的构建和使用帮助满足了我的好奇心。当我与仪表板互动时,我更好地理解了九月效应。当我投资股票时,这个项目帮助我确认了我和我的“货币与金融”课教授的共识,他说,“股票市场和任何东西都没有关系。”
通过九月效应项目,我获得了新的知识和技能。我还开发了分析投资证券和市场的新方法。当现有的投资分析仪表板不能满足我的分析需求时,我打算继续使用 Excel、其股票历史功能和 Tableau 来增强我的能力。
我希望你也能从这篇文章中获得新的知识和想法。感谢您的阅读。
“对历史有一个好的视角,我们可以更好地理解过去和现在,从而对未来有一个清晰的愿景。” —卡洛斯·斯利姆·埃卢
关于作者的免责声明
虽然我在软件开发、数据工程和数据分析方面有丰富的专业经验,但我是个业余投资者。请不要依赖这里提供的信息来指导你的投资。请依靠自己的决策和专业的投资建议。
了解更多信息
从准备发布的数据框架中创建完美的表格
杰瑞米·泽罗在 Unsplash 上的照片
教程-表格-R
如何创建发布就绪表的分步教程
我是一名数据科学家,大多数时候,我会考虑一种完美的方式来可视化大量数据,以向客户和团队成员传达有趣的发现。老实说,在大多数情况下,如果不是在所有情况下,以简单的表格形式显示数据及其结构是必要的,并将有助于提高整体理解。
然而,在大多数情况下,我使用 PowerPoint 或 Excel 来创建这个表,以使其看起来可展示和/或可发布。这当然打破了自动重现这一结果的可能性。在我最近的一个项目中,我了解并应用了一个软件包,该软件包允许我在不离开我的数据科学平台的情况下创建漂亮的、可供发布的数据表。
1 简介
在本文中,我将向您展示如何使用 Grammar of Tables (gt)包来创建完美的、准备发布的表格,将您的设置转换为主题以便快速重用,以及如何在您的下一个数据科学项目中应用该主题。
标准普尔 500 数据示例表(图片由作者提供)
2 设置
我的大部分客户工作都涉及到 Python 和熊猫。但是,通过训练,我是一个 R 人。我为 R 数据科学平台解决了这个问题,但是在我即将发表的一篇文章中,我将研究如何使用 Python 和 Pandas 来实现这个问题。
然而,以下是我正在使用的软件和软件包列表:
- R & RStudio —语音的数据科学平台和 IDE。
- tidyverse 包——这个包允许我编写优雅、可读、高效的代码来操作数据帧
- gt 包 —表格语法(gt)包,打造完美的表格设计
- Gapminder 软件包——Gapminder 按国家分列的预期寿命、人均国内生产总值和人口数据摘录
2.1 表格语法概述(gt)
gt 包遵循一种描述性的方法来创建表格,比如图形的语法。简而言之,它允许我们指定什么应该发生,而不是指定如何应该发生——这是编写代码的一种非常棒且可读的方式。
gt 表的零件(图片来源:https://gt.rstudio.com)
gt 包定义了大量的区域来添加到您的表中,并操纵它们的可视化。在下面的例子中,我将向你解释如何使用这些区域。
还需要注意的是,您可以为 R notebook 创建一个表格,并以多种格式保存该表格,包括 HTML 和 PNG,如果您需要在不同的出版物(如网站或 PowerPoint 文档)中报告表格,这将非常有用。
2.2 包和常量
在开始创建一个表之前,我先分享一下这段代码,它将加载(如果有必要的话,还会安装)必需的包:
我还使用了一些帮助我编写灵活的 R 脚本的常量。请注意,我使用 c_rn 来指定表中包含的最大行数,使用 c_save 来确定是否将表创建过程的每一步都保存为文件(这需要一点时间),使用 c_format 来指定输出格式。
Gapminder 数据集的一般输出如下所示:
标准控制台输出(图片由作者提供)
3 创建一个完美的、准备发布的表格
gt 包最基本的用途只是将过滤后的数据帧传递给 gt 函数。不过,这并不太令人兴奋,也没有给标准控制台输出带来任何好处。
标准 gt 输出(图片由作者提供)
3.1 添加分组列
这可能与您的大多数数据框无关。然而,我想展示这是如何工作的,这将有助于更好地理解你的表。为此,我将列 continental 作为分组列传递,并将 country 列指定为行标签列。
添加分组列(图片由作者提供)
3.2 添加汇总行
下面的代码允许我们添加汇总行。摘要可能包含的内容由你决定,并对你的听众有价值。我决定添加函数 sum、average 和 standard deviation。虽然不是所有的汇总函数对这个数据集都有意义,但我想展示如何实现它们。
添加汇总行(作者图片)
3.3 更改每列的标签
我相信你在你的项目中也经历了这一点。如何给你的栏目贴标签?您的数据框通常使用技术名称(即,不含空格的短名称),但也有对受众有意义的功能名称。Gapminder 数据集中的一个例子是真正代表“预期寿命”的列 lifeExp。gt 包允许我们在不改变数据集的情况下改变结果表的标签。
更改标签名称(图片由作者提供)
3.4 格式化列
格式化列包括几个方面。在这个例子中,我告诉包区分数字和货币列,它们的对齐方式,以及它们应该有多少空间(px)。opt_row_striping()函数创建带状行,以提高表格的可读性。
格式化列(图片由作者提供)
3.5 添加标题、脚注和来源
如果您计划将所有相关的元信息作为表布局的一部分,gt 包将会帮助您。尤其是脚注的可能性是有益的,因为你可以对它应用一个函数。在下面的例子中,将为人口最少的国家添加一个脚注。请注意,可以使用 md 函数使用标记来修改文本布局。
添加标题、脚注和来源(图片由作者提供)
3.6 对表格应用格式
这是一个相当长的问题,但是我希望代码能够解释这里可能会发生什么。请注意,我使用了函数 tab_options() 以及 tab_style() 。tab_options 看起来像是操纵一般的设置,而 tab_style 用于更具体的位置。请分享你的想法来简化下面的代码。非常感谢。
将格式应用于表格(图片由作者提供)
3.7 应用条件单元格着色
gt 包的另一个有用的特性是基于值给单元格着色的能力。在下面的例子中,我将以两种不同的方式使用它。首先,我想为第一个中的“预期寿命”一栏应用蓝色底纹。为此,我将使用名为 c_col 的调色板,它在开始时被指定为常量之一。
我想用第二种方法将人口最少的行涂成蓝色。
应用条件单元格颜色(图片由作者提供)
4 创建可重复使用的 gt 主题
为了创建一个主题,我需要理解如何区分与外观相关的设置和与特定于数据的列相关的设置(这将随着每个数据集而改变)。为了展示这一点,我将使用数据集“每日标准普尔 500 指数数据”,它是 gt 包的一部分。
4.1 从 S & P 数据集创建一个 gt 表
标准 gt 表输出(图片由作者提供)
4.2 创建主题
我创建了一个函数 my_theme() ,它可以快速应用于你的任何 gt 表。
主题 gt 表输出(图片由作者提供)
请注意,这个主题是用我有限的知识构建的。因此,请分享如何改进和简化这段代码的想法。非常感谢。
4.3 应用特定于列的格式
剩下的步骤是格式化特定于 S&P 的列。首先,我用货币格式指定列。
格式化列(图片由作者提供)
最后,我向表中添加汇总行,包括平均值和标准偏差。
添加了汇总行(图片由作者提供)
5 结论
在本文中,我向您介绍了 gt 包。然后,我向您展示了如何格式化表格、包含汇总行以及应用条件单元格格式。此外,我解释了如何创建一个单独的主题,您可以在每个数据项目中重用它。
请注意,我只是触及了 gt 包的表面。此外,我的知识可能有限,有更好的方法用更少的代码实现这些结果。如果你有兴趣,请接触其他教程,进一步教育自己。我很高兴与下面的列表分享伟大的教程:
- http://www . danieldsjoberg . com/gt-and-gt summary-presentation/# 1
- https://themockup.blog/static/slides/intro-tables.html#1
- https://malco . io/2020/05/16/replication-an-nyt-table-of-Swedish-covid-deaths-with-gt/
- https://themockup . blog/posts/2020-05-16-gt-a-grammer-of-tables/
你怎么看?你有什么反馈给我吗?
如有任何问题和意见,请随时联系我。谢谢你。
为您的时间序列数据创建 GitHub 的风格贡献图
让您的热图脱颖而出
墙上的另一块砖|作者图片
Github 贡献图显示了您在过去一年中对存储库的贡献。一张填满的贡献图不仅看起来赏心悦目,还表明了你的努力工作(除非你已经黑了它)。图表虽然漂亮,但也显示了关于你的表现的大量信息。然而,如果你仔细观察,它只是一个显示一些时间序列数据的热图。因此,作为一项周末活动,我试图复制一些基本时间序列数据的图表,通过本文与您分享这一过程。
数据集和一些预处理
我将在本文中使用的数据集来自 Kaggle 上的表格游乐场系列(TPS)竞赛。TPS 竞赛为期一个月,于每月 1 日开始。我将使用 TPS — 七月版竞赛 中的数据集。
数据集是基于时间序列的数据,其任务是根据基本天气信息(温度和湿度)和 5 个传感器的输入值,预测空气污染测量值随时间的变化。
让我们导入基本库并在 pandas 中解析数据集。
import pandas as pd
import numpy as np
import datetime as dt
from datetime import datetimedata = pd.read_csv(‘train.csv’, parse_dates=[‘date_time’])
data.head()
时间序列数据集
对于我们的目的来说,这是一个相当不错的数据集。我们开始工作吧。
使用 Seaborn 库创建基本热图
Seaborn 是 Python 中的统计数据可视化库。它基于 matplotlib,但是有一些很棒的默认主题和绘图选项。从技术上讲,创建热图本质上是用颜色替换数字。更准确地说,这意味着将数据绘制成颜色编码的矩阵。让我们看看如何通过代码实现这一点。但在此之前,我们必须将数据转换成所需的格式
#Importing the seaborn library along with other dependenciesimport seaborn as sns
import matplotlib.pyplot as plt
import datetime as dt
from datetime import datetime# Creating new features from the datadata['year'] = data.date_time.dt.year
data['month'] = data.date_time.dt.month
data['Weekday'] = data.date_time.dt.day_name()
对数据进行子集化,只包含year 2010
,然后丢弃除了month
、weekday
、and
、deg_C.
之外的所有列,然后我们将旋转数据集,得到一个类似矩阵的结构
data_2010 = data[data['year'] == 2010]
data_2010 = data_2010[['month','Weekday','deg_C']]pivoted_data = pd.pivot_table(train_2010, values='deg_C', index=['Weekday'] , columns=['month'], aggfunc=np.mean)
由于我们的数据集已经以矩阵的形式存在,现在用 seaborn 绘制热图只是小菜一碟。
plt.figure(figsize = (16,6))
sns.heatmap(pivoted_data, linewidths=5, cmap='YlGn',linecolor='white', square=True)
使用 Seaborn 库创建的热图|图片由作者提供
热图显示了 2010 年的平均温度(摄氏度)。我们可以清楚地看到,7 月是当年最热的一个月。为了模拟 Github 的贡献图,使用了一些参数:
- pivoted_data:使用的数据集
- 线宽:分隔每个单元格的线的宽度。
- 线条颜色:划分单元格的线条的颜色
- 方形:确保每个单元格都是方形的
这是一个很好的尝试,但仍有改进的余地。我们还没有接近 Github 的贡献图。让我们用另一个库再试一次。
使用 calmap 创建日历热图
Python 中有一个名为 calmap 的专用库,而不是对 seaborn 进行修补。它根据 Github 贡献图中的时间序列数据创建了漂亮的日历热图,而且只用了一行代码。
#Installing and importing the calmap library
pip install calmap#import the library
import calmap
我们将使用与上一节相同的数据集,并使用yearplot()
方法来绘制。
#Setting the date_time column as the index
data = data.set_index('date_time')#plotting the calender heatmap for the year 2010
plt.figure(figsize=(20,10))
calmap.**yearplot**(data['deg_C'], cmap='YlGn', fillcolor='lightgrey',daylabels='MTWTFSS',dayticks=[0, 2, 4, 6],
linewidth=2)
使用 calmap 库创建的热图|图片由作者提供
上面,我们已经定制了color
、linewidth
和fillcolor
,即在没有数据的日子里使用的颜色。您可以根据需要设置这些值。更多信息可从文档中获得。
也可以使用[**calendarplot()**](https://pythonhosted.org/calmap/#calmap.calendarplot) method.
将所有年份作为支线剧情绘制成一个图形
fig_kws=dict(figsize=(20, 10)
带有 calmap 库的 Calenderplots 按作者分类的图像
如你所见,2011 年的数据并不多,但我相信你已经有了想法。
包裹
热图是有用的可视化工具,通过使用颜色提供深度透视来帮助传达模式。它有助于可视化矩阵的两个维度之间的值的集中,这对人眼来说比单纯的数字更明显。这篇文章向你展示了如何让你的热图变得更明亮、更生动,并在创建热图时获得乐趣。
在 R and R 创建交互式地图应用程序,探索地理空间数据
使用地图进行输入选择的 Web 应用程序
作者制作的动画
数字所能讲述的重要故事通常与地点有关。地理空间数据(或空间数据,也称为地理数据)是指由地理位置指示或与地理位置相关的任何数据( REF )。地理空间数据将地址、邮政编码或区域等位置信息与和该位置相关联的相应属性信息相结合。
对于大多数人来说,如果不使用地图,很难探索地理空间数据。通过这个应用程序,我们展示了如何使用 R and R Shiny 创建一个免费的开源(FOSS)解决方案,允许用户与地理空间数据进行交互,并使用交互式地图快速找到他们想要看到的内容。
Web 应用程序设计
我们选择使用 运费分析框架【FAF】数据进行本次论证。FAF 是一个公共数据源,提供各州和主要大都市地区之间所有运输方式的货运流量的估计和预测。
与 FAF 数据相关联的地理信息被定义为区域。在美国大陆地区总共有 129 个 FAF 区,每个区都可以是起点区或终点区。换句话说,有 129×129 个可能的始发地-目的地区域对组合。
用户可以浏览他们选择的任何始发地和目的地区域对之间的货运数据。该工具提供了一种直观的方法,用户可以直接从地图上选择一个区域,同时获得区域的位置、大小和边界信息,而不是从 129 个区域的长列表中选择一个区域。
运费分析框架区域(图片由作者提供)
用户可以通过点击区域直接从地图上选择始发地和目的地区域来选择他们想要查看的数据。他们可以放大、缩小或平移地图来查找感兴趣的区域。
如果单击原点,原点区域的质心将显示为绿色。如果单击目标区域,目标区域的质心将显示为红色。我们将在本文后面解释当选择一个区域时,如何确定区域类型(即起点和终点)。
一旦选择了始发地和目的地区域,应用程序后端的 R 脚本将查询 FAF 数据,并将结果显示为所选始发地-目的地区域对的数据表和图表。
我们将一步一步地解释这个 web 应用程序的实现,如下所示:
- R and R 闪亮简介
- 布局用户界面(UI)
- 设置服务器以生成输出
- 免费发布闪亮的应用
注:这篇文章的代码和数据可以在this GitHub repo找到。
1.R and R 闪亮简介
r 是一种用于统计计算和图形的语言和环境。R 的优势之一是可以很容易地制作出设计良好的出版物质量的情节。(参考
Shiny 是 R 的一个 web 应用程序框架,它结合了 R 的计算能力和现代 web 的交互性。Shiny 为开发者提供了卓越的能力来创建 web 应用程序,这些应用程序可以使用你自己的服务器或 Shiny 的托管服务来部署。
闪亮应用的结构
Shiny app 是一个目录,包含两个 R 脚本,即ui.R
和server.R
以及其他输入到 app 的文件。
ui.R
控制应用程序的布局和外观,并在闪亮的应用程序中创建用户界面。它通过接受用户输入并在屏幕上动态显示生成的输出来为应用程序提供交互性。
server.R
包含构建应用程序逻辑的指令,因此它就像是应用程序的大脑。它将用户的输入转换成想要的输出,如表格和图表,显示在屏幕上。
或者,Shiny app 可以由一个名为app.R
的文件组成,该文件包含 UI 和服务器组件。一个只有一个文件(即app.R
)的闪亮应用的基本结构如下所示:
library(shiny)ui <- fluidPage(
# front end interface
)server <- function(input, output, session) {
# back end logic
}shinyApp(ui = ui, server = server)
保持两个独立的 R 文件,即ui.R
和server.R
*、*通常被认为是一个好的实践,特别是对于较大的应用程序,具有独立的ui.R
和server.R
文件使得代码更容易管理。
2.布局用户界面(UI)
首先,我们将所有需要的库加载到应用程序中。应用程序界面通常使用fluidPage
创建,这样可以确保页面根据每个设备的分辨率动态布局( REF ),这样应用程序界面可以在不同屏幕分辨率的不同设备上流畅运行。
我们使用fluidRow
和column
从网格系统构建我们的定制布局。行由fluidRow()
函数创建,包括由column()
函数定义的列( REF )。
我们还使用 Shiny 的 HTML 标签函数为用户界面添加内容,比如br, div, span, HTML
等。这些功能与常见的 HTML5 标签相似。
使用span()
函数添加的应用程序“运费分析框架 FAF4 vs. FAF5,2017 年”的标题显示在界面顶部,后面是一个fluidRow()
,左边是一个名为“Zone”的地图,右边是一组静态(如span("select")
)和动态文本输出(如htmlOutput("od_info")
)。
闪亮的应用程序包含输入和输出对象。输入允许用户通过修改他们的值与应用程序交互(我们将在后面讨论输入对象)。输出是显示在应用程序中的对象(参考)。输出对象总是与渲染函数配合使用,例如:
ui <- fluidPage(
leafletOutput("Zone")
)server <- function(input, output, session) {
output$Zone <- renderLeaflet({
# generate the map
})
}
在ui
中我们使用leafletOutput()
,在server()
中我们使用renderLeaflet()
。在renderLeaflet()
中,我们写下返回传单地图的说明。
此应用程序中显示的输出对象类型包括:
活页 用于创建交互式地图,如leafletOutput("Zone")
html 用于将反应输出变量显示为 html,如htmlOutput("od_info")
DT 用于显示交互表格中的数据,如DT:dataTableOutput("od_vol")
plotly 用于创建与数据交互的图形,如plotlyOutput("od_ton_chart”)
3.设置服务器以生成输出
导入数据文件
数据文件与 R 文件位于相同的位置。我们使用read.csv()
函数读取 CSV 文件(centroid.csv``od_mode_vol_45.csv
),使用 rgdal 包的readOGR()
函数读取 FAF 区域的 shape file(faf4_zone2.shp
)。
区域 shapefile 中的每个要素都是一个多边形。以下是 shapefile 中属性数据的示例。表中的每一行都用区域 ID、区域名称和几何定义了一个多面要素(即区域)。
来自 faf4_zone2 的数据示例(图片由作者提供)
centroid.csv
中的每一行用区域 id、区域名称、经度和纬度定义了一个 FAF 区域质心(即区域的中心位置)。注意centroid.csv
中的区域 ID 和区域名称与 shapefile 中的对应。因此,我们可以使用区域 ID 作为从区域多边形到区域质心的关键字,反之亦然。
数据示例来自 centroid.csv(图片由作者提供)
od_mode_vol_45.csv
包含每个始发地-目的地区域对(使用区域 id 定义)按运输方式(如卡车、铁路、水路、航空等)计算的重量和价值的货运数据。此文件中的数据是从原始的 FAF 版本 5 (FAF5)数据和 FAF 版本 4 (FAF4)数据设计而来的。
FAF5 数据提供 2017 年的货运走势预估;而 FAF4 数据提供了 2017 年 的货运预测 。该应用程序比较了每个始发地-目的地对的 FAF5 与 FAF4 的 2017 年数据。
文件od_mode_vol_45.csv
中的起点 ID 和终点 ID 对应于centroid.csv
和faf4_zone2.shp
中的区域 ID 字段。
数据样本来自 od_mode_vol_45.csv(图片由作者提供)
使用全局变量来跟踪区域选择
让我们先解决房间里的大象。应用程序需要判断点击(或选择)的区域应该是起始区域还是目标区域。
我们假设当用户开始使用应用程序时,第一个点击的区域将是源区域,第二个点击的区域将是目标区域。
然而,如果用户希望通过选择另一对始发地和目的地区域来继续使用该应用程序,该怎么办?如果用户在地图上不断点击,不断改变选择怎么办?
为了解决这个问题,我们需要跟踪用户点击地图的总次数。
下面的全局变量用于跟踪用户的区域选择动作。因为我们需要在不同的函数中访问和改变这些变量的值,所以有必要将这些变量定义为全局变量。
*click_count <- 0
type <- 0
origin <- ""
dest <- ""
origin_id <- 0
dest_id <- 0*
- 变量
click_count
用于跟踪自会话开始以来地图上的累计点击次数。 注意其初始值设为 0 。 - 变量
type
用于将click_count
转换为区域类型,即始发地区域或目的地区域。它的值由模数click_count
乘以 2 计算得出:
*# with click_count initiated with value 0type <<- click_count%%2if (type ==0 ){
# treat as origin zone
}
if (type == 1){
# treat as destination zone
}# add one to the accumulative map click counts
click_count <<- click_count+1*
上面的代码将被嵌入到一个函数中,要改变函数内部全局变量的值,我们需要使用全局赋值操作符
<<-
。当使用赋值运算符<<-
时,该变量属于全局范围。
- 变量
origin
和dest
用于存储所选始发地和目的地区域的描述性区域名称。 - 变量
origin_id
和dest_id
用于存储所选起点和终点区域的区域 id。
Shiny 中的反应式编程
Shiny 使用一个反应式编程模型来简化 R-powered web 应用程序的开发。Shiny 从用户界面获取输入,用 监听变化,观察 或 无功。
反应源通常是通过浏览器界面的用户输入。我们通过在构建输出的server()
中的反应表达式(如render*()
和reactive()
函数)中包含输入input$variable_selected
的值来创建反应。当输入发生变化时,所有依赖于输入的输出都将使用更新后的输入值自动更新(或重建)。
传单 当用户与地图和对象交互时,它们会将输入值(或事件)发送到 Shiny。对象事件名称通常使用这种模式:
输入$MAPID_OBJCATEGORY_EVENTNAME
对于leafletOutput("Zone")
,点击其中一个多边形形状(即 FAF 区)将在input$Zone_shape_click
更新闪亮的输入。
点击事件被设置为 NULL(如果该事件从未发生过),或者 list()包括:对象的纬度和经度是可用的;否则,鼠标光标;和 layerId,如果有的话。
在我们的例子中,基于区域 Id 的 layerId 字段包含在多边形对象中;因此区域 ID 的值将在input$Zone_shape_click
事件的事件$Id* 中返回。*
*addPolygons(data=zone.rg, col="black", weight = 1, **layerId = ~id**, label = zone_labels, highlight = highlightOptions(color = "blue",weight = 2, bringToFront = F, opacity = 0.7))*
我们希望应用程序的服务器端对地图上的点击做出响应,所以我们需要创建反应式表达式,使用reactive()
函数来结合用户的选择。使用reactive()
函数也有助于减少代码中的重复。
selected_zone()
返回点击(或选择)区域的质心。
*selected_zone <- reactive({
p <- input$Zone_shape_click
subset(centroid, id==p$id )
})*
selected_od()
返回所选始发地-目的地区域对的信息(包括区域名称和区域 id)。请注意,它会一直等待,直到选择了起始区域和目标区域才返回值。
如果选择了一个新的原点区域,上一轮选择的目的区域将被重置。
*selected_od <- reactive({
p <- input$Zone_shape_click
# return selected origin-destination zone pair
})*
使用带光泽的传单
传单 是最流行的用于交互式地图的开源 JavaScript 库之一。 活页 包装包含强大而方便的功能,可与闪亮的应用程序集成(参考)。可以通过以下基本步骤创建传单地图:
- 通过调用 leaflet()创建地图小部件
- 通过使用图层功能(例如,添加切片、添加标记、添加多边形)来修改地图微件,将图层(即,要素)添加到地图中。
- 根据需要重复步骤 2。
- 打印地图微件以显示它。
*output$Zone <- renderLeaflet({
# create zone labels
# create map widget called m
# add base map and the FAF zone polygon layer
})*
观察者使用热切评估策略,即一旦他们的依赖关系改变,他们就调度自己重新执行。
现在我们更新input$Zone_shape_click
对应的地图。当input$Zone_shape_click
改变时,观察器将自动重新执行。
*observe({
p <- input$Zone_shape_click # get input value
if (is.null(p))
return()
m2<-leafletProxy("Zone", session = session) # get map widget
# create zone labels
selected <- selected_zone() # get selected zone centroid
# create selected zone label
type <<- click_count%%2
if (type ==0 ){
# clear the centroids displayed
# add a marker, the centroid of the new origin zone
}
if (type == 1){
# add a marker, the centroid of the new destination zone
}
click_count <<- click_count+1 # keep track of map clicks
})*
首先获取所选区域,并使用前面解释的逻辑确定所选区域是源区域还是目标区域。通过显示所选区域的质心来更新地图,并对起点和终点使用不同的颜色。
为了修改页面中已经运行的地图,我们使用了
leafletProxy()
函数来代替*leaflet()*
调用。
通常我们使用leaflet
来创建地图的静态方面,使用leafletProxy
来管理动态元素,这样就可以在点击时更新地图,而不用重新绘制整个地图。关于如何使用该功能的详细信息,请参见 RStudio 网站。
添加输出
现在,我们在 Shiny 应用程序中显示数据,包括几个用于交互式可视化的输出。
output$od_info
对象是无功端点,它使用无功源input$Zone_shape_click
。每当input$Zone_shape_click
改变时,output$od_info
被通知需要重新执行。此输出动态显示选定的源区域和目标区域的名称。
od_info 的输出(图片由作者提供)
我们使用 R package DT 将数据对象(矩阵或数据框)显示为 HTML 页面上的表格。在output$od_vol
中,我们首先通过selected_od()
获取所选始发地和目的地区域的信息,然后过滤od_mode_vol
中存储的 FAF 数据,以获取所选始发地和目的地区域对的结果。
所选始发地和目的地区域对的 FAF 数据比较(图片由作者提供)
除了将查询结果显示为数据表之外,我们还使用条形图和圆环图来显示结果。
作者图片
我们使用renderPlotly()
函数来渲染一个反应式表达式,该表达式根据输入值input$Zone_shape_click
到selected_od()
生成**图形。**
要制作一个圆环图,使用add_pie()
函数的hole=
参数设置要从饼图中切掉的半径的分数。该值可以在0.01
和0.99
之间。
4.免费发布闪亮的应用
Shinyapps.io 是一款软件即服务(SaaS)产品,用于在云中托管闪亮的应用。RStudio 负责托管应用程序和维护服务器的所有细节,因此我们可以专注于编写应用程序。
一个闪亮的应用程序可以在几分钟内部署到 shinyapps.io 上。只要按照这个详细的一步一步的指示就可以了。
Shinyapps.io 提供免费和付费计划。通过免费计划,您可以同时部署多达 5 个闪亮的应用程序,并且每月有多达 25 个小时的活动时间由该帐户下托管的所有应用程序共享。
***https://huajing-shi.medium.com/membership
r 代码和输入数据可从 my GitHub repo 获得。***
参考
使用小部件在 Google Colab 中创建交互式工具
一个 Python 应用程序,可以读取你的每日星象
作者制作的动画
在充满不确定性的时代,你不会想知道未来会怎样吗?让我们在学习如何用 Python 创建一个用户友好的工具来阅读你的每日星座运势的同时,停止担心,找点乐子吧。
作为编码练习,我设想在 Python 笔记本中创建一个交互式工具,如上面的动画所示。用户只需点击按钮,就可以很容易地看到不同的程序输入如何改变输出。
该程序将使用 Google Colab 来实现,以便更容易与最终用户共享,特别是那些没有编码和没有在他们的计算机上安装 Python 的用户。在我的上一篇文章中,我解释了为什么我选择 Google Colab 进行 Python 编程。
程序设计
通过的交互式图形用户界面为用户创造一种身临其境的、有趣的体验,我们可以将静态代码转化为探索的工具,让 Python 笔记本变得生动起来。
Python 中有一个有趣的库叫做 PyAztro ,它提供了太阳星座的星座信息。一旦指定一个标志名称,以及日期类型(“昨天”、“今天"或"明天”),则 pyaztro。Aztro() 函数返回当天所选星座的相关信息,包括幸运数字、幸运颜色、心情、与其他太阳星座的兼容性以及描述等。每日占星读数每天在格林威治时间午夜(格林威治标准时间)更新,所以你每天都有新读数!
用户可以从日期范围标记的星座图像列表中选择一个太阳星座(或星星星座),然后单击与该星座相关的按钮来获得星座读数。
该计划的实施可分为以下几个步骤:
- 安装缺失的 Python 库
- 从网上抓取星座图像
- 创建一个变量来保存星座图像和相应的日期范围
- 生成星座阅读工具的用户界面
这里可以下载笔记本。
程序实现
第一步。在 Google Colab 中安装 Python 库
*!pip install pyaztro*
PyAztro 库默认不安装在 Colab 中,我们需要先安装。要在 Colab 中运行任何命令行脚本,您需要添加一个!在行首。
第二步。从网上抓取星座图像
为了获得标牌图像,我们从 Python 图像库(PIL) 中导入图像*,并调用 Image.open() 来创建来自网站的图像文件的图像对象。使用 Image.open() 接收的图像对象,以后可以应用调整大小、裁剪、绘制或其他图像操作方法调用。***
第三步。创建一个变量来保存星座图像和相应的日期范围
创建一个列表变量来保存每个标志的数据,包括标志名称、图像对象和日期范围。
第四步。生成星座阅读工具的用户界面
**为十二个太阳星座创建了十二个按钮的列表。来自 ipywidgets 的 按钮小部件(也称为 jupyter-widgets 或简称为小部件)用于处理鼠标点击。按钮的 on_click 方法可以用来注册点击按钮时要调用的函数。
点击按钮时,将调用 on_button_clicked() 函数,从 pyaztro 中生成所选星座的星座读数。Aztro() 。循环的用于返回三天中每一天的符号读数,即昨天、今天和明天。**
输出小部件 可以捕获并显示 **IPython 生成的 stdout、stderr 和 rich 输出。**输出可以直接追加或从输出小工具中清除。为了避免在一系列按钮点击后累积输出,我们需要在显示新输出前清除先前的输出。输出小部件是 interact 的基础,因为它构成了如何实现 interact 和相关方法的基础。**
为了让应用程序看起来对用户有吸引力,应用程序的组件(即图像、按钮和文本)的布局是一个需要考虑的重要因素。为了排列十二个标志图像、相应的日期范围和按钮,我们使用Colab 的布局小部件中的 网格 ,这些小部件使能够将未来的输出重定向到布局中的特定位置。图像对象的大小被调整为适合布局。**
这是这个占星阅读程序的界面:
作者图片
****https://huajing-shi.medium.com/membership
源代码:GitHub 上的谷歌可乐笔记本****
本文的灵感来自“蟒蛇的隐藏宝藏”
**** ****
如何基于 Pandas 中其他列的值创建新列
讨论如何从 pandas 数据框架中的现有列创建新列
介绍
作为数据处理或特征工程的一部分,我们通常需要在现有列的基础上创建额外的列。在今天的简短指南中,我们将探索如何在熊猫身上进行这样的操作。
具体来说,我们将探索如何以几种不同的方式实现这一点,使用
apply()
方法numpy.select()
方法(对于矢量化方法)loc
地产
首先,让我们创建一个示例 DataFrame,我们将在整篇文章中引用它来演示一些概念,并展示如何基于现有列的值创建新列。
import pandas as pd
df = pd.DataFrame(
[
(1, 'Hello', 158, True, 12.8),
(2, 'Hey', 567, False, 74.2),
(3, 'Hi', 123, False, 1.1),
(4, 'Howdy', 578, True, 45.8),
(5, 'Hello', 418, True, 21.1),
(6, 'Hi', 98, False, 98.1),
],
columns=['colA', 'colB', 'colC', 'colD', 'colE']
)
print(df)
colA colB colC colD colE
0 1 Hello 158 True 12.8
1 2 Hey 567 False 74.2
2 3 Hi 123 False 1.1
3 4 Howdy 578 True 45.8
4 5 Hello 418 True 21.1
5 6 Hi 98 False 98.1
使用 apply()方法
如果您需要在现有列上应用一个方法,以便计算一些最终将作为新列添加到现有数据框架中的值,那么[pandas.DataFrame.apply()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.apply.html)
方法应该可以做到。
例如,您可以定义自己的方法,然后将其传递给apply()
方法。假设我们想要创建一个名为colF
的新列,它将基于列colC
的值使用下面定义的categorise()
方法创建:
def categorise(row):
if row['colC'] > 0 and row['colC'] <= 99:
return 'A'
elif row['colC'] > 100 and row['colC'] <= 199:
return 'B'
elif row['colC'] > 200 and row['colC'] <= 299:
return 'C'
return 'D'
你需要做的就是将上述方法作为 lambda 表达式传递给apply()
:
df['colF'] = df.apply(lambda row: categorise(row), axis=1)
print(df)
colA colB colC colD colE colF
0 1 Hello 158 True 12.8 B
1 2 Hey 567 False 74.2 D
2 3 Hi 123 False 1.1 B
3 4 Howdy 578 True 45.8 D
4 5 Hello 418 True 21.1 D
5 6 Hi 98 False 98.1 A
对于更简单的操作,您可以将 lambda 表达式直接指定给apply()
方法。例如,假设我们想要创建另一个名为colG
的列,它将把列colC
和colE
的值加在一起。以下内容应该可以解决问题:
df['colG'] = df.apply(lambda row: row.colC + row.colE, axis=1)
print(df)
colA colB colC colD colE colF colG
0 1 Hello 158 True 12.8 B 170.8
1 2 Hey 567 False 74.2 D 641.2
2 3 Hi 123 False 1.1 B 124.1
3 4 Howdy 578 True 45.8 D 623.8
4 5 Hello 418 True 21.1 D 439.1
5 6 Hi 98 False 98.1 A 196.1
使用 NumPy 的 select()方法
现在,一种更矢量化的方法(在性能方面可能更好)是使用 NumPy 的select()
方法,如下所述。
同样,假设我们想要创建一个名为colF
的新列,它将基于列colC
的值来创建。这一次,我们将创建一个包含所需条件的列表,而不是定义一个函数。
import numpy as np
conditions = [
np.logical_and(df['colC'].gt(0), np.less_equal(df['colC'], 99)),
np.logical_and(df['colC'].gt(100), np.less_equal(df['colC'],199)),
np.logical_and(df['colC'].gt(200), np.less_equal(df['colC'],299)),
]
然后,我们定义一个额外的列表,其中包含新列将包含的相应值。注意,在下面的列表中,我们不包括默认值D
。
outputs = ['A', 'B', 'C']
最后,我们使用select()
方法来应用条件,并指定当指定的条件都不满足时将使用的默认值。
df['colF'] = pd.Series(np.select(conditions, outputs, 'D'))
print(df)
colA colB colC colD colE colF
0 1 Hello 158 True 12.8 B
1 2 Hey 567 False 74.2 D
2 3 Hi 123 False 1.1 B
3 4 Howdy 578 True 45.8 D
4 5 Hello 418 True 21.1 D
5 6 Hi 98 False 98.1 A
使用 loc 属性
最后,另一个选择是loc
属性,在某些情况下,它可能比apply()
方法更有效。请注意,与我们之前讨论过的解决方案相比,这种方法可能会更加冗长。
df.loc[
np.logical_and(df['colC'].gt(0), np.less_equal(df['colC'], 99)),
'colF'
] = 'A'
df.loc[
np.logical_and(df['colC'].gt(100), np.less_equal(df['colC'], 199)),'colF'
] = 'B'
df.loc[
np.logical_and(df['colC'].gt(200), np.less_equal(df['colC'], 299)),'colF'
] = 'C'
df['colF'].fillna('D', inplace=True)
print(df)
colA colB colC colD colE colF
0 1 Hello 158 True 12.8 B
1 2 Hey 567 False 74.2 D
2 3 Hi 123 False 1.1 B
3 4 Howdy 578 True 45.8 D
4 5 Hello 418 True 21.1 D
5 6 Hi 98 False 98.1 A
最后的想法
在今天的简短指南中,我们讨论了根据现有列的值在 pandas 数据框架中添加新列。具体来说,我们展示了如何在 pandas 中使用apply()
方法和loc[]
属性来实现这一点,如果您对更加矢量化的方法感兴趣,还可以使用 NumPy 的select()
方法。
成为会员 阅读介质上的每一个故事。你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。
你可能也会喜欢
https://medium.com/geekculture/how-to-refine-your-google-search-and-get-better-results-c774cde9901c
用几行代码创建组织图(5 分钟学习)
如何用 R 和 Python 来实现
作者生成
组织结构图非常受欢迎,但创建起来确实令人头疼。创建它们的手动软件既烦人又费时。如果我们只用几行代码就能把它们组装起来,那不是很好吗?
好消息是,只要有正确的数据,你就可以做到,因为组织图是一种特殊类型的图表,称为树或树状图。树是一个图,其中任意两个顶点之间只有一条路径。因为我们拥有使用数据科学语言处理和可视化图表的工具,所以我们可以使用这些工具来创建组织图。在本文中,我将向您展示如何操作,首先使用 R,然后使用 Python。r 有更好的 viz 选项,但是你也可以用 Python 生成一个基本的组织结构图。
为了举例说明,我们将使用 Chinook 开源数据库,您可以在这里下载。下载后解压找到一个叫chinook.db
的文件。这是一个示例数据库,与您在任何组织中找到的数据库没有什么不同,但显然为了演示的目的,它更小更简单。
R 里怎么做
在 R 中,在我们做了一些数据操作之后,我们将通过从数据中创建一个igraph
对象,然后使用令人敬畏的ggraph
包来可视化它。
首先让我们使用RSQLite
包连接到我们的数据库,并查看表格:
library(RSQLite)con <- dbConnect(
drv = RSQLite::SQLite(),
"chinook.db"
)RSQLite::dbListTables(con)## [1] "albums" "artists" "customers" "employees" "genres" "invoice_items"
## [7] "invoices" "media_types" "playlist_track" "playlists" "sqlite_sequence" "sqlite_stat1"
## [13] "tracks"
让我们下载并快速浏览一下employees
表的字段名:
employees <- dbGetQuery(con, "SELECT * FROM employees")
colnames(employees)## [1] "EmployeeId" "LastName" "FirstName" "Title" "ReportsTo" "BirthDate" "HireDate" "Address" "City"
## [10] "State" "Country" "PostalCode" "Phone" "Fax" "Email"
您能看到我们如何使用ReportsTo
列来形成组织图的基础吗?事实上,我们从这个数据库中需要做的就是EmployeeId
和ReportsTo
字段,但是我们也将使用FirstName
使它更友好(假设它们都是唯一的)。
library(dplyr)
(emps <- employees |>
dplyr::select(EmployeeId, FirstName, ReportsTo))## EmployeeId FirstName ReportsTo
## 1 1 Andrew NA
## 2 2 Nancy 1
## 3 3 Jane 2
## 4 4 Margaret 2
## 5 5 Steve 2
## 6 6 Michael 1
## 7 7 Robert 6
## 8 8 Laura 6
现在,我们可以使用EmployeeId
和ReportsTo
对表本身进行连接,以创建一个在图表中使用的报告关系边列表:
(edgelist <- emps |>
dplyr::inner_join(
emps,
by = c("EmployeeId" = "ReportsTo")
) |>
dplyr::select(from = FirstName.x, to = FirstName.y))## from to
## 1 Andrew Nancy
## 2 Andrew Michael
## 3 Nancy Jane
## 4 Nancy Margaret
## 5 Nancy Steve
## 6 Michael Robert
## 7 Michael Laura
现在我们已经拥有了在igraph
中创建图形对象所需的一切:
library(igraph)
(orgchart <- igraph::graph_from_data_frame(
edgelist
))## IGRAPH e155618 DN-- 8 7 --
## + attr: name (v/c)
## + edges from e155618 (vertex names):
## [1] Andrew ->Nancy Andrew ->Michael Nancy ->Jane Nancy ## ->Margaret Nancy ->Steve Michael->Robert
## [7] Michael->Laura
不错!最后一步是想象它。您可以使用树状图布局、肘形边和节点标签用ggraph
创建一个漂亮的可视化:
library(ggraph)
ggraph(orgchart, layout = "dendrogram") +
geom_edge_elbow() +
geom_node_label(aes(label = name), fill = "lightblue") +
theme_void()
作者生成的图像
用 Python 怎么做
要连接到chinook
并获取员工详细信息:
import sqlite3, pandas as pd
con=sqlite3.connect('chinook.db')qry="""
SELECT EmployeeId, FirstName, ReportsTo
FROM employees
"""emps=pd.read_sql(qry, con)## EmployeeId FirstName ReportsTo
## 0 1 Andrew NaN
## 1 2 Nancy 1.0
## 2 3 Jane 2.0
## 3 4 Margaret 2.0
## 4 5 Steve 2.0
## 5 6 Michael 1.0
## 6 7 Robert 6.0
## 7 8 Laura 6.0
要生成边列表:
edgelist=pd.merge(emps, emps, left_on='EmployeeId', right_on='ReportsTo')edgelist.rename(
columns={'FirstName_x' :'from', 'FirstName_y' :'to'},
inplace=True
)edgelist=edgelist[['from', 'to']]## from to
## 0 Andrew Nancy
## 1 Andrew Michael
## 2 Nancy Jane
## 3 Nancy Margaret
## 4 Nancy Steve
## 5 Michael Robert
## 6 Michael Laura
创建一个networkx
图形对象:
import networkx as nxorgchart=nx.from_pandas_edgelist(edgelist,
source='from', target='to')
Python 对图形可视化的支持肯定比 R 更基本。然而,如果你已经在你的系统上安装了 graphviz(例如brew install graphviz
或sudo apt-get install graphviz
)并且安装了pydot
包,你可以用它来获得一个基本的可视化:
p=nx.drawing.nx_pydot.to_pydot(orgchart)
p.write_png('orgchart.png')
作者生成
最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在 LinkedIn 或Twitter上找我。也可以看看我的博客上的drkeithmcnulty.com或者我的 教科书上的人物分析 。
使用 Gridspec 在 Matplotlib 中创建面板图形布局
Python 科学绘图
使用 gridspec 布局您的图形,而不需要导出多个图形,并使用另一个程序将它们组合在一起
出版物人物通常需要将多个情节放入镶板布局中来讲述一个故事。一种简单的拖放方法是单独创建每个绘图,然后使用图像编辑程序甚至 Powerpoint 将绘图排列成完整的图形并保存为一个图像。这种方法的问题;然而,字体之间大小一致性等。如果您必须继续编辑单个绘图、调整大小和移动以适应您的图形布局,这是很困难的。确保所有单个图形格式一致的一种方法是直接在matplotlib
中创建面板图形,并导出为一个图像。对我们来说幸运的是,有一个强大的工具叫做gridspec
,我们可以用它让matplotlib
为我们做大部分的工作。让我们从创建一个 10 x 10 英寸大小的空白图形开始:
**# Import Libraries** import matplotlib.pyplot as plt
import numpy as np**# Create Blank Figure** fig = plt.figure(figsize=(10, 10))
假设这是我们希望最终从脚本中生成的布局:
我们镶板图形的理想布局
如果我们想利用gridspec
的优势,我们需要将我们的布局简化成一个网格。因此,为了设计布局,我们可以把上面的图想象成一个 4×4 的网格,其中Plot 3
占据了底部的两个正方形。我们可以如下创建这个初始网格:
**# Create 4x4 Grid** gs = fig.add_gridspec(nrows=2, ncols=2)
现在我们有了网格,我们可以创建三个轴对象,对应于上面布局中的三个图。我们可以像索引任何二维数组或列表一样索引gridspec
。注意对于ax3
我们索引gs[1, :]
,这意味着轴对象将跨越第二行和两列。
**# Create Three Axes Objects** ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])
基本 gridspec 布局
在那里!我们有了最初尝试创建的基本布局。当前的布局是使用 4 个大小相等的正方形,它们之间有默认的间距。假设我们想要对布局有更多的控制——我们可以从图中各个图之间的水平和垂直间隙开始,我们可以通过hspace
(高度空间)和wspace
(宽度空间)作为参数。这些关键字参数采用对应于平均轴高度和宽度的一部分的浮点值。
**# Edit gridspec to change hspace and wspace** gs = fig.add_gridspec(nrows=2, ncols=2, hspace=0.5, wspace=0.5)
hspace 和 wspace 值为 0.5 的 Gridspec 布局
如您所见,这些图现在间隔得更远了,因为空间是按平均轴宽和高度的一半来计算的。现在,假设我们实际上希望Plot 1
的宽度是Plot 2
的两倍,而Plot 3
的高度是Plot 1
和Plot 2
的一半。我们可以使用关键字参数height_ratios
和width_ratios
对此进行调整。这两个参数都接受一个浮点数列表,分别描述轴的高度和宽度的比率。
**# Edit gridspec to change height_ratios and width_ratios** gs = fig.add_gridspec(nrows=2, ncols=2, height_ratios=[2, 1], width_ratios=[2, 1])
height_ratios 和 width_ratios 已更改的 Gridspec 布局
在这里,我们非常简单地创建了具有不同高度和宽度的更复杂的网格布局。现在,让我们使用最后的布局来创建最终的面板图:
**# Styling** plt.style.use("seaborn-darkgrid")
plt.rcParams["font.family"] = "Avenir"
plt.rcParams["font.size"] = 16**# Create Blank Figure** fig = plt.figure(figsize=(10, 10))**# Create 4x4 Grid**
gs = fig.add_gridspec(nrows=2, ncols=2, height_ratios=[2, 1], width_ratios=[2, 1])**# Create Three Axes Objects** ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])**# Dummy Data** x = np.linspace(0, 2*np.pi, 1000)**# Plot Data** ax1.plot(x, np.sin(x))
ax2.plot(x, np.sin(x)**2)
ax3.plot(x, np.sin(x) + np.cos(3*x))**# Set axis labels** ax1.set_ylabel("y", size=20)
ax3.set_xlabel("x", size=20)
ax3.set_ylabel("y", size=20)
最终面板图
我们做到了!我们能够非常简单地使用matplotlib
中的gridspec
来创建我们的面板图形。
结论
这是一个非常基本的介绍,介绍如何使用gridspec
创建带有多个图的面板图形。您可以使用本文中显示的设置来创建一些非常复杂的布局,甚至可以利用在一些网格元素中使用空白地块来创建空间区域。本文中的gridspec.ipynb
笔记本将在这个 Github 资源库中提供。
感谢您的阅读!我感谢任何反馈,你可以在 Twitter 上找到我,并在 LinkedIn 上与我联系,以获取更多更新和文章。
使用 Altair 创建令人惊叹的可视化效果
提高在 Python 中可视化数据的效率
“美将拯救世界。”
- F .陀思妥耶夫斯基
在 Unsplash 上由 corina ardeleanu 拍摄的照片
介绍
你是否曾经在看了 Python 中的可视化后感到沮丧?你有没有想过用更少的努力和时间可以做得更好?如果是这样,这篇文章非常适合你,因为我想分享一下 Altair 库,它会提高你的工作效率,让你的视觉效果更吸引人。
我想你已经知道可视化对于任何分析是多么重要,以及它如何帮助向更广泛的受众传达和翻译一个想法。此外,可视化数据是探索数据并了解从哪里深入挖掘的第一步。因此,我将使用散点图 重点介绍牛郎星的 基本语法,然后 与您分享一些各种图形 的示例。在此之前,我们先来说说牛郎星,了解一下它为什么这么厉害。
为什么是牛郎星?
牛郎星示例图库(来源于作者)
Altair 是一个声明性的统计可视化库,它使用 Vega 和 Vega-Lite 语法来帮助描述 JSON 格式的可视化的视觉外观和交互行为。
Altair 背后的关键思想是,你声明数据列和可视编码通道之间的链接(例如,x 和 y 轴、颜色、大小等。)并且可视化过程的其余部分由库来处理。因此,它让你有更多的时间关注数据和分析,而不是解释如何可视化数据[1]。
牛郎星的组件
-
数据: 用于可视化的数据帧
-
标记: 您希望数据以何种方式显示(线条、条形、刻度、点)?
-
编码: 数据将如何表示(x 和 y 的位置,颜色,大小)?
-
转换: 在应用可视化之前,您希望如何转换数据(聚集、折叠、过滤等)。)?
-
Scale: 用于在屏幕上输入和渲染数据的功能
-
引导: 图例、x 轴和 y 轴上的记号等视觉辅助。
对于 标记 组件,可以使用以下基本标记属性:
Altair 的文档截图
用散点图理解牛郎星的语法
让我们把我们的手脏,并学习阿尔泰的语法使用散点图。
装置
$ pip install altair vega_datasets
conda 的等效值为
$ conda install -c conda-forge altair vega_datasets
数据
我将使用以下 Vega 数据集:
- data.gapminder()
- 投资数据.股票()
- data.movies()
让我们导入包并查看数据
import pandas as pd
import altair as alt
from vega_datasets import data
Gapminder 数据集
股票数据集
电影数据集
步骤 1:简单散点图
Chart()。让我们使用 Chart() 、 mark_point()。
alt.Chart(df_gm_2005).mark_point().encode(
alt.X(‘life_expect’),
alt.Y(‘fertility’))
简单散点图
第二步:增加互动性
通过在散点图中添加 *interactive()。此外,让我们用 *alt 来定义泡沫的大小。大小)(为地块添加更多信息。
alt.Chart(df_gm_2005).mark_point(filled=True).encode(
alt.X(‘life_expect’),
alt.Y(‘fertility’),
alt.Size(‘pop’)
).interactive()
简单交互散点图
第三步:添加颜色
我们可以通过添加 alt 来改变气泡的颜色。中的颜色()编码为对象。这是伟大的,我们不需要担心每一个国家的每一种颜色,因为牛郎星为你这样做。
alt.Chart(df_gm_2005).mark_point(filled=True).encode(
alt.X(‘life_expect’),
alt.Y(‘fertility’),
alt.Size(‘pop’),
alt.Color(‘country’),
alt.OpacityValue(0.7)
).interactive()
带有彩色气泡的交互式散点图
第 4 步:添加更多信息
我们可以通过在 encode()。
alt.Chart(df_gm_2005).mark_point(filled=True).encode(
alt.X(‘life_expect’),
alt.Y(‘fertility’),
alt.Size(‘pop’),
alt.Color(‘country’),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip(‘country’),
alt.Tooltip(‘fertility’),
alt.Tooltip(‘life_expect’),
alt.Tooltip(‘pop’),
alt.Tooltip(‘year’)]
).interactive()
现在显示每个国家/地区的信息
第五步:让情节充满活力
对于 2005 年的数据来说已经显得惊人了。让我们添加一个酒吧,以改变数据,使绘图动态。
select_year = alt.selection_single(
name=’Select’, fields=[‘year’], init={‘year’: 1955},
bind=alt.binding_range(min=1955, max=2005, step=5)
)alt.Chart(df_gm).mark_point(filled=True).encode(
alt.X(‘life_expect’),
alt.Y(‘fertility’),
alt.Size(‘pop’),
alt.Color(‘country’),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip(‘country’),
alt.Tooltip(‘fertility’),
alt.Tooltip(‘life_expect’),
alt.Tooltip(‘pop’),
alt.Tooltip(‘year’)]
).add_selection(select_year).transform_filter(select_year).interactive()
选择年度的动态可视化
步骤 6:更改大小并添加标题
最后,让我们更改情节的大小并添加一个标题
select_year = alt.selection_single(
name=’Select’, fields=[‘year’], init={‘year’: 1955},
bind=alt.binding_range(min=1955, max=2005, step=5)
)scatter_plot = alt.Chart(df_gm).mark_point(filled=True).encode(
alt.X(‘life_expect’),
alt.Y(‘fertility’),
alt.Size(‘pop’),
alt.Color(‘country’),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip(‘country’),
alt.Tooltip(‘fertility’),
alt.Tooltip(‘life_expect’),
alt.Tooltip(‘pop’),
alt.Tooltip(‘year’)]
).properties(
width=500,
height=500,
title=”Relationship between fertility and life expectancy for various countries by year”
).add_selection(select_year).transform_filter(select_year).interactive()scatter_plot.configure_title(
fontSize=16,
font=”Arial”,
anchor=”middle”,
color=”gray”)
散点图的最终结果
最终的输出看起来很棒,我们可以从这样一个复杂的可视化中得到各种见解。
其他有用的地块与牵牛星
现在,了解了基本的牵牛星的语法,让我们看看其他一些情节。
方框图
box_plot = alt.Chart(df_gm_2005).mark_boxplot(size=100, extent=0.5).encode(
y=alt.Y(‘life_expect’, scale=alt.Scale(zero=False))
).properties(
width=400,
height=400,
title=”Distribution of life expectancy for various countries in 2005 year”
).configure_axis(
labelFontSize=14,
titleFontSize=14
).configure_mark(
opacity=0.6,
color=’darkmagenta’
)box_plot.configure_title(
fontSize=16,
font=”Arial”,
anchor=”middle”,
color=”gray”)
方框图
柱状图
histogram = alt.Chart(df_gm_2005).mark_bar().encode(
alt.X(“life_expect”, bin=alt.Bin(extent=[0, 100], step=10)),
y=”count()”
).properties(
width=400,
height=300,
title=”Distribution of population for various countries in 2005 year”
).configure_axis(
labelFontSize=14,
titleFontSize=14
).configure_mark(
opacity=0.5,
color=’royalblue’
)histogram.configure_title(
fontSize=16,
font=”Arial”,
anchor=”middle”,
color=”gray”)
柱状图
条形图
bar_chart = alt.Chart(df_gm_ir).mark_bar(color=’seagreen’,
opacity=0.6
).encode(
x=’pop:Q’,
y=”year:O”
).properties(
width=400,
height=400,
title=”Population of Ireland”
)text = bar_chart.mark_text(
align=’left’,
baseline=’middle’,
dx=3
).encode(
text=’pop:Q’
)bar_chart + text
条形图
折线图
line_chart = alt.Chart(df_stocks).mark_line().encode(
x=’date’,
y=’price’,
color=’symbol’
).properties(
width=400,
height=300,
title=”Daily closing stock prices”
)line_chart.configure_title(
fontSize=16,
font=”Arial”,
anchor=”middle”,
color=”gray”)
折线图
多个散点图
mult_scatter_plots = alt.Chart(df_movies).mark_circle().encode(
alt.X(alt.repeat(“column”), type=’quantitative’),
alt.Y(alt.repeat(“row”), type=’quantitative’),
color=’Major_Genre:N’
).properties(
width=150,
height=150
).repeat(
row=[‘US_Gross’, ‘Worldwide_Gross’, ‘IMDB_Rating’],
column=[‘US_Gross’, ‘Worldwide_Gross’, ‘IMDB_Rating’]
).interactive()mult_scatter_plots
多个散点图
最后的想法
牛郎星是一个伟大的工具,以提高你的生产力可视化数据,在那里你只需要指定数据和可视化编码通道之间的链接。这样你就可以把你的思想直接放在一个情节上,而不用担心耗时的“如何”部分。
有关详细信息,请参阅
- 我的 Jupyter 笔记本用于博客帖子
- 官方文件附有各种地块的示例画廊。
感谢您的阅读,请在下面评论您对使用 Altair 可视化数据的想法。要查看我的更多帖子,请订阅 Medium 和 LinkedIn 。
参考
- 总览页面。概述— Altair 4.1.0 文档。(未注明)。https://altair-viz.github.io/getting_started/overview.html.
用 Python 创建具有异常特征的合成时间序列
行业笔记
一种简单而直观的方式来创建带有定制异常的合成(人工)时间序列数据,特别适合工业应用。
图片来源:作者用 Pixabay (免费使用)图片创作
为什么要合成时间序列?
正如我在被大量引用的文章中所写的,合成数据集是以编程方式生成的数据的存储库。所以,它没有被任何现实生活中的调查或实验所收集。因此,它的主要目的是足够灵活和丰富,以帮助 ML 从业者用各种分类、回归和聚类算法进行有趣的实验。
合成时间序列也不例外,它可以帮助数据科学家试验各种算法方法,并为现实生活中的部署做准备,而这种部署方式仅使用真实数据集是不可能的。
工业环境中的时间序列数据
在现代工业环境中,时间序列分析有各种丰富的应用,大量的传感器正在从机器、工厂、操作员和业务流程中创建永无止境的数字数据流。
压力。温度。电动部件的振动和加速度。质检数据。操作员操作日志。
数字从未停止过。这是工业 4.0 或智能工厂时代的新规范。虽然结构化和半结构化数据都在增加,但其中许多仍然是来自现代工厂中嵌入的所有测量抽头的各种各样的时间序列(或类时间序列)数据。
https://metrology.news/factory-2030-the-coming-of-age-of-the-smart-factory/
图片来源 : Pixabay (免费使用)
异常检测至关重要
大多数时候,它们是“正常”、“在范围内”、“符合预期”。但在极少数情况下,他们不是。这就是你需要注意的地方。这些是正常数据流中的“异常”,它们需要被捕获、分析并采取行动——几乎总是实时的。
这些数据流中的异常检测是所有现代数据分析产品、服务和初创公司的面包和黄油。他们正在使用各种方法,从经过试验和测试的时间序列算法到最新的基于神经网络的序列模型,来检测这些异常信号,并根据业务逻辑的要求发出警报或采取行动。
在现代工业环境中,时间序列分析有各种丰富的应用,大量的传感器正在创建一个永无止境的数字数据流…
合成数据生成是一个强大的辅助工具
关于这些工业数据流,有几点值得重复,以理解为什么合成时间序列的生成可能会非常有用。
- 现实生活中的异常是罕见的,人们需要监控和处理大量数据来检测各种有趣的异常。对于想要在短时间内测试和重新测试一系列算法的数据科学家来说,这不是一个好消息。
- 异常的出现是如此不可预测,以至于它们的模式很难在任何全面的统计分布中被捕捉到。对大量异常类型进行快速实验对于生产健壮可靠的异常检测系统至关重要。在缺乏常规、可靠的异常数据来源的情况下,合成方法提供了实现某种受控实验的唯一希望。
- 许多工业传感器生成的数据被认为是高度保密的,不允许超出本地私有云或现有的边缘分析系统。为了再现异常特征而不损害数据安全性,合成方法是显而易见的选择。
这些是正常数据流中的“异常”,它们需要被捕获、分析并采取行动——几乎总是实时的。
在本文中,我们展示了一种简单而直观的方法,在模拟工业过程的一维合成时间序列数据中创建一些常见类型的异常特征。我们会为此使用大家最喜欢的 Python 语言。
注意:这不是一篇关于异常检测算法的文章。我只讨论与合成生成注入异常的时间序列数据相关的思想和方法(集中在一个特定的应用领域)。
有异常的合成时间序列
这里是 Jupyter 笔记本 这里是带主类对象的 Python 模块供你玩。
工业过程和“单位过程时间”的概念
图片来源:作者创作
上面,我们展示了一个典型的工业过程和“单位加工时间”的图解。假设一些原材料(图中的 流程 I/P )正在进入一台复杂的机器,而成品(图中的 流程 O/P )正在从另一端出来。
我们不需要知道机器内部到底发生了什么,只需要知道它会定期生成一些数据,也就是说,我们可以以时间序列的方式测量过程的状态(也许使用一些传感器)。我们想看看这个数据流,发现异常。
因此,要定义我们的合成时间序列模块,我们至少需要以下内容:
- 流程开始时间
- 流程结束时间
- 单位处理时间(我们接收数据的时间间隔)
因此,基类SyntheticTS
的定义就是这样开始的,
“正常”过程
要产生异常,我们需要一个正常的基线。我们可以用“正态分布”来解释这一点。您可以根据您的具体过程类型和情况随时更改它,但绝大多数工业过程的传感器测量值确实遵循正态分布。
假设我们有一个工业流程/机器,从 2021 年 5 月 1 日开始运行,一直运行到 2021 年 5 月 6 日(在每周维护之前,在许多情况下通常运行 6 天)。单位处理时间为 15 分钟。我们选择过程的平均值为 100,标准偏差为 5。
基本的“异常化”方法
作为一种合成数据生成方法,您希望控制异常的以下特征:
- 需要异常的数据部分
- 异常的规模(它们离正常有多远)
- 单边或双边(在数量上高于或低于正常数据)
我们不会为精确的代码而烦恼,而是向您展示一些关键的结果。
单边异常
这里有一个例子,
改变异常尺度
我们可以通过简单地改变anomaly_scale
参数将异常放置在不同的距离。
这是结果图。请注意图的垂直比例是如何变化的,以适应越来越大的异常。
异常的变化部分
接下来,我们更改异常的分数(保持比例不变,为 2.0)。
引入“积极转变”
这在工业过程中是相当常见的情况,其中由于过程/机器设置的突然变化或一些其他原因,在过程中引入了可见的偏移。有时是计划好的,有时是无意的。根据具体情况,异常检测算法可能需要对其进行不同的分析和处理。无论如何,我们需要一种方法在合成数据中引入这样的变化。
在这种情况下,我们选择了 10%的数据偏移,即带有pct_drift_mean=10
参数的平均值。注意,如果我们没有在方法中指定参数time_drift
,那么代码会自动在整个过程的开始和结束时间的中间点引入漂移。
特定位置的负偏移
在下面的例子中,我们展示了一种情况,
- 数据向负方向漂移
- 数据的分布(方差)随着平均值而变化
- 漂移从用户可以选择的特定位置开始
这是比较现实的情况。
块状异常
在许多情况下,异常会成批出现,然后消失。我们也可以综合这种情况。请注意,这里我们创建了“双侧异常”,但与所有其他选项类似,我们也可以创建“单侧”变异。
现在,代码创建了在整个时间段内均匀分布的分块异常。但是这可以在下一次代码更新中用单独的时间点和异常特征来定制。
摘要
我们展示了一种简单直观的方法来创建具有各种异常特征的合成一维时间序列数据,这些异常特征在工业用例中很常见。这种合成数据生成技术对于算法迭代和模型测试非常有用。
保持简单
为了专注于工业用例,我们没有在基线数据生成中添加传统的时间序列模式(如季节性、上升/下降趋势),而是将其保持为极其简单的高斯过程。数据也没有自动回归的性质。尽管 ARIMA 等算法非常受欢迎,对金融和商业数据分析很有帮助,但工业环境中独立传感器生成的数据通常呈正态分布,我们坚持这一原则。
进一步的改进
有很多方法可以在此基础上添加额外的功能。有些可能是,
- 增加了各种统计分布的选择作为基线数据生成过程
- 分块异常的任意位置和特征
- 多个合成数据类/对象的合成方法
- 更好的可视化方法
同样,示例 Jupyter 笔记本在这里。请随意叉和实验。
Y ou 可以查看作者的 GitHub 知识库获取机器学习和数据科学方面的代码、思想和资源。如果你和我一样,对人工智能/机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/
用您的能源数据创造价值
提高数据分析和创造价值的五个步骤
约翰尼·多宾斯通过 Canva.com 获得授权。
最近,我坐在那里惊恐地看着一名控制室性能工程师目测风力涡轮机的数千条功率曲线,以确定性能不佳。她的 tableau 仪表板是她最好的,毫无疑问,她能够做出/一些/影响,但一个 30x30 像素乘以数千的情节只是融入无关紧要的,可能会错过很多机会。
另一次,一名太阳能性能工程师与一名数据科学家合作开发逆变器的可用性分析。这是一种基于“黑盒”机器学习的分析,实际上导致每个逆变器都有问题。一位英国朋友把它描述为“血腥的红色仪表板”,我相信对一个美国人来说,这意味着“疯狂的红色仪表板”,所有的东西都在发出警报;我认为这是血淋淋的,散发着失去机会的恶臭。
这两个轶事代表了我每天从资产经理、运营商和性能工程师那里看到的试图用他们的数据创造价值的大约 80%。
提高精力的五件事数据分析
我想分享我在与能源行业客户合作时学到的五件事:
- 能源生产中的大多数见解都来自数量少得惊人的简单时间序列数据源,包括:状态、警报和传感器数据。大多数人在创造任何价值方面都差得惊人。
- 通常,洞察力是在这些来源的筒仓中形成的。
- 不费吹灰之力,通过打破这些数据孤岛就可以开发出更全面的见解。
- 通过将与资产相关的人类活动产生的额外结构化和非结构化数据纳入其中,洞察价值将远远超过通过简单的传感器观察所产生的价值。
- 最后,理解什么是部落知识以及如何应用它将会增强即使是最基本的分析的洞察力。
让我们更深入地了解一下我在这些问题背后的想法。
来自简单时间序列数据来源的见解缺乏价值
在过去的五年里,我一次又一次地直接接触到从有限的时间序列数据集发展而来的天真见解,这些数据集来自对能源生产资产的传感器观察。
我们通常会看到 SCADA 数据或传感器观测数据,以及状态和运行数据,其处理方式与我在开头描述的类似。这三种结构良好且通常干净的数据类型经过适当分析后可以提供丰富的见解。但是我们怎么做呢?
从识别对组织重要的事情开始;很明显,对吧?你会惊讶于那些实现这些分析的人常常不清楚这些价值。对组织的财务影响可以通过因长期表现不佳、缺乏对可用性损失的了解以及最终完全不了解资产健康和维护需求而导致的能源生产损失来衡量。
通过开发专注于这三个特定领域的分析,然后将其与特定原因相关联,您可以将“血腥的红色仪表板”转化为可操作的见解的明确列表,这些见解通常具有硬价值。
即使使用警报和状态数据,应用一个简单的帕累托方法,您也可以很容易地找出导致组织在运营和财务上最混乱的事情。然而,通常情况下,运营商无法告诉您他们资产上的哪些类型的事件正在影响该资产对组织的价值;这种可见性的缺乏导致了在提供很少价值的领域中的分析开发工作。双重错失的机会。
我发现,通过确定对一个组织影响最大的 5 件事,然后从这 5 件事开始逆向工作以开发分析和见解,会导致彻底的采用和价值。
认识数据孤岛及其对洞察力的影响
当单个资产存在两个或更多数据源并且它们没有被一起分析时,就存在数据竖井。
在能源领域,使用单一时间序列数据源进行分析已经变得司空见惯。数据科学家如此专注于从多年的数据深度中创建模型,以至于他们经常忘记在他们正在处理的单一来源之外进行发现。或者,很有可能,他们甚至不知道其他可用的来源。
由此产生的孤立分析通常不太可行,因此缺乏价值。
想象一下,在对风力涡轮机进行性能分析时,您考虑了环境因素以及发电量,还可能考虑了涡轮机的一些其他传感器观测结果;有了这个,你就可以为涡轮机的性能开发一个有趣的模型。事实上,甚至有关于如何最好地做到这一点的 IEC 标准文件。然而,最终,它只会告诉您,您有一个性能问题,您可能已经知道了,或者至少像我前面描述的工程一样关注了。
类似地,您可能已经对您的涡轮机组中发生的故障进行了帕累托分析,并了解了由于这些故障您在哪些地方失去了最大的可用性。
通过这两个简单的分析,您最终会意识到性能不佳以及特定警报对可用性的影响;这是一个不错的起点,但是,想象一下,如果你结合这两种分析?
打破孤岛,从数据中形成更完整的见解
打破数据孤岛将立即丰富您正在产生的见解,并从数据中创造更多价值。
什么意思?超越单一数据源方法,包括任何可用的额外时间序列数据。将这些传感器观察结果与状态和警报数据合并。
在水平扩展数据的同时保持分析的简单性,这使您能够快速迭代,同时获得更丰富的洞察力,因此在开始时,请坚持使用简单的基于统计的分析。机器学习有它的位置,只是避免它开始。
以上一节的例子为例;您可以运行基于 IEC 的功率曲线分析,同时对故障数据进行帕累托分析。通过结合这两种方法和数据源,您可以立即将损失值分配给警报和警告。此外,你可以开始对不同类型的表现不佳进行分类;有些您可能无法通过维护来影响,而有些您可以。
当你把你的视野缩小到那些你实际上可以影响创造价值的事情上时,那个“血腥的红色仪表板”立刻变成了暗红色。
通过扩展该示例以包括额外的传感器数据,您还将能够识别暗示特定故障的资产数据模式。这使您能够为错过的维护机会甚至由此导致的可用性损失分配价值。
打破你的数据孤岛,摆脱原始设备制造商的“警告”和花哨的软件升级;这两种情况都会阻碍您利用时间序列数据源创造真正的、可能的转换价值。
在未来的帖子中,我将分享数据和 python 的实际例子来演示我所描述的内容。请记住,这是一种纯粹基于统计的方法,您不需要数据科学家或机器学习来完成这一点。
开始包括与资产相关联的人类活动所创建的数据
由人类活动创建的数据通常属于以下类型之一:工作订单、工作日志或检查数据。它也是时间序列,与您的资产生成的传感器、状态和故障数据惊人地吻合。
在您的分析中使用这些数据的挑战通常在于 IT 部门不希望在用于生成数据的应用程序之外提供这些数据。正如 OEM 的情况一样,我发现 it 团队经常因为允许他们管理的数据在他们的组织之外使用而感到威胁。这是一个可悲的事实,数据囤积和保护主义的发生。
然而,一旦您解放了这些数据,它可以为组织增加的价值是巨大的。
以前面的例子为例,您可能已经确定了影响组织底线的 5 大事件。这样,您就可以确定这些事件何时发生,发生在哪些资产上;开始把它和特定的人类活动联系起来。
现在,您可以开始通过改进维护计划来识别价值机会;此外,您可以冲洗相反的地方,在那里维护是低于标准的。想象一下,能够识别重复访问以解决一个持续存在的问题,然后为该问题建立一个更好的维护操作手册?您甚至可以更好地让 OEM 或合同维护团队对他们的工作更加负责。
能源数据分析中包含的群体知识是开发真正洞察力的圣杯
“当我看到这种情况发生时,我通常会这样做,问题就会消失。”
再多的流程图也不能真正抓住维护者在解决问题时使用的逻辑。
我记得我是一名年轻的飞行员,曾多次在美国空军 KC-10A 飞机上担任乘务长,当时的“技术指令”或“流程”文件缺少有效完成维修所需的细节。有一次,我按照文档中的说明一步一步地密封一个灯罩。我设法把这种军用规格的密封剂涂在我和飞机上,弄得一团糟。清理一个 15 分钟的任务需要几个小时。后来,一个长着灰胡子的乘务长把我拉到一边,向我解释了他完成任务的更简单、更干净的方法。他的方法遵循流程,但包括一些来之不易的知识。下一次我必须执行这项任务时,我听从了他的建议,在大约 15 分钟内进出。
这是部落知识。通常通过完成任务的经验学习,并通过口头或工作日志传递。
通过高级自然语言处理(NLP),熟练的分析开发人员与主题专家一起工作,可以开发必要的代码和逻辑来提取这些部落见解。
这有什么用?您已经确定了导致组织价值损失最大的前 5 个事件,现在您可以通过在以前的工作日志中确定具体的事情并将其包括在现有的时间序列数据分析中,将此 NLP 值乘数添加到该事件中。这可能演变成特定的数据模式,需要特定的工具或部件来进行预先调度,或者在已经安排好的停机时间内进行更高效的修复。
我真的做不了 NLP 部落知识提取正义这个通用帖子;在不久的将来,我将回到这一点,并包括一些实际的数据和工作的 python 来做我所描述的事情。
我在职业工程生涯中花了很多时间开发应用程序,帮助人们从他们的数据和内容中获得更多价值。
这方面的经验包括为佛罗里达州的 TBO.com 构建“防飓风”的新闻编辑室应用程序,为国家地理杂志构建“摄影比赛”应用程序,以及在过去的五年中,为运营商开发工具,帮助他们提高能源行业资产的性能和影响力。
导入本
为您的时间序列预测模型创建“不受天气影响”的验证
使用 Python 构建最终时间预测的指南
马尔科·布里托在 Unsplash 上的照片
时间旅行!!—是时候让我们的探索更上一层楼,致力于预测依赖于时间的结果了。时间序列是以时间间隔出现的一系列数据。这些时间间隔可以是每小时、每天、每周或任何可量化的重复持续时间。在一定时间间隔内进行的一系列观察称为时间序列。
预测时间序列处理的是预测下一个周期或在未来参考时间框架内发生的事件观察。
在整个故事中,我们的目标是建立一个对所有问题都理想的时间序列预测。这里的想法是不要为一个问题建立最佳解决方案,而是为大多数问题建立一个可以接近的解决方案。
成功的时间序列所需的重要结构和测试
- 重采样
- 时间序列的平稳性
- ARIMA 和皮拉明德·ARIMA 造型
- 季节性和缺失值插补
- Ad-Fuller (ADF)测试
- 自相关和偏相关
- 格兰杰因果检验
了解时间序列预测的流程
时序预测和分析的逐步流程|作者图片
Panel Data: Panel 是一个基于时间的数据集,除了序列数据之外,还包含一个或多个在某些时间段量化的关联变量。这些因变量有助于为预测“Y”的值提供有价值的见解。
时间序列中的滞后: Lag,作为一个通用的英文术语,指的是较慢的响应时间,通常称为潜伏期。在时间序列预测或分析中,1 到 8 范围内的滞后被认为适用于季度定时数据。对于以月为间隔的时间序列,6、12 或 24 的滞后被认为是合适的。为了更好地理解滞后,让我们看一下这个场景。对于属于时间序列的一组离散值,对于滞后 1,此时间序列将与当前时间序列之前的同一时间序列进行比较。换句话说,时间序列被移动到过去的一个时间段。
了解数据集是时间序列还是面板的一种方法是了解时间列是否是影响预测结果的唯一数据部分。
从下一节开始,我们开始动手(我们编码!!)而且为了简单起见,我在这个故事里只加伪代码。但是,为了能够遍历整个代码,我链接了下面的代码库。这只是一个 Python 笔记本,我建议您跟随这个故事。
1.对时间序列进行重采样
重采样是一种用于改变时间序列观测频率的技术。在 pandas 的数据帧中,重采样方法使这种频率转换变得很方便。所需的先决条件是,对象必须具有 DateTime 数据类型格式(DateTime、DateTimeIndex、PeriodIndex、TimeDeltaIndex 等。).如下所述,存在两种重采样类型。 虽然,在这两种情况下,都必须发明数据。
- 上采样:增加采样数据的频率。例如,将基于分钟的频率更改为秒。
- 下采样:上采样的反过程。例如,将基于天的频率更改为月。
当数据可用的频率与您进行分析的频率不同时,需要进行重采样。
但在最常见的情况下,重采样用于为监督学习算法提供某种程度的附加结构和对机器学习问题的洞察。
# The series module from Pandas will help in creating a time series
from pandas import Series,DataFrame
import seaborn as sns# Before resampling
timeseries_mm = time_series['wind_speed']
timeseries_mm.plot(style='g--')
plt.show()# Resampling the dataset using the Mean() resample method
timeseries_mm = time_series['wind_speed'].resample("A").mean()
timeseries_mm.plot(style='g--')
plt.show()
时间序列重采样前后记录的风速变化|作者提供的图像
2.平稳和非平稳时间序列
平稳性被认为是每个时间序列的一个特征。在平稳序列的情况下,时间序列的值不是时间的函数。
这意味着当前值与过去值的均值、方差和自相关等测量值都是恒定的。平稳的时间序列也不受季节变化的影响。
几乎每一个时间序列都可以通过适当的变换变得平稳。
使时间序列平稳
使用以下提到的任何一种方法都可以使时间序列数据变得平稳:
- 对序列进行一次或多次差分:差分的概念是用当前时间中的序列值减去前一时间单位中同一序列的值,将使其保持不变。也就是说,用当前值减去下一个值叫做差分。
— 比如考虑以下数列:[1,5,2,12,20]。一阶差分给出:[5–1,2–5,12–2,20–12]=[4,-3,10,8]。第二次求差得到:[-3–4,-10–3,8–10]=[-7,-13,-2] - 获取现有时间序列的日志
- 取当前数列的第 n 个根。
- 结合一种或多种上述技术。
为什么平稳时间序列很重要?
平稳的时间序列比较容易预测,也比较可靠。
原因是,预测模型基本上是线性回归算法,利用这些系列数据的滞后来形成预测值。
我们还知道,线性回归算法在预测值(X)彼此不相关的情况下效果最好。使时间序列平稳可消除预测值之间的所有和任何持续的自相关,从而使序列更适合回归分析。一旦序列的滞后或预测因子是独立的,预测就有望给出可靠的预测。
*** 下节中的 Ad-Fuller 测试将测试系列的稳定性。*
3.ARIMA 和皮拉明德·ARIMA 造型
统计学和经济学领域的通用术语,**【自回归综合移动平均线(ARIMA)】**用于描述移动平均线构造。他们对建立时间序列预测模型产生了浓厚的兴趣。
ARIMA 模型适用于输入数据在均值意义上显示非平稳性的证据,但没有观察到显著差异的情况。
我们可以将 ARIMA 的定义分解如下,ARIMA 的 AR 部分代表一个进化变量,它根据自身滞后(旧值)进行回归。MA 部分显示回归误差,它是过去不同时间出现的误差项的线性组合。剩下的“I”(积分)表示数据被当前值和先前值之间的差异所取代。这些单独的过程可能需要执行多次。每个功能的目的都是使模型尽可能符合数据。
来自 Python 文档 — Pyramid 是一个严肃的统计 Python 库,只有一个目标:将 R 的 auto.arima 功能引入 Python。金字塔的运作方式是将 statsmodels.tsa.ARIMA 和stats models . TSA . statespace . sarimax包装到一个估算器类中,并为熟悉 scikit-learn 的程序员创建一个更加用户友好的估算器界面。
pmdarima 最初被称为 pyramid-arima,是一个统计库,有助于填补 Python 时间序列中的数据空白。它包含一组用于检查平稳性和季节性的统计测试。还包括时间序列差分和逆差分等功能。
# Predicting Wind Speeds using "pmdarima" package in Pythonfrom pmdarima.arima import auto_arima
from pmdarima.arima import ADFTesttrain=df[:1300]
test=df[-250:]
plt.figure(figsize=(15,10))adf_test=ADFTest(alpha=0.05)
adf_test.should_diff(time_series_train["wind_speed"])
df = time_series_train["wind_speed"]model = auto_arima(train,start_p=0,d=1,start_q=0,max_p=5,max_d=5,max_q=5, start_P=0,D=1, start_Q=0, max_P=5,max_D=5,max_Q=5, m=12,seasonal=True,error_action='warn',trace=True,supress_warnings=True,stepwise=True,random_state=20,n_fits=50)plt.plot(train)
plt.plot(test)
plt.autoscale()
使用 pmdarima 风速模型预测的数据部分(橙色)|图片由作者提供
4.季节性和缺失值插补
时间序列数据的季节性是指在小于一年的特定时间间隔内出现的变化。这些时间间隔可以是每小时、每月、每周或每季度。天气或气候变化等各种因素会导致季节性。
造成季节性的模式总是循环的,并以周期性模式出现。
对于工作依赖于这些变化的企业来说,如股票市场、劳工组织等,理解季节性是很重要的。季节性变化有几个研究的理由和意义:
- 对数据集季节性影响的解释提供了对季节性变化对数据影响的详细理解。
- 一旦一个季节模式被建立,重要的方法可以被用来从时间序列中消除它。这将有助于研究数据集其他不规则成分的影响。去季节性是消除季节性的概念。
- 季节性和规律性变化的历史模式有助于预测类似数据的未来趋势。例如,气候模式的预测。
处理时间序列内的缺失值
在任何数据集中观察到缺失数据是很常见的。类似地,对于表示时间序列的数据,可以观察到缺少日期或时间的序列。数据总是有可能被捕获并且为零。在这种情况下,需要忽略假阴性。
此外,需要注意的重要一点是,对于时间序列数据,均值或中值插补不是一个好的做法。特别是,如果时间序列没有表现出平稳性。更好、更明智的方法是用该时间段的历史值填充远期数据。
但是,基于对数据的研究和序列的前景,可以尝试多种方法来估算缺失值。以下是一些值得注意的输入缺失时间序列值的常用技术:
- 反向填充
- 线性内插法
- 二次插值法
- 最近邻居的平均值
- 季节性对应平均值
将新值引入数据集后,测量时间序列的性能也很重要。
使用两种或多种方法输入值,然后使用均方根(RMSE)等方法计算模型的精度,这被认为是一种良好的做法。这有助于决定哪种插补技术最适合数据。
5.Ad-Fuller (ADF)测试
扩展的 Dickey-Fuller 检验(ADF),也称为 Ad-Fuller 检验,是时间序列分析的一种重要检验机制。它测试一个基本的零假设,即给定的输入单位根存在于整个时间序列样本中。另一个假设通常是序列的平稳性或趋势平稳性。
在这个测试中主要使用的增强的 Dickey-Fuller(ADF)统计是一个负数。越是否定,对某个置信水平下存在单位根的假设的否定越强。
Ad-Fuller 测试背后的启示是,如果时间序列以单位根过程为特征,那么在这种情况下,序列(y-1)的滞后水平将不会产生任何预测(y)未来变化的相关信息,除了在(y-1)的 delta 中观察到的那些变化。*在这种情况下,零假设不被拒绝。*另一方面,如果现有过程没有单位根,则表明它是稳定的,因此显示出向均值的回归。这里,滞后水平将提供预测未来变化的相关信息。
# Statsmodel and Adfuller will help in testing the stationarity of the time series
import statsmodels
from statsmodels.tsa.stattools import adfuller# Decomposing the time series with Statsmodels Decompose Method
from statsmodels.tsa.seasonal import seasonal_decompose
sd_1 = seasonal_decompose(time_series_train["meantemp"])
sd_2 = seasonal_decompose(time_series_train["humidity"])
sd_3 = seasonal_decompose(time_series_train["wind_speed"])
sd_4 = seasonal_decompose(time_series_train["meanpressure"])
sd_1.plot()
sd_2.plot()
sd_3.plot()
sd_4.plot()
所有列的季节性分解|按作者分类的图像
# From the above graph’s observations, it looks like everything other than meanpressure is already stationary
# To re-confirm stationarity, we will run all columns through the ad-fuller testadfuller(time_series_train["meantemp"])
adfuller(time_series_train["humidity"])
adfuller(time_series_train["wind_speed"])
adfuller(time_series_train["meanpressure"])# Consolidate the ad-fuller tests to test from static data
temp_var = time_series_train.columns
print('significance level : 0.05')
for var in temp_var:
ad_full = adfuller(time_series_train[var])
print(f'For {var}')
print(f'Test static {ad_full[1]}',end='\n \n')***>>> significance level : 0.05
>>> For meantemp Test static 0.2774121372301611
>>> For humidity Test static 0.004470100478130758
>>> For wind_speed Test static 0.0025407221531464
>>> For meanpressure Test static 0.0***
通过 ad-fuller 检验,我们现在可以得出结论,所有数据都是静态的,因为静态检验低于显著性水平。这也否定了平均压力不是静态的假设。
6.自相关和偏相关
自相关:序列与其滞后时间的相关性称为自相关。就像相关性测量两个变量之间线性关系的大小一样,自相关在时间序列的滞后值之间也是如此。如果时间序列有很大的自相关性,这意味着滞后对时间序列预测的影响很大。更一般地说,相关因子 1(滞后= 1)表示彼此相隔一个周期的值之间的相关性。同样,滞后“k”自相关显示了彼此独立的“k”个时间段的值之间的关联。
**偏相关:**偏相关的目的也类似于自相关,因为它传达了关于变量及其滞后之间关系的信息。但是部分自相关仅提供滞后之间的纯关联的细节,而忽略了中间滞后产生的相关性。
# Plotting the test data with auto correlation
from statsmodels.graphics.tsaplots import plot_acf# The next 6 periods of mean temperature (graph 1) and wind_speed (graph 2)
plot_acf(df_forecast["meantemp"])
plot_acf(df_forecast["wind_speed"])
平均温度和风速的自相关|图片作者
7.格兰杰因果检验
格兰杰因果关系检验有助于通过分析相似的时间序列来理解时间序列的行为。
该测试假设,如果一个事件 X 导致另一个事件 Y 的发生,那么基于前面的 Y 和 X 的组合值的 Y 的未来预测应该超过单独基于 Y 的 Y 的预测。
因此,这里需要注意的是,格兰杰因果关系不应该在事件 Y 的滞后导致 Y 的情况下使用。
带有 PyPi 的 statsmodel 包实现了格兰杰因果关系检验。该方法接受一个有两列的二维数组作为其主参数。第一列包含值,第二列包含预测值(X)。这里的零假设是,属于第二列的序列不会导致属于第一列的序列出现。 如果 P 值小于预定义的显著性水平 0.05,则拒绝零假设。这也得出结论,X 的滞后是有用的。 第二个参数*“maxlag”*允许您输入 Y 需要包含在测试中的最大滞后数。
# Import Granger Causality module from the statsmodels package and use the Chi-Squared test metric
from statsmodels.tsa.stattools import grangercausalitytests
test_var = time_series.columns
lag_max = 12
test_type = 'ssr_chi2test'causal_val = DataFrame(np.zeros((len(test_var),len(test_var))),columns=test_var,index=test_var)
for a in test_var:
for b in test_var:
c = grangercausalitytests ( time_series [ [b,a] ], maxlag = lag_max, verbose = False)
pred_val = [round ( c [ i +1 ] [0] [test_type] [1], 5 ) for i in range (lag_max) ]
min_value = np.min (pred_val)
causal_val.loc[b,a] = min_value
causal_val
作者图片
格兰杰因果关系的结果证明了这些特征之间的密切相关性。
结论
时间序列是一个巨大的主题,包括本章没有讨论的各种其他奇点,这应该被认为是这一领域研究的开始。分析从研究时间序列数据开始,了解平稳性,测试季节性,建立预测模型,最后进行时间预测。这个故事的目的是强调可以建立一个可持续的和健壮的时间序列预测模型的关键结构。如果需要的话,请随意浏览下面的参考资料部分,以获得各个主题的详细解释。另外提醒一下,我建议您在阅读本文的同时阅读上面链接的代码库。
通读几个比较有趣的机器学习教程
关于我
我是 Rahul,目前在研究人工智能,在 Xbox 游戏上实现大数据分析。我在微软工作。除了专业工作之外,我还试图制定一个程序,来理解如何通过使用人工智能来改善世界上发展中国家的经济状况。
我现在在纽约的哥伦比亚大学,你可以通过 LinkedIn 和 Twitter 与我联系。
[参考文献]
- https://www . statistics solutions . com/free-resources/directory-of-statistical-analyses/time-series-analysis/
- https://towards data science . com/the-complete-guide-to-time-series-analysis-and-forecasting-70d 476 bfe 775
- https://en . Wikipedia . org/wiki/auto regressive _ integrated _ moving _ average
- https://machine learning mastery . com/ARIMA-for-time-series-forecasting-with-python/
- https://otexts.com/fpp2/arima.html
- https://towards data science . com/taking-consideration-for-time-series-analysis-4 E1 F4 fbb 768 f
- https://www . first intuition . co . uk/fihub/time-series-analysis/