【数据挖掘】如何为可视化准备数据

news2024/10/6 2:21:45

一、说明

        想要开始您的下一个数据可视化项目吗?首先与数据清理友好。数据清理是任何数据管道中的重要步骤,可将原始的“脏”数据输入转换为更可靠、相关和简洁的数据输入。诸如Tableau Prep或Alteryx之类的数据准备工具就是为此目的而创建的,但是当您可以使用Python等开源编程语言完成任务时,为什么要在这些服务上花钱呢?本文将指导您完成使用 Python 脚本为可视化准备数据的过程,为数据准备工具提供更具成本效益的替代方案。

摄影:Robert Katzki on Unsplash

二、数据清洗概说

注意:在本文中,我们将重点介绍如何让 Tableau 为数据可视化做好准备,但主要概念同样适用于其他商业智能工具。

        我明白了。数据清理似乎是将可视化或仪表板变为现实的漫长过程中的又一步。但这是至关重要的,而且可以令人愉快。这是您通过深入了解您拥有和没有的数据以及为实现最终分析目标而必须采取的相应决策来适应数据集的方式。

        虽然 Tableau 是一种多功能的数据可视化工具,但有时获得答案的途径并不明确。在这里,在将数据集加载到 Tableau 之前对其进行处理可能是您最大的秘密帮手。让我们探讨一下为什么在将数据清理与 Tableau 集成之前,数据清理是有益的一些关键原因:

  • 消除不相关的信息: 原始数据通常包含不必要或重复的信息,这些信息可能会使您的分析混乱。通过清理数据,您可以消除浪费,并将可视化集中在最相关的数据功能上。
  • 简化数据转换:如果您对要生成的可视化有清晰的认识,那么在将数据加载到 Tableau 之前执行这些预转换可以简化流程。
  • 团队内部更易于转移:定期更新数据源时,新增数据源可能会带来不一致,并可能破坏 Tableau。借助 Python 脚本和代码描述(更正式地称为 markdown 文档),您可以有效地共享和授权其他人理解您的代码并解决可能出现的任何编程问题。
  • 节省数据刷新时间: 需要定期刷新的数据可以从利用 Hyper API 中受益,Hyper API 是一个生成特定于 Tableau 的 Hyper 文件格式的应用程序,允许自动上传数据提取,同时提高数据刷新过程的效率。

现在我们已经介绍了准备数据的一些优点,让我们通过创建一个简单的数据管道来将其付诸实践。我们将探讨如何将数据清理和处理集成到工作流中,并帮助简化可视化效果的管理。

三、使用 Python 脚本创建数据管道

图片来源:作者

我们的数据过程非常简单:数据清理、视觉对象数据处理,并将其转换为 Tableau 就绪的超级文件以实现无缝集成。

在深入研究我们的工作示例之前,最后一点是,对于 Hyper 文件转换,您需要下载库。此库简化了将 Pandas 数据帧转换为 Tableau .hyper 数据提取的过程。您可以通过在所选环境的终端中使用以下代码轻松完成此操作(对于那些不太熟悉环境的人来说,这是一篇关于它们是什么以及如何安装某些库的很棒的入门文章):pantab

#run the following line of code to install the pantab library in your environment
pip install pantab

四、教程:使用 Python 进行数据准备(探索加拿大的电动汽车牌照)

        我们将根据加拿大统计局的政府可用数据,专注于不同电动汽车制造商和车型的受欢迎程度。

重要的是要注意,这建立在我之前的文章中使用的数据集之上:使用R进行电动汽车分析。如果您有兴趣了解数据集的初步探索以及所做决策背后的基本原理,请参阅它以获取更多详细信息。本教程重点介绍如何构建 Python 脚本,在初始输入之后的每一步中,我们将每个 Python 脚本的输出保存到各自的文件夹中,如下所述:

图片来源:作者

        文件夹过程可确保管道井井有条,并且我们能够记录项目中每个输出。让我们开始构建我们的第一个 Python 脚本!

4.1 数据清理

        管道中的初始脚本遵循数据清理的基本步骤,对于此数据集,这些步骤包括:保留/重命名相关列、删除 null 和/或重复项,以及使数据值保持一致。

        我们可以从指定输入文件位置和输出文件的目的地开始。此步骤很重要,因为它允许我们在同一位置组织文件的不同版本,在这种情况下,我们每月修改文件输出,因此每个文件输出按月分隔,如文件名末尾所示:2023_04

#import necessary packages
import pandas as pd 
import os.path as path

inputfile = "Data/prep_tableau/input/izev-april-2023.csv" 
outputfile = 'clean_data/clean_data_2023-04.csv'

        以下代码读取原始.csv输入,并定义我们要保留的列。在这种情况下,我们有兴趣保留与所购买车型类型相关的信息,而忽略与汽车经销商或任何其他不相关的列。

# read in the data
df = pd.read_csv(inputfile)

# removing certain columns
clean_df = df[df.columns[~df.columns.isin(['Incentive Request Date', 
                                           'Government of Canada Fiscal Year (FY)',
                                           'Dealership Province / Territory '
                                           'Dealership Postal Code','BEV/PHEV/FCEV - Battery equal to or greater than 15 kWh or \nElectric range equal to or greater than 50 km',
                                           'BEV, PHEV  ? 15 kWh or PHEV < 15 kWh (until April 24, 2022) \nand\nPHEV ?  50 km or PHEV < 50 km and  FCEVs ? 50 km or FCEVs < 50 km\n(April 25, 2022 onward)',
                                           'Individual or Organization \n(Recipient)',
                                           'Country'])]]

        现在我们可以缩短列名,删除前导或尾随空格,并添加下划线以便于理解。

# shortening longer column names
clean_df = clean_df.rename({"Battery-Electric Vehicle (BEV), Plug-in Hybrid Electric Vehicle (PHEV) or Fuel Cell Electric Vehicle (FCEV)" : "EV_Type",
                     "Recipient Province / Territory":"Province.Recipient"},axis="columns")

# adding and removing white spaces underscores between column names
clean_df.columns = clean_df.columns.str.strip()
clean_df.columns = clean_df.columns.str.replace(' ', '_')

        接下来,在检查数据集中只有几个空条目后,我们将使用该函数删除空数据。此时,您还希望删除重复项,但对于此特定数据集,我们不会删除。这是因为存在大量重复信息,并且在没有行标识符的情况下,删除重复项将导致数据丢失。.dropna

# removing nulls
clean_df = clean_df.dropna(how="all")

        最后一步是将数据作为.csv文件保存到适当的文件夹位置,该位置将放置在我们共享目录的文件夹中。clean_data

# save to csv
clean_path = path.abspath(path.join(__file__ ,'../', outputfile ))
clean_df.to_csv(clean_path,index=False)

        请注意我们如何使用 引用文件,并使用 bash 命令指定文件目录,其中指示以前的文件夹。我们的数据清理脚本到此结束。现在让我们进入数据处理阶段!__file__../

访问完整的工作代码和组装脚本可以在我的Github存储库中找到。

4.2 可视化的数据处理

        让我们重新审视一下我们试图实现的可视化目标,这些目标旨在突出注册电动汽车普及率的变化。为了有效地展示这一点,我们希望最终的 Tableau 就绪数据集包含以下功能,我们将对这些功能进行编码:

  • 按年份划分的车辆绝对数量
  • 按年份划分的车辆比例
  • 登记车辆增减幅度最大
  • 登记车辆排名
  • 以前注册比较的车辆排名

根据您打算生成的视觉效果,创建理想列可能是一个迭代过程。就我而言,我在构建可视化后包括了最后一列,因为我知道我想为查看者提供排名差异的视觉比较,因此相应地调整了 Python 脚本。

对于以下代码,我们将重点关注模型聚合数据集,因为品牌的其他数据集非常相似。让我们首先定义我们的和:inputfileoutputfile

inputfile = "/Data/prep_tableau/clean_data/clean_data_2023-04.csv"
outputfile = "clean_model/ev_vehicle_models_2023-04.csv" #edit date as needed

        请注意我们如何引用 from 文件夹,这是我们的数据清理脚本的输出。inputfileclean_data

下面的代码读取数据,并创建聚合计数的数据框:Vehicle_Make_and_ModelCalendar_Year

# Read in the data
auto_df = pd.read_csv(inputfile)

# Defining the Dataframe and renaming columns
processed_auto = pd.DataFrame(auto_df.groupby(["Vehicle_Make_and_Model", "Calendar_Year"])["Calendar_Year"].count())
processed_auto = processed_auto.rename(columns={"Calendar_Year": "count"}).reset_index()

        该函数的执行类似于 Excel 中的数据透视表函数,其中它将每个值作为列输入。pivotCalendar_Year

# Pivoting the data based on Vehicle Make and Year with their respective counts
processed_auto_pivot = processed_auto.pivot(index='Vehicle_Make_and_Model', columns='Calendar_Year', values='count').reset_index()

        然后,脚本使用 For 循环来创建输入。这将计算每个模型的比例,以便能够在同一比例上比较每个模型,并为每年创建一个列:per_1K

# Defining column list required for the For Loop
col_list = range(2019, 2024)

# Looking at magnitude every 1000 cars - For loop
for year in col_list:
    column_name = f"per_1K_{year}"
    total_column = year
    processed_auto_pivot[column_name] = round(processed_auto_pivot[total_column] / processed_auto_pivot[total_column].sum(), 4) * 1000
        

        通过按年计算比例,我们可以计算出从 2019 年数据集开始到 2022 年最后一个全年数据的最大增减。

#Calculating prop_num_change
processed_auto_pivot["prop_num_change"] = processed_auto_pivot["per_1K_2022"] - processed_auto_pivot["per_1K_2019"]

        在这里,该函数用于将按年份分隔的列重新透视回行,因此我们只有一列及其关联值。meltper_1Kper_1K

# Pivoting for totals
cars_per1K = pd.melt(
    processed_auto_pivot,
    id_vars=["Vehicle_Make_and_Model", "prop_num_change"],
    value_vars=["per_1K_2019", "per_1K_2020", "per_1K_2021", "per_1K_2022", "per_1K_2023"],
    var_name="year",
    value_name="per_1K"
).loc[:, ["Vehicle_Make_and_Model", "year", "per_1K", "prop_num_change"]

下面的代码允许我们联接绝对计数和我们刚刚创建的其他计算。

# Making year names consistent with processed_auto
cars_per1K["year"]= cars_per1K["year"].str.replace("per_1K_", "")

#joining the total counts with 1K totals
ev_totals = processed_auto.merge(cars_per1K, left_on=["Vehicle_Make_and_Model", "Calendar_Year"], right_on=["Vehicle_Make_and_Model", "year"], how="left")
#dropping irrevelant column
ev_totals = ev_totals.drop("year", axis=1)

现在,我们可以使用许可证计数创建列,并按 和 对这些值进行排序。rankVehicle_Make_and_ModelCalendar_Year

#ranking model by counts
ev_totals['rank'] = ev_totals.groupby('Calendar_Year')['count'].rank(ascending=False, method="min")
ev_totals = ev_totals.sort_values(['Vehicle_Make_and_Model', 'Calendar_Year'])

要创建的最后一列是使用该函数创建的列。previous_rankshift

#creating previous rank, lag by rank
ev_totals['previous_rank'] = ev_totals.groupby('Vehicle_Make_and_Model')['rank'].shift()

最后,我们能够将输出保存到管道中的文件夹路径,为我们提供一个可视化就绪数据集。clean_model

# save to csv
model_path = path.abspath(path.join(__file__ ,'../', outputfile ))
ev_totals.to_csv(model_path,index=False)

作为友情提醒,完整的 python 脚本代码,包括已处理数据集的代码,可以在我的 GitHub 存储库中找到。clean_brand

4.3 将最终数据文件转换为 .hyper 文件格式

        管道的最后一步相对简单,因为我们剩下要做的就是将我们创建.csv处理的文件转换为 .hyper 文件格式。只要您下载了前面提到的库,这应该相对容易。pantab

        值得一提的是,在 Tableau 中,连接的数据既可以实时连接,也可以提取。实时连接可确保数据流持续,来自源的更新几乎立即反映在 Tableau 中。提取的数据涉及 Tableau 创建一个文件扩展名为 .hyper 的本地文件,其中包含数据的副本(可在此处找到数据源的详细说明)。它的主要优点是其快速加载功能,Tableau 可以更有效地访问和呈现信息,这对于大型数据集特别有用。

        超级文件转换脚本的代码从加载和包开始,然后读取 Tableau 所需的数据集。pandaspantabcleaned_model

import pandas as pd
import pantab

#read in files
model_df = pd.read_csv('Data/prep_tableau/clean_model/ev_vehicle_models_2023-04.csv')  

        最后一行代码使用生成 .hyper 文件并将其保存到文件夹中的函数。frame_to_hyper hyper

#save to hyper file
pantab.frame_to_hyper(model_df, "hyper/ev_vehicle_models.hyper", table="rank_vehicle_models")

        最后一步,我们可以通过打开新工作簿轻松地将 .hyper 文件格式加载到 Tableau 中,在该部分中,您可以通过选择 .当我们加载文件时,它应该显示为 Tableau 数据提取,如下面的屏幕截图所示,您的数据已准备好在其上构建视觉对象!select a filemoreev_vehicle_models.hyper

五、结语

        通过将深思熟虑的规划纳入可视化效果,您可以通过创建简单的数据管道来简化仪表板的维护。如果您缺乏资源,请不要担心;像Python这样的开源编码程序提供了强大的功能。最后,作为友好的提醒,要访问Python脚本,请在此处查看我的GitHub存储库。

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

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

相关文章

【ACM】—蓝桥杯大一暑期集训Day4

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前正在学习C/C、Java、算法等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&#xff…

基于STM32的homeassistant(采用FreeRTOS操作系统)【第一、二章优化拓展:Wifi、服务器连接验证以及UASRT串口区分】

第一、二章优化拓展开发环境&#xff1a; 主控STM32F103C8T6WIFI模块ESP01S开发语言C开发编译器 KEIL 组网方式WIFI服务器协议MQTT 硬件连接 STM32ESP01S3.3V3.3V GND GND GPIO2 (USRAT2-TX) RXGPIO3 (USART3-RX)TX 本章要点&#xff1a; 对ESP01S的AT指令的反馈指令进…

集合面试题--HashMap

目录 HashMap实现原理 HashMap的jdk1.7和jdk1.8有什么区别 总结 HashMap的put方法的具体流程 常见属性 添加数据的流程图 ​编辑 具体实现源码 总结 HashMap的扩容机制 总结 hashMap的寻址算法 总结 hashmap在1.7情况下的多线程死循环问题 HashMap实现原理 HashMap的…

MyBatis的多表操作

1 MyBatis的多表操作 1.1 多表模型介绍 我们之前学习的都是基于单表操作的&#xff0c;而实际开发中&#xff0c;随着业务难度的加深&#xff0c;肯定需要多表操作的。 多表模型分类 一对一&#xff1a;在任意一方建立外键&#xff0c;关联对方的主键。 一对多&#xff1a;在…

IDEA 工具- Java - Tomcat 9.x - 无法使用外部 tomcat 服务器的断点测试功能

问题&#xff1a;使用外部 Tomcat 运行项目&#xff0c;却无法使用断点功能测试 Java 项目 解决方法&#xff1a; 在 IDEA 工具的tomcat Edit configurations&#xff0c;进行修改 具体配置位置&#xff1a; Environment Variables 配置选项添加内容&#xff1a; NameValueJ…

Unity游戏源码分享-线条圆圈游戏Line and Circle Game Template

Unity游戏源码分享-线条圆圈游戏Line and Circle Game Template 圆圈穿过线条就通关 工程地址&#xff1a; https://download.csdn.net/download/Highning0007/88061484

java学习路程之篇十、知识点、数组介绍、二维数组介绍、静态初始化、访问元素、遍历元素、动态初始化、内存图、数组常见问题

文章目录 01、数组介绍02、数组静态初始化03、数组元素访问04、数组遍历操作05、数组动态初始化06、数组内存图07、数组常见问题08、二维数组介绍09、二维数组静态初始化10、二维数组遍历11、二维数组动态初始化12、二维数组内存图 01、数组介绍 02、数组静态初始化 03、数组元…

封装 视频以及监控组件

1.引入插件。 文件Git 地址&#xff1a; https://gitee.com/wang-xiaowang123/liveplayer.html 文件中 <script src"/assets/js/liveplayer-lib.min.js" exclude></script> // liveplayer-lib.min.js 文件在Git仓库中2.封装组件 LivePlayerDemo.vue …

php做网页版剪刀石头布的功能

实例讲述了php实现的网页版剪刀石头布攻略在玩游网上的设计。分享给大家供大家参考&#xff0c;具体如下&#xff1a; <?php /* * Created on 2016-11-25 * */ if (isset($_POST[sub])) { $what $_POST[what]; //需要输入的数组 $my_array array("剪刀","…

算法通关村第一关-链表青铜挑战笔记

文章目录 前言一、Java的链表是怎么构造的&#xff1f;单链表的构造简介&#xff1a; 构造链表&#xff1a; 链表增加元素&#xff0c;首部&#xff0c;中间和尾部分别会有什么问题&#xff0c;需要怎么处理&#xff1f;链表的新增在头部添加元素&#xff1a;在中间添加元素&am…

IP库新增多种颜色转换空间IP

颜色空间转换是图像及视频中常用的解决方案&#xff0c;涉及hsv-rgb、rgb-ycrcb等一些常见的颜色空间互相转换&#xff0c;今天带来几种常见的颜色空间转换IP&#xff0c;主要如下&#xff1a; IP库简介 一直想做一个可以供大家学习、使用的开源IP库&#xff0c;类似OpenCores&…

美化图表——LiveCharts中的时序图的制作,相对问题的解决

美化图表——LiveCharts中的时序图的制作&#xff0c;相应问题的解决 前言一、效果展示二、基本的一些实现的代码1.X,Y坐标的相关设置2.新增波形对象3.实时更新数据 三、修改的点总结 前言 在项目中&#xff0c;需要用到图表来展示波形的实时变化&#xff0c;故找到了这个Live…

优维低代码实践:统计视图

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

35.Vue自定义指令-总结

目录 1.自定义指令容易踩的坑 1.1 指令名如果是多个单词&#xff0c;要使用kebab-case命名方式&#xff0c;不要用camelCase命名 1.2 指令回调函数中的this问题 1.3 局部指令与全局指令 2.自定义指令总结 2.1 定义语法&#xff1a; (1).局部指令 (2).全局指令 2.2 配置…

3.14 Bootstrap 缩略图

文章目录 Bootstrap 缩略图添加自定义的内容 Bootstrap 缩略图 本章将讲解 Bootstrap 缩略图。大多数站点都需要在网格中布局图像、视频、文本等。Bootstrap 通过缩略图为此提供了一种简便的方式。使用 Bootstrap 创建缩略图的步骤如下&#xff1a; 在图像周围添加带有 class …

ChatGPT | 修改RetrievalQA推荐答案的数量

知识库经常遇到一个问题会在一个文件的多处或者多个文件出现&#xff0c;这时候如果只回答一个结果就欠佳&#xff0c;最理想的做法是模仿推荐功能&#xff0c;把合适的多个答案及其出处汇总给用户。 如图&#xff0c;一个接口文档里面提到多处“http请求URL”&#xff1a; 使…

vue项目如何部署?有遇到布署服务器后刷新404问题吗?

一、如何部署 前后端分离开发模式下,前后端是独立布署的,前端只需要将最后的构建物上传至目标服务器的web容器指定的静态目录下即可 我们知道vue项目在构建后,是生成一系列的静态文件

Minecraft 1.20.x Forge模组开发 01.Idea开发环境配置

我们本次来进行Minecraft 1.20.x 模组开发环境配置教程的介绍。 效果演示 效果演示 效果演示 1.首先我们需要下载Java17和1.20模组开发包: Java17下载官网

csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板

文章目录 ⭐前言⭐利用inscode免费开放资源&#x1f496; 在inscode搭建vue3tsant项目&#x1f496; 调整配置&#x1f496; antd 国际化配置&#x1f496; 用户store&#x1f496; 路由权限&#x1f496; 预览 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享…

【字节流】读数据(一次读一个字节数组数据)

字节流读数据&#xff08;一次读一个字节数组数据&#xff09; 1.需求&#xff1a; 把文件fos.txt中的内容读取出来在控制台输出 2.思路&#xff1a; 创建字节输入流对象调用字节输入流对象的读数据方法释放资源 package com.bytestream; import java.io.FileInputStream; …