跳至主要内容

使用 Python 与 Tableau 进行数据可视化教程

了解如何使用 Python 拓展 Tableau 的数据可视化能力。
· 15分钟 阅读

使用 AI 探索

Python Tableau Tutorial

为何将 Python 与 Tableau 搭配使用

Tableau 提供多种方式来扩充并创建新的数据字段。您可以使用计算字段执行算术、逻辑、空间以及预测建模等功能。Tableau 是一款强大的商业智能(BI)工具,但也有其局限性;这正是 Python 派上用场的地方。  

Python 在数据社区中非常流行。您可以用它来抽取、清洗、处理数据,并应用复杂的统计函数。它为您提供机器学习框架、数据编排、多进程,以及丰富的库,几乎可以完成任何可能的任务。 

Python 是通用型语言,与 Tableau 搭配使用可让我们自由完成高度复杂的任务。在本教程中,我们将使用 Python 来抽取和清洗数据。然后,我们会将清洗后的数据用于在 Tableau 上创建数据可视化。

我们不会使用 Tabpy 来创建 Tableau 的 Python 服务器并在 Tableau 内执行 Python 脚本。相反,我们将先在 Python(Jupyter Notebook)中抽取并清洗数据,然后使用 Tableau 创建交互式可视化。 

Data Visualization with Tableau
Goodreads 数据可视化 | Tableau Public

这是一个基于代码的 Goodreads API 分步教程,并在 Tableau 上创建复杂可视化。请查看下方链接以获取代码和 Tableau 仪表板。 

使用 Python 进行数据摄取与处理

在教程的第一部分,我们将学习使用 Goodreads API 访问公共数据。在本例中,我们将聚焦用户资料,并将其转换为可读的 Pandas 数据框。此外,我们将清洗数据并将其导出为 CSV 文件格式。 

开始上手

我们将使用 DataLab 来运行 Python 代码。它自带数据科学任务所需的 Python 包。 

如果您是 Python 新手并希望在本地机器上搭建环境,请安装 Anaconda。它会安装 Python、Jupyter Notebook 和所需的 Python 包。 

在开始编写代码之前,我们需要安装 xmltodict 包,因为它不属于 DataLab 或 Anaconda 的数据栈。我们将使用 `pip` 来安装缺失的 Python 包。

注意:`!` 符号仅在 Jupyter Notebook 中有效。它允许我们在 Jupyter 代码单元内访问终端。 

!pip install xmltodict

>>> Collecting xmltodict
>>>   Using cached xmltodict-0.13.0-py2.py3-none-any.whl (10.0 kB)
>>> Installing collected packages: xmltodict
>>> Successfully installed xmltodict-0.13.0

下一步,我们将导入必要的包。 

import pandas as pd
import xmltodict
import urllib.request

解析个人资料链接

要抽取用户数据,我们需要用户 ID 和用户名。在本节中,我们将解析用户(Abid)的个人资料链接。 

注意:您可以使用您朋友的个人资料或自己的个人资料链接来运行此脚本。 

  1. 通过在链接中过滤数字提取 user_id,并返回“73376016”。 
  2. 为提取 user_name,我们将以 user_id 分割字符串,然后再以“-”分割以获取用户。将“-”替换为空格后,得到用户名“abid”。
  3. 最后,我们将 user_id 与 user_name 连接。该唯一 ID 将在下一节中用于访问用户数据。
Goodread_profile = "https://www.goodreads.com/user/show/73376016-abid"

user_id = ''.join(filter(lambda i: i.isdigit(), Goodread_profile))
user_name = Goodread_profile.split(user_id, 1)[1].split('-', 1)[1].replace('-', ' ')
user_id_name = user_id+'-'+user_name

print(user_id_name)

>>> 73376016-abid

Goodreads 数据抽取

在 2020 年底,Goodreads 停止提供开发者 API。您可以在此处阅读完整说明。为解决此问题,我们将使用旧项目(如 streamlit_goodreads_app)中的 API 密钥。该项目解释了如何使用 API 访问 Goodreads 的用户数据。 

Goodreads 也提供无需 API 密钥即可将数据下载为 CSV 文件格式的选项,但它仅限于单个用户,且无法让我们自由抽取实时数据。 

本节中,我们将创建函数,接收 user_id_name、version、shelf、per_page 和 apiKey 作为参数。 

  • apiKey:用于访问公共数据
  • version:用于指定最新数据类型。
  • shelf:用户资料中有多个书架,但最常见的是 read、to-read 和 currently-reading。
  • per_page:每页书籍条目数

该函数接收用户输入来拼接 URL,然后使用 urllib.request 下载数据。最后,我们得到 XML 格式的数据。 

apiKey = "ZRnySx6awjQuExO9tKEJXw"
version = "2"
shelf = "read"
per_page = "200"

def get_user_data(user_id, apiKey, version, shelf, per_page):
    api_url_base = "https://www.goodreads.com/review/list"
    final_url = (
        api_url_base
        + user_id
        + ".xml?key="
        + apiKey
        + "&v="
        + version
        + "&shelf="
        + shelf
        + "&per_page="
        + per_page
    )
    contents = urllib.request.urlopen(final_url).read()
    return contents
contents = get_user_data(user_id_name,apiKey,version, shelf, per_page)
print(contents[0:100])


>>> b'<?xml version="1.0" encoding="UTF-8"?>\n<GoodreadsResponse>\n  <Request>\n    <authentication>true</aut'

将 XML 转换为 JSON

我们的初始数据为 XML 格式,无法直接转换为结构化数据库。因此,我们将使用 xmltodict Python 包将其转换为 JSON。 

XML 数据会被转换为嵌套的 JSON 格式。为展示图书评论数据中的第一条记录,我们将使用方括号来访问被封装的数据。 

您可以尝试探索元数据并发掘更多选项,但在本教程中,我们将专注于用户评论数据。  

contents_json = xmltodict.parse(contents)
print(contents_json["GoodreadsResponse"]["reviews"]["review"][:1])

>>> [{'id': '4626706284', 'book': {'id': {'@type': 'integer', '#text': '57771224'}, 'isbn': '1250809606', 'isbn13': '9781250809605', 'text_reviews_count': {'@type': 'integer', '#text': '150'}, 'uri': 'kca://book/amzn1.gr.book.v3.tcNoY0o7ErAhczdQ', 'title': 'Good Intentions', 'title_without_series': 'Good Intentions', 'image_url': .........

将 JSON 转换为 Pandas 数据框 

要将 JSON 数据类型转换为 Pandas 数据框,我们将使用 json_normalize 函数。评论数据位于第三级,为访问它,我们将依次访问 GoodreadsResponse、reviews 和 review。

在展示数据框之前,我们将通过删除缺少 date_updated 列的书籍来过滤无关数据。 

通过学习 Streamlined Data Ingestion with pandas 课程,了解使用 Pandas 摄取 CSV 文件、电子表格、JSON、SQL 数据库和 API 的多种方式。 

df = pd.json_normalize(contents_json["GoodreadsResponse"]["reviews"]["review"])
df = df[df["date_updated"].notnull()]
df.head()

Converting JSON to Pandas Dataframe

数据清洗

原始数据框看起来相当干净,但我们仍需减少列的数量。 

如您所见,共有 61 列。

df.shape
(200, 61)

让我们删除空列。 

df.dropna(axis=1, how='all', inplace=True)
df.shape
(200, 58)

我们已成功删除 3 个缺失值列。

现在我们将使用 `df.columns` 查看所有列名,并选择最有用的列。 

final_df = df[
    [
        "rating",
        "started_at",
        "read_at",
        "date_added",
        "book.title",
        "book.average_rating",
        'book.ratings_count',
        "book.publication_year",
        "book.authors.author.name"
    ]
]
final_df.head()

如您所见,最终的数据框仅保留了相关数据字段,十分干净。 

Final Dataframe

导出 CSV 文件

最后一节中,我们将把数据框导出为与 Tableau 兼容的 CSV 文件。在 to_csv 函数中,添加带扩展名的文件名,并将 index 参数改为 False 以去除索引。 

final_df.to_csv("abid_goodreads_clean_data.csv",index=False)

CSV 文件将显示在当前目录中。

Goodreads Clean CSV File

Goodreads 清洗后的 CSV 文件

您也可以查看 Python Jupyter Notebook:使用 Goodreads API 进行数据摄取。它有助于调试您的代码;如果您想跳过 Python 编程部分,也可以点击 Copy & Edit 按钮后直接运行脚本下载文件。 

在 Tableau 中进行数据可视化

在第二部分中,我们将使用清洗后的数据,在 Tableau 中创建简单和复杂的数据可视化。我们的目标是绘制交互式图表,帮助我们理解用户的读书行为。 

连接数据

我们将通过选择 Text 文件选项并选择 abid_goodreads_clean_data.csv 文件来连接 CSV。之后,我们将把 Started At、Read At 和 Date Added 数据字段更改为 Date & Time,如下所示。 

注意:在开始时修改数据字段是一个良好习惯。  

Connecting Data and Modifying Data Types
连接数据并修改数据类型

创建评分直方图

本节中,我们将创建用户图书评分的直方图。 

  • 首先,将 Rating 字段拖放到 Rows 货架。 

User Rating Histogram Part 1
用户评分直方图 第 1 步

  • 点击 Show Me 下拉按钮以访问可视化模板。我们将通过点击 Histogram 选项把条形图转换为直方图。

User Rating Histogram Part 2
用户评分直方图 第 2 步

  • Rating 轴有 0.5 的刻度间隔。通过右键单击底部坐标轴并选择 Edit Axis 来更改刻度。然后点击 Tick Marks 选项卡,将 Major Tick Marks 改为 Fixed。确保 Tick Origin 为 0,Tick Interval 为 1。


用户评分直方图 第 3 步

  • 我们将通过清理轴标签、修改条形的颜色与边框、添加标记标签来自定义直方图。您可以在 Marks 面板中完成这些设置。该面板位于左中部。 

User Rating Histogram Part 4
用户评分直方图 第 4 步

该用户通常给出 3 到 4 分之间的评分。0 分表示未评分的书籍。 

折线图

绘制折线图:

  1. 将 Book.Publication Year 字段拖放到 Rows 与 Columns 货架。
  2. 通过右键单击 Rows 数据字段并选择 Measure > Count,将其改为计数。 
  3. 通过右键单击 Columns 数据字段并选择 Dimensions,将其改为维度。
  4. 前往 Marks 面板,点击 Automatic 下拉选项,并改为 Line。 
  5. 清理坐标轴标签,自定义图表、添加标题,并移除空值。

Book Publication Year Line Plot
图书出版年份折线图

该用户读过一些年代较久的书籍,但他们对 2015 至 2020 年间出版的书籍尤为感兴趣。 

如果您感到有些吃力并希望学习 Tableau 的基础知识,Eugenia Anello 的《Tableau 新手教程》或许对您有所帮助。 

箱线图

绘制箱线图:

  1. 将 Books.Ratings Count 数据字段拖到 Rows 货架。将其从 Discrete 改为 Continuous。 
  2. 将 Books.Ratings Count 数据字段拖到 Marks 面板的 Detail 选项。将其从 Measure 改为 Dimension。
  3. 点击 Show Me 下拉选项并选择箱线图选项。 
  4. 将数据字段从 Rows 移到 Columns 货架,使其呈水平显示。 
  5. 最后一步是自定义:我们将增大尺寸、更改颜色、添加标题,并将坐标轴重命名为“Popularity”(受欢迎度)。

Number of Reviews per Book Boxplot
每本书的评论数箱线图

看起来该用户更多在读不太热门的书,只有少数是知名书。这意味着用户更看重内容本身,而非热度。 

气泡图

我们已经创建了一个简单却很实用的可视化来了解用户的阅读行为。接下来,我们将学习更复杂的可视化,其中包括创建新的计算字段、编辑分箱,以及构建多层图形。

在气泡图中,标签表示用户读完一本书所用的天数,气泡大小表示出现次数。我们没有持续时间这个数据字段,但可以用 Started At 和 Read At 来创建。

第一步,我们需要在 Data 面板中点击向下箭头并选择 Create Calculated Field 来创建新的计算字段。 

Creating Calculated Field
创建计算字段

新窗口会弹出,您需要:

  1. 将标题字段重命名为“Read Duration”(阅读时长)
  2. 使用 DATEDIFF 函数获取 Read At 与 Started At 之间的差值。
  3. 确保函数的第一个参数为“day”。
  4. 将字段名拖放或在方括号中输入,作为第二与第三个参数。 

Read Duration in Days
以天计的阅读时长

Read Duration 数据字段是连续型的,要绘制打包气泡可视化,我们需要将该字段划分为更小的片段(分箱)。 

  1. 将新创建的 `Read Duration` 字段拖到 Rows 货架。
  2. 点击 Show Me 并选择 histogram。这会自动为您创建一个分箱字段。

Creates a Bin Field
创建分箱字段 

  1. 右键单击新建的 Read Duration(bin)字段,选择“Read Duration in Days”选项。
  2. 将 Size of Bins 改为 10。这样会创建多个更小的数据片段,有助于我们构建更精细的打包气泡图。 

Editing Bins
编辑分箱

难点已过,现在是见证成果的时刻。 

  1. 要创建简单的可视化,点击 Show Me 并选择 packed bubbles。您将看到不同大小的单色圆形。
  2. 为增加颜色,我们将把 Read Duration 字段拖到 Marks 面板中的 Color 选项。 
  3. 通过右键单击该字段并选择 Measure > Count(Distinct),将颜色字段改为去重计数。这会为每个分箱或标签赋予唯一颜色。

Unicolor Packed Bubbles Plot
单色打包气泡图

  1. 点击 Marks 面板中的 Color 选项并选择 Edit Colors… > Sunrise-Sunset Diverging。您可以选择任何符合您审美的渐变色。 
  2. 最后一步是自定义,确保您的可视化既美观又能传达准确信息。

Packed Bubbles Plot
打包气泡图 

大多数书籍用户都在一天内读完。您还可以看到几个超过 300 的离群值。 

我们也可以将这些可视化组合在一起,创建一个 Tableau 仪表板。在本教程中了解如何创建 Tableau 仪表板。

结语

在本教程中,我们学习了 Python 的重要性以及如何将其与 Tableau 搭配使用。在第一部分中,我们使用开发者 API 抽取了 Goodreads 用户数据,并将 XML 数据转换为干净且结构化的 Pandas 数据框。在第二部分中,我们使用清洗后的数据创建了简单与复杂的数据可视化。 

Python 与 Tableau 的结合打开了全新的可能性。您可以集成数据管道、部署机器学习模型、运行复杂的统计分析,并执行许多仅靠 Tableau 无法完成的任务。 

您可以在 DataLab 上免费运行 Python 代码,它包含运行本示例所需的全部包。为创建 Tableau 可视化,我们使用了名为 Tableau Public 的免费版 Tableau。

如果您是 Python 新手并希望深入了解其功能与语法,请查看 Introduction to Data Science in Python 课程。您也可以通过 Tableau Fundamentals 技能路径掌握 Tableau 可视化与自定义的基础。它包含 5 门课程,涵盖Tableau 入门、数据分析、创建交互式仪表板、案例研究,以及连接多个数据源。

主题