使用 Pandas 进行 JIRA 分析
来源:dev.to
时间:2024-08-30 15:22:40 321浏览 收藏
欢迎各位小伙伴来到golang学习网,相聚于此都是缘哈哈哈!今天我给大家带来《使用 Pandas 进行 JIRA 分析》,这篇文章主要讲到等等知识,如果你对文章相关的知识非常感兴趣或者正在自学,都可以关注我,我会持续更新相关文章!当然,有什么建议也欢迎在评论留言提出!一起学习!
问题
很难说 atlassian jira 是最受欢迎的问题跟踪器和项目管理解决方案之一。你可以喜欢它,也可以讨厌它,但如果你被某家公司聘用为软件工程师,那么很有可能会遇到 jira。
如果您正在从事的项目非常活跃,可能会有数千个各种类型的 jira 问题。如果您领导着一个工程师团队,您可能会对分析工具感兴趣,这些工具可以帮助您根据 jira 中存储的数据了解项目中发生的情况。 jira 集成了一些报告工具以及第三方插件。但其中大多数都是非常基本的。例如,很难找到相当灵活的“预测”工具。
项目越大,您对集成报告工具的满意度就越低。在某些时候,您最终将使用 api 来提取、操作和可视化数据。在过去 15 年的 jira 使用过程中,我看到了围绕该领域的数十个采用各种编程语言的此类脚本和服务。
许多日常任务可能需要一次性数据分析,因此每次都编写服务并没有什么回报。您可以将 jira 视为数据源并使用典型的数据分析工具带。例如,您可以使用 jupyter,获取项目中最近的错误列表,准备“特征”列表(对分析有价值的属性),利用 pandas 计算统计数据,并尝试使用 scikit-learn 预测趋势。在这篇文章中,我想解释一下如何做到这一点。
准备
jira api 访问
这里我们要说的是云版jira。但如果您使用的是自托管版本,主要概念几乎是相同的。
首先,我们需要创建一个密钥来通过 rest api 访问 jira。为此,请转到配置文件管理 - https://id.atlassian.com/manage-profile/profile-and-visibility 如果选择“安全”选项卡,您将找到“创建和管理 api 令牌”链接:
在此处创建一个新的 api 令牌并安全地存储它。我们稍后会使用这个令牌。
jupyter 笔记本
处理数据集最方便的方法之一是使用 jupyter。如果您不熟悉这个工具,请不要担心。我将展示如何使用它来解决我们的问题。对于本地实验,我喜欢使用 jetbrains 的 dataspell,但也有免费的在线服务。 kaggle 是数据科学家中最知名的服务之一。但是,他们的笔记本不允许您建立外部连接以通过 api 访问 jira。另一项非常受欢迎的服务是 google 的 colab。它允许您进行远程连接并安装额外的 python 模块。
jira 有一个非常易于使用的 rest api。您可以使用您最喜欢的 http 请求方式进行 api 调用并手动解析响应。然而,我们将利用一个优秀且非常流行的 jira 模块来实现此目的。
实际使用的工具
数据分析
让我们结合所有部分来提出解决方案。
进入google colab界面并创建一个新笔记本。创建笔记本后,我们需要将之前获得的 jira 凭据存储为“秘密”。单击左侧工具栏中的“密钥”图标打开相应的对话框并添加两个具有以下名称的“秘密”:jira_user 和 jira_password。在屏幕底部,您可以看到如何访问这些“秘密”:
接下来是安装额外的 python 模块以进行 jira 集成。我们可以通过在笔记本单元范围内执行 shell 命令来做到这一点:
!pip install jira
输出应如下所示:
collecting jira downloading jira-3.8.0-py3-none-any.whl (77 kb) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.5/77.5 kb 1.3 mb/s eta 0:00:00 requirement already satisfied: defusedxml in /usr/local/lib/python3.10/dist-packages (from jira) (0.7.1) ... installing collected packages: requests-toolbelt, jira successfully installed jira-3.8.0 requests-toolbelt-1.0.0
我们需要获取“秘密”/凭证:
from google.colab import userdata jira_url = 'https://******.atlassian.net' jira_user = userdata.get('jira_user') jira_password = userdata.get('jira_password')
并验证与 jira cloud 的连接:
from jira import jira jira = jira(jira_url, basic_auth=(jira_user, jira_password)) projects = jira.projects() projects
如果连接正常并且凭据有效,您应该会看到一个非空的项目列表:
[<jira project: key='proj1', name='name here..', id='10234'>, <jira project: key='proj2', name='friendly name..', id='10020'>, <jira project: key='proj3', name='one more project', id='10045'>, ...
这样我们就可以从 jira 连接并获取数据了。下一步是获取一些数据以使用 pandas 进行分析。让我们尝试获取某个项目在过去几周内已解决问题的列表:
jira_filter = 19762 issues = jira.search_issues( f'filter={jira_filter}', maxresults=false, fields='summary,issuetype,assignee,reporter,aggregatetimespent', )
我们需要将数据集转换为pandas数据框:
import pandas as pd df = pd.dataframe([{ 'key': issue.key, 'assignee': issue.fields.assignee and issue.fields.assignee.displayname or issue.fields.reporter.displayname, 'time': issue.fields.aggregatetimespent, 'summary': issue.fields.summary, } for issue in issues]) df.set_index('key', inplace=true) df
输出可能如下所示:
我们想分析一下解决问题通常需要多长时间。人都是不理想的,所以有时他们会忘记记录工作。如果您尝试使用 jira 内置工具分析此类数据,则会带来麻烦。但我们用pandas做一些调整并不是问题。例如,我们可以将“时间”字段从秒转换为小时,并用中值替换缺失的值(注意,如果有很多间隙,dropna 可能更合适):
df['time'].fillna(df['time'].median(), inplace=true) df['time'] = df['time'] / 3600
我们可以轻松地可视化分布以找出异常情况:
df['time'].plot.bar(xlabel='', xticks=[])
查看受让人解决的问题的分布也很有趣:
top_solvers = df.groupby('assignee').count()[['time']] top_solvers.rename(columns={'time': 'tickets'}, inplace=true) top_solvers.sort_values('tickets', ascending=false, inplace=true) top_solvers.plot.barh().invert_yaxis()
它可能看起来像下面这样:
预测
让我们尝试预测完成所有未决问题所需的时间。当然,我们可以在没有机器学习的情况下,通过使用简单的近似和平均时间来解决问题。因此,预计所需时间就是未解决问题的数量乘以解决问题的平均时间。例如,解决一个问题的平均时间为 2 小时,而我们有 9 个未解决的问题,因此解决所有问题所需的时间为 18 小时(近似值)。这是一个足够好的预测,但我们可能知道解决的速度取决于产品、团队和问题的其他属性。如果我们想改进预测,我们可以利用机器学习来解决这个任务。
高级方法如下所示:
- 获取“学习”数据集
- 清理数据
- 准备“特征”,又名“特征工程”
- 训练模型
- 使用模型来预测目标数据集的某些值
第一步,我们将使用过去 30 周的门票数据集。出于说明目的,此处对某些部分进行了简化。在现实生活中,用于学习的数据量应该足够大才能建立有用的模型(例如,在我们的例子中,我们需要分析数千个问题)。
issues = jira.search_issues( f'project = pps and status in (resolved) and created >= -30w', maxresults=false, fields='summary,issuetype,customfield_10718,customfield_10674,aggregatetimespent', ) closed_tickets = pd.dataframe([{ 'key': issue.key, 'team': issue.fields.customfield_10718, 'product': issue.fields.customfield_10674, 'time': issue.fields.aggregatetimespent, } for issue in issues]) closed_tickets.set_index('key', inplace=true) closed_tickets['time'].fillna(closed_tickets['time'].median(), inplace=true) closed_tickets
就我而言,大约有 800 张门票,并且只有两个“学习”字段:“团队”和“产品”。
下一步是获取我们的目标数据集。我为什么这么早做?我想一次性清理两个数据集并进行“特征工程”。否则,结构之间的不匹配可能会导致问题。
issues = jira.search_issues( f'project = pps and status in (open, reopened)', maxresults=false, fields='summary,issuetype,customfield_10718,customfield_10674', ) open_tickets = pd.dataframe([{ 'key': issue.key, 'team': issue.fields.customfield_10718, 'product': issue.fields.customfield_10674, } for issue in issues]) open_tickets.set_index('key', inplace=true) open_tickets
请注意,我们这里没有“时间”列,因为我们想要预测它。让我们取消它并结合两个数据集来准备“特征”。
open_tickets['time'] = 0 tickets = pd.concat([closed_tickets, open_tickets]) tickets
“团队”和“产品”列包含字符串值。处理这个问题的方法之一是将每个值转换为带有布尔标志的单独字段。
products = pd.get_dummies(tickets['product'], prefix='product') tickets = pd.concat([tickets, products], axis=1) tickets.drop('product', axis=1, inplace=true) teams = pd.get_dummies(tickets['team'], prefix='team') tickets = pd.concat([tickets, teams], axis=1) tickets.drop('team', axis=1, inplace=true) tickets
结果可能如下所示:
组合数据集准备完毕后,我们可以将其分成两部分:
closed_tickets = tickets[:len(closed_tickets)] open_tickets = tickets[len(closed_tickets):][:]
现在是时候训练我们的模型了:
from sklearn.model_selection import train_test_split from sklearn.tree import decisiontreeregressor features = closed_tickets.drop(['time'], axis=1) labels = closed_tickets['time'] features_train, features_val, labels_train, labels_val = train_test_split(features, labels, test_size=0.2) model = decisiontreeregressor() model.fit(features_train, labels_train) model.score(features_val, labels_val)
最后一步是使用我们的模型进行预测:
open_tickets['time'] = model.predict(open_tickets.drop('time', axis=1, errors='ignore')) open_tickets['time'].sum() / 3600
最终的输出,就我而言,是 25 小时,这比我们最初的粗略估计要高。这是一个基本的例子。但是,通过使用 ml 工具,您可以显着扩展分析 jira 数据的能力。
结论
有时,jira 内置工具和插件不足以进行有效分析。此外,许多第 3 方插件相当昂贵,每年花费数千美元,而且您仍然很难让它们按照您想要的方式工作。然而,您可以通过 jira api 获取必要的信息,轻松利用众所周知的数据分析工具,并超越这些限制。我花了很多时间使用各种 jira 插件,试图为项目创建好的报告,但它们经常错过一些重要的部分。在 jira api 之上构建工具或功能齐全的服务通常看起来也有些过头了。这就是为什么 jupiter、pandas、matplotlib、scikit-learn 等典型数据分析和 ml 工具在这里可能效果更好。
本篇关于《使用 Pandas 进行 JIRA 分析》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
203 收藏
-
228 收藏
-
379 收藏
-
297 收藏
-
182 收藏
-
322 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习