当前位置: 首页 > news >正文

使用 Python、Elasticsearch 和 Kibana 分析波士顿凯尔特人队

作者:来自 Jessica Garson

大约一年前,我经历了一段压力很大的时期,最后参加了一场篮球比赛。 在整个过程中,我可以以一种我以前无法做到的方式断开连接并找到焦点。 我加入的第一支球队是波士顿凯尔特人队。 波士顿凯尔特人队是一支不同寻常的球队,虽然他们本赛季经常位居 NBA 实力排行榜榜首,但他们只是有时在许多核心指标上领先联盟。

使用数据可视化,我可以更深入地了解这支球队,回答一些有关它的关键问题,并更好地分析赛季。 这篇博文将向你展示如何使用 Python 在 Elastic 中加载数据,使用 Elasticsearch 编写查询,使用 Kibana 创建仪表板。 你可以查看这篇博文的完整代码。

先决条件

本教程使用 Elasticsearch 版本 8.12; 如果你是新手,请查看我们的 Elasticsearch 和 Kibana 快速入门。

如果你的计算机上尚未安装 Python,请下载最新版本。 此示例使用 Python 3.12.1。

你将使用 nba_api 包获取有关波士顿凯尔特人队、Jupyter Notebooks 和 Elasticsearch Python 客户端的最新统计数据。 在测试此代码时,除非安装了 pandas,否则我会收到错误,因为 nba_data 创建 pandas DataFrame。

要安装这些软件包,你可以运行以下命令。

pip3 install nba_api jupyter elasticsearch pandas load_dotenv

你将需要加载 Jupyter Notebook 以交互方式处理你的数据。 为此,你可以在终端中运行以下命令。

export ES_USER=elastic
export ES_PASSWORD=xnLj56lTrH98Lf_6n76yjupyter notebook

在上面,你需要根据自己的 Elasticsearch 设置替换上面的 ES_USER 及 ES_PASSWORD 值。

在右上角,你可以选择 “New” 来创建新的 Jupyter Notebook。

步骤 1:解析和清理波士顿凯尔特人队数据

第一步是连接到 NBA 数据并将该数据加载到 Elasticsearch 中。 你首先需要导入所需的库。 在此示例中,你将使用 nba_api 的静态球队数据来获取有关波士顿凯尔特人队的信息。 leaguegamefinder 端点允许你获取信息。 要连接到 Elastic,你将使用 Elasticsearch Python 客户端 elasticsearch。 

要加载这些包,你可以使用以下代码:

from dotenv import load_dotenv
from nba_api.stats.static import teams
from nba_api.stats.endpoints import leaguegamefinder
from elasticsearch import Elasticsearch, helpers
import osload_dotenv()elastic_user=os.getenv('ES_USER')
elastic_password=os.getenv('ES_PASSWORD')url = f"https://{elastic_user}:{elastic_password}@localhost:9200"
es = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)print(es.info())

你需要从 NBA 球队静态数据集中获取球队数据,其中每个球队都有一个 ID。 你可以使用列表理解来查找波士顿缩写为 BOS 的球队。 获得完整的 Celtics 对象后,你可以将其范围缩小到仅 ID,你可以使用它来查找比赛数据。

nba_teams = teams.get_teams()
celtics = [team for team in nba_teams if team['abbreviation'] == 'BOS'][0]
celtics_id = celtics['id']

现在,你可以使用凯尔特人队的 ID 获取该球队的所有可用比赛数据。 你可以查看前五个结果,以确保使用 .head() 方法正确加载数据。

celtics_games = leaguegamefinder.LeagueGameFinder(team_id_nullable=celtics_id)
games = celtics_games.get_data_frames()[0]
games.head()

在处理这些数据时,我注意到今年的数据包括季前数据。 因此,我使用赛季日期将数据范围缩小到当前赛季。 在 Jupyter Notebook 中,你可以调用 current_season 来查看完整的 DataFrame。

current_season = games.loc[(games['GAME_DATE'] >= '2023-10-24') & (games['GAME_DATE'] <= '2024-06-20')]
current_season

由于空值在将数据加载到 Elasticsearch 时可能会产生问题,因此你可以仔细检查该数据是否没有空值。 下面的行返回一个布尔值,让你知道数据是否有任何空值。 由于该数据集返回 False 值,因此它没有空值,因此我们不必进行进一步的清理。

current_season.isnull().values.any()

第 2 步:将波士顿凯尔特人队数据加载到 Elasticsearch 中

在将数据加载到 Elastic 之前,你必须创建索引。 你可以为当前季节创建一个。

INDEX_NAME = "boston_celtics_current_season"es.indices.create(index = INDEX_NAME)

你可以创建一个函数将当前季节的数据加载到 Elasticsearch 中。 每个 game 都被视为一个文档。

def doc_generator(df, timeframe):for index, document in df.iterrows():yield {"_index": INDEX_NAME, "_id": f"{document['GAME_ID']}","_source": document.to_dict(),}

Python 客户端的帮助程序功能允许你高效地将保存当前赛季比赛数据的 DataFrame 上传到 Elasticsearch。 通过调用刚刚创建的 doc_generator 函数,你可以将 DataFrame 转换为文档。

helpers.bulk(es, doc_generator(current_season, index))
es.indices.refresh(index=index)

第 3 步:使用 Elasticsearch 编写查询

现在你的数据已加载,你可以开始使用 Elasticsearch 编写查询,以了解有关波士顿凯尔特人队本赛季表现的更多信息。 首先,你可以创建一个查询来查看他们本赛季到目前为止已经取得了多少场胜利,并返回胜利的计数结果。

search_query = {"query": {"match": {"WL": "W"}}
}games_won = es.count(index="boston_celtics_current_season", body=search_query)

在处理复杂的数据集时,编写句子来帮助解释数据集有时会很有帮助。 以下是波士顿凯尔特人队本赛季赢得多少场比赛的一个例子。

print(f"The Celtics won {games_won['count']} games this season so far.")

输出应如下所示:

The Celtics won 38 games this season so far.

体育运动中的连胜是指球队或个人连续获胜或失败的一系列连续比赛或赛事。 连胜很重要,因为它们反映了一段时期的出色表现(连胜)或具有挑战性的阶段(连败)。 在分析一支球队的表现时,检查他们有多少连续得分通常是有帮助的。 你可以创建一个查询,允许你按比赛数据对输赢进行排序。

streak_query = {"size": 1000,  "sort": [{"GAME_DATE": {"order": "asc"}}],"_source": ["GAME_DATE", "WL"]
}

你可以使用 es.search() 方法根据上面的查询创建搜索。

streak_search = es.search(index="boston_celtics_current_season",body=streak_query)

以下代码创建一个比赛日期和比赛结果的 JSON 对象。

gs = [hit['_source'] for hit in streak_search['hits']['hits']]

要查看本赛季前五连胜,你可以为每个连胜创建一个字典并进行相应的排序。

streaks = []
current_streak = 1
for i in range(1, len(gs)):if gs[i]['WL'] == gs[i-1]['WL']:current_streak += 1else:streaks.append((gs[i-1]['WL'], current_streak))current_streak = 1streaks.append((gs[-1]['WL'], current_streak))
top_streaks = sorted(streaks, key=lambda x: x[1], reverse=True)[:5]
top_streaks

第 4 步:使用 Kibana 创建仪表板

虽然我们可以继续编写查询来了解有关波士顿凯尔特人队的更多信息,但创建仪表板是从数据中获取见解的更有效方法。

在制作仪表板之前,你需要创建一个数据视图,以确保 Kibana 可以访问 Elasticsearch 索引中的数据。 对于数据视图,你需要为其命名,选择表示要可视化的多个索引的索引或模式,并提供时间戳字段,以便你可以创建基于时间的可视化。

注意:在进行可视化之前,你需要为当前的索引创建一个 data view。

创建数据视图后,你可以开始创建仪表板。 在 “Analytics” 标题下,选择 “Dashboard” 所在的位置,然后单击 “Create Dashboard” 所在的位置。

一个出色的可视化首先是为仪表板创建标题可视化。 你可以选择文本可视化和 Markdown 以将图像添加到标题中。

# ![image](https://1000logos.net/wp-content/uploads/2016/10/Boston-Celtics-Logo.png) How are the Boston Celtics performing this season?

要了解凯尔特人队赢得的比赛是否多于输掉的比赛,你可以创建一个 waffle 图来说明在赛季的此时点,凯尔特人队赢得的比赛多于输掉的比赛。

你可以在此处查看此图表的配置:

保持助攻多于失误是球队有效传球的一个重要指标。 截至本博文发布之日,随附的可视化结果清楚地表明球队在这方面表现良好,展示了熟练的球分配和团队合作。

该可视化的配置如下所示:

篮球比赛中的正负值显示了波士顿凯尔特人队比其他球队多了多少分,这个统计数据经常被用来解释一支球队对比赛的影响。 高分表明球队在比赛时在得分或阻止进球/得分方面往往表现良好。 高负分表明相反的情况 —— 球队往往会被超越。 赛季初,凯尔特人队在一场比赛中比另一支球队多得分超过 50 分,但随着时间的推移,这种情况逐渐正常化。 最近一场对阵密尔沃基雄鹿队的比赛(在撰写本文时)也是一个异常值。

以下是上述可视化的配置。

要了解有关凯尔特人队投篮频率的更多信息,你可以创建一些顶线,包括:

  • 平均投篮命中率是多少?
  • 三分线外的平均投篮命中率是多少?
  • 平均罚球命中率是多少?

这些顶行的配置在 Kibana 中如下所示:

投篮命中率顶线配置:

三分线底线投篮命中率配置:

罚球命中率顶线配置:

最终的可视化检查了凯尔特人队的得分是否会随着抢断和盖帽的增加而增加。 颜色代表盖帽平均值加上抢断平均值。 随着盖帽和抢断数量的增加,绿色会变暗。 然而,数据中缺乏明显的模式表明这些防守行为与其总体得分之间没有显着相关性。

此可视化的配置应如下所示:

结论

通过以这种方式可视化数据,你可以与数据进行稳健的交互并得出进一步的见解。 请务必查看这篇博文的完整代码。 下一步,创建一个数据管道,以编程方式将数据输入仪表板或利用我们的一些机器学习功能,例如异常检测。 你还可以通过添加凯尔特人队的历史数据或将凯尔特人队与 NBA 中的其他球队进行比较来扩展此数据集。 我们希望你可以继续使用 Python、Elasticsearch 和 Kibana。 与往常一样,如果你需要这篇博文激励你构建任何东西,或者你对我们的讨论论坛和社区 Slack 频道有任何疑问,请告诉我们。

更多关于可视化的文章,请参阅文章:

  • Kibana:Kibana 入门 (一)

  • Kibana:Kibana 入门 (二)

  • Kibana:Kibana 入门 (三)

原文:Analyzing the Boston Celtics using Python, Elasticsearch, and Kibana — Elastic Search Labs

相关文章:

使用 Python、Elasticsearch 和 Kibana 分析波士顿凯尔特人队

作者&#xff1a;来自 Jessica Garson 大约一年前&#xff0c;我经历了一段压力很大的时期&#xff0c;最后参加了一场篮球比赛。 在整个过程中&#xff0c;我可以以一种我以前无法做到的方式断开连接并找到焦点。 我加入的第一支球队是波士顿凯尔特人队。 波士顿凯尔特人队是…...

探索C语言结构体:编程中的利器与艺术

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 常量与变量 1. 什么是结构体 在C语言中本身就自带了一些数据类型&#x…...

Git介绍与常用命令总结

Git介绍与其常用命令总结 1、Git介绍2、Git的使用3、Git常用命令3.1 初始化仓库3.2 克隆仓库3.3 配置用户信息3.4 提交代码(Commit)3.5 推送代码(Push)3.6 拉取代码(Pull)3.7 分支(Branch)3.8 远程仓库(Remote)3.9 撤销回退本地改动3.10 更新本地仓库与远程仓库 1、Git介绍 Gi…...

机器学习 | 探索朴素贝叶斯算法的应用

朴素贝叶斯算法是一种基于贝叶斯定理和特征条件独立假设的分类算法。它被广泛应用于文本分类、垃圾邮件过滤、情感分析等领域&#xff0c;并且在实际应用中表现出色。 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法&#xff1a; 1&#xff09;对于给定的待分类项r…...

【无刷电机学习】电流采样电路硬件方案

【仅作自学记录&#xff0c;不出于任何商业目的】 目录 AD8210 INA282 INA240 INA199 AD8210 【AD8210数据手册】 在典型应用中&#xff0c;AD8210放大由负载电流通过分流电阻产生的小差分输入电压。AD8210抑制高共模电压(高达65V)&#xff0c;并提供接地参考缓冲输出&…...

对于协同过滤算法我自己的一些总结和看法

文章目录 协同过滤算法的基本原理协同过滤算法的分类用户相似度计算UserCF && ItemCF应用场景 协同过滤算法的优缺点优点缺点 协同过滤算法的总结与展望Q&A 协同过滤算法的基本原理 关于协同过滤算法&#xff0c;我看过很多老师写的博客以及一些简单的教程&#x…...

数据库管理phpmyadmin

子任务1-PHPmyadmin软件的使用 本子任务讲解phpmyadmin的介绍和使用操作。 训练目标 1、掌握PHPmyadmin软件的使用方法。 步骤1 phpMyAdmin 介绍 phpmyadmin是一个用PHP编写的软件工具&#xff0c;可以通过web方式控制和操作MySQL数据库。通过phpMyAdmin可以完全对数据库进行…...

Oracle数据表ID自增操作

一、Oracle ID自增长功能介绍 Oracle数据库默认不支持像 SQLServer、MySQL中的自增长&#xff08;auto increment&#xff09;功能&#xff0c;即自动为每一行记录的自增长字段生成下一个值。 二、Oracle ID自增长方法 第一种&#xff0c;通过序列&#xff08;sequence&#…...

npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher

当使用npm下载vue3-lazy时出现一下错误时的解决方案 报错&#xff1a;npm WARN deprecated uuid3.4.0: Please upgrade to version 7 or higher 尝试使用过一下命令更新 npm install uuidlatest -g 是安装了最新版本的uuid&#xff0c; 再次下载已解决问题 ***但看某些播客依…...

第2节、让电机转起来【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍用简单的方式&#xff0c;让步进电机转起来。其目的之一是对电机转动有直观的感受&#xff0c;二是熟悉整个开发流程。本系列教程必要的51单片机基础包括IO口操作、中断、定时器三个部分&#…...

1154: 第多少天

题目描述 定义一个包括年、月、日的结构体变量&#xff0c;读入年、月、日&#xff0c;计算该日在当年中是第几天。注意闰年问题。 输入描述 三个整数&#xff0c;分别表示年、月、日。保证输入是实际存在的日期&#xff0c;且年份在1000至3000之间&#xff08;包含1000和30…...

【C语言初阶-const作用详解】const修饰变量、const修饰指针(图文详解版)

少年&#xff0c;做你认为对的事 目录 少年&#xff0c;做你认为对的事 1.const修饰变量 2.const修饰指针&#xff08;重要&#xff09; 代码1&#xff1a; 代码2&#xff1a; 代码3&#xff1a; ​编辑 3.结论 1.const修饰变量 const修饰变量将变量赋予了常量属性…...

线程协作工具类【CountDownLatch倒数门闩、Semaphore信号量、CyclicBarrier循环栏栅、Condition接口】

线程协作工具类 CountDownLatch倒数门闩Semaphore信号量CyclicBarrier循环栅栏CyclicBarrier和CountDownLatch区别: Condition接口(条件对象) 转自 极客时间 线程协作工具类就是帮助程序员更容易的让线程之间进行协作&#xff0c;来完成某个业务功能。 CountDownLatch倒数门闩…...

Python 函数式编程进阶:map、filter、reduce

Python 函数式编程进阶&#xff1a;map、filter、reduce 介绍map 函数作用和语法使用 map 函数Lambda 函数的配合应用 filter 函数作用和语法使用 filter 函数Lambda 函数的结合运用 reduce 函数作用和语法使用 reduce 函数典型应用场景 介绍 在函数式编程中&#xff0c;map、…...

大模型|基础_word2vec

文章目录 Word2Vec词袋模型CBOW Continuous Bag-of-WordsContinuous Skip-Gram存在的问题解决方案 其他技巧 Word2Vec 将词转化为向量后&#xff0c;会发现king和queen的差别与man和woman的差别是类似的&#xff0c;而在几何空间上&#xff0c;这样的差别将会以平行的关系进行表…...

14.2 url后端过滤器(❤❤)

14.2 过滤器 1. 过滤器Filter1.1 配置形式实现过滤器1.2 过滤器生命周期1.3 过滤器特性(面试点)1.4 注解形式实现过滤器1.5 两种实现的选择2. 应用2.1 字符集过滤:统一设置请求与响应字节编码1. 配置方式实现过滤器参数化:init-param标签关键代码完整代码2. 注解方式实现2.2 多…...

Leetcode 377 组合总和 Ⅳ

题意理解&#xff1a; 给你一个由 不同 整数组成的数组 nums &#xff0c;和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 这道题目和凑零钱是一样的&#xff0c;需要求使用指定元素&#xff08;纸币…...

CleanMyMacX4.14.6如何清理mac垃圾内存

一直以来&#xff0c;苹果电脑的运行流畅度都很好&#xff0c;但是垃圾内存多了磁盘空间慢慢变少&#xff0c;还是会造成卡顿的。这篇文章就告诉大家电脑如何清理垃圾内存&#xff0c;电脑如何清理磁盘空间。 一、电脑如何清理垃圾内存 垃圾内存指的是各种缓存文件和系统垃圾…...

Java 学习和实践笔记(1)

2024年&#xff0c;决定好好学习计算机语言Java. B站上选了这个课程&#xff1a;【整整300集】浙大大佬160小时讲完的Java教程&#xff08;学习路线Java笔记&#xff09;零基础&#xff0c;就从今天开始学吧。 在这些语言中&#xff0c;C语言是最基础的语言&#xff0c;绝大多…...

【自然语言处理-工具篇】spaCy<1>--介绍及安装指南

目录 前言 安装指南 pip conda spaCy升级 总结 前言 spaCy是一个开源的自然语言处理库,用于处理和分析文本数据。它提供了许多功能,包括分词、词性标注...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...