查看全课大纲(第 13 / 45 节)
- 1.课程简介
- 2.环境搭建
- 3.预备知识
- 4.pyecharts初体验
- 5.数据可视化概述
- 6.数据可视化的目标和作用
- 7.数据可视化工具对比分析
- 8.数据可视化基本流程
- 9.数据可视化设计原则
- 10.pyecharts简介
- 11.官方图表样例
- 12.常用图表的基本结构
- 13.数据格式
- 14.图表的分类
- 15.柱状图与条形图
- 16.其他对比图表
- 17.常用配置项(一)
- 18.常用配置项(二)
- 19.折线图 面积图
- 20.K线图
- 21.其他时间图表
- 22.常用配置项
- 23.散点图 气泡图
- 24.热力图
- 25.其他相关性图表
- 26.饼图
- 27.矩形树图
- 28.其他成分比例图表
- 29.箱型图与直方图
- 30.3D柱状图与折线图
- 31.其他统计图表
- 32.地图 Map
- 33.地理坐标系Geo
- 34.3D 地图
- 35.网络关系图
- 36.主题河流图
- 37.词云图
- 38.组合图表组件
- 39.仪表盘相关图表
- 40.项目介绍
- 41.数据准备
- 42.子图制作(一)
- 43.子图制作(二)
- 44.数据大屏制作
- 45.项目总结
数据格式
数据格式:从 Pandas 到 pyecharts 的桥梁
小象实战讲义 · ECharts 数据可视化
在数据分析的旅程中,我们常常使用 Pandas 和 NumPy 来处理和清洗数据。然而,当你希望将这些分析成果转化为交互式的 Web 图表时,会发现一个关键障碍:pyecharts 无法直接使用这些库的原生数据结构。本节课程将为你扫清这个障碍,深入讲解 pyecharts 所支持的数据格式,以及如何高效地将你的 Pandas 或 NumPy 数据转换为可用的形式。理解并掌握这些转换技巧,是你从数据分析迈向数据可视化的关键一步。
💡 核心导读
- 核心原理:pyecharts 本质上是将 Python 字典配置序列化为 JSON 格式,因此它只支持 JSON 兼容的 Python 原生基础数据类型。
- 格式映射:Python 的
int/float、str、bool、dict、list分别对应 JSON 的number、string、boolean、object、array。 - 转换技巧:掌握两种核心转换方法:使用 列表推导式 进行灵活的数据处理,以及使用 Pandas Series 的
.tolist()方法进行快速转换。 - 避坑指南:理解错误数据可能通过构建阶段,却在
dump_options()/render()阶段报错,并学会主动检查和转换。
一、 理解 pyecharts 的数据格式原理
pyecharts 是一个 Python 接口库,它的核心任务是将你在 Python 中定义的图表配置,转换成 ECharts(一个基于 JavaScript 的图表库)能够理解的格式。这个转换过程是通过 序列化 实现的:将 Python 的字典(dict)配置项,序列化为 JSON(JavaScript Object Notation) 格式的文本。
JSON 是一种轻量级的数据交换格式,它规定了有限的几种数据类型。因此,pyecharts 能够支持什么样的 Python 数据类型,完全取决于 JSON 支持什么类型。
下表清晰地展示了 Python 数据类型与 JSON 数据类型的对应关系:
| Python 数据类型 | JSON 数据类型 | 说明 |
|---|---|---|
int, float | number | 数值类型 |
str | string | 字符串类型 |
bool | boolean | 布尔类型(True/False) |
dict | object | 对象/字典类型 |
list | array | 数组/列表类型 |
关键结论:pyecharts 仅支持上表中列出的 Python 原生基础数据类型。
这意味着,来自 NumPy(如 numpy.int64, numpy.float32)和 Pandas(如 pandas.Series, pandas.DataFrame)的数据结构,虽然它们底层可能也是数组或列表,但由于其类型并非继承自 Python 原生的 int、float 或 list,因此 不能直接用于 pyecharts。你必须将它们转换为对应的原生类型。
二、 数据转换的核心技巧
既然知道了需要转换,接下来就是学习如何高效、准确地进行转换。我们主要掌握两种方法。
1. 使用列表推导式进行灵活转换
列表推导式(List Comprehension)是 Python 中一种简洁、高效的创建列表的方法。它特别适合用于对一组数据进行遍历、筛选和转换。
基本语法:
[表达式 for 变量 in 可迭代对象 if 条件]- 表达式:对变量进行处理后,作为新列表的元素。
- for 变量 in 可迭代对象:遍历原始数据。
- if 条件:(可选)用于筛选数据。
让我们通过几个例子来理解它的强大之处。
示例1:基础类型转换 假设我们有一个整数列表,需要将其转换为字符串列表。
下面把三个基础转换示例放在同一个自包含代码块中运行。
# 原始整数列表
int_list = list(range(10)) # [0, 1, 2, ..., 9]
# 方法A:使用传统的 for 循环
str_list_for = []
for num in int_list:
str_list_for.append(str(num))
# 方法B:使用列表推导式(一行代码,更简洁高效)
str_list_comprehension = [str(num) for num in int_list]
print("for循环结果:", str_list_for[:3], "...")
print("推导式结果:", str_list_comprehension[:3], "...")
# 示例2:为每个数值添加 "元" 作为单位(字符串拼接)
# 为每个数值添加"元"作为单位
amount_list = [100, 200, 350]
amount_with_unit = [f"{amount}元" for amount in amount_list]
print("带单位的数据:", amount_with_unit)
# 示例3:只选取能被3整除的数,并计算其平方
numbers = list(range(1, 16))
squares_of_multiples_of_3 = [num**2 for num in numbers if num % 3 == 0]
print("1-15中3的倍数的平方:", squares_of_multiples_of_3)输出:
for循环结果: ['0', '1', '2'] ...
推导式结果: ['0', '1', '2'] ...
带单位的数据: ['100元', '200元', '350元']
1-15中3的倍数的平方: [9, 36, 81, 144, 225]通过列表推导式,你可以轻松地将 NumPy 数组或其他可迭代对象中的元素,转换为你需要的任何原生 Python 类型,从而为 pyecharts 做好准备。
2. 使用 Pandas Series 的 .tolist() 方法
当你从 CSV、Excel 等文件用 Pandas 读取数据后,最常用的数据结构就是 Series(一列数据)。Pandas 非常贴心地为 Series 提供了 .tolist() 方法,可以将其直接转换为 Python 原生列表。
这是将 Pandas 数据处理后用于 pyecharts 最直接、最常用的方法。
让我们通过一个完整的柱状图示例,来对比错误和正确的做法。
import pandas as pd
from pyecharts.charts import Bar
from pyecharts import options as opts
# 1. 创建示例数据(模拟销售数据)
data_dict = {
'商品': ['笔记本', '手机', '平板', '耳机', '键盘'],
'商家A': [120, 85, 64, 90, 55],
'商家B': [95, 110, 70, 80, 65]
}
sales_df = pd.DataFrame(data_dict)
print("原始数据表:")
print(sales_df)
print("\n数据类型检查:")
print(f"商品列类型: {type(sales_df['商品'])}")
print(f"商家A列类型: {type(sales_df['商家A'])}")输出:
原始数据表:
商品 商家A 商家B
0 笔记本 120 95
1 手机 85 110
2 平板 64 70
3 耳机 90 80
4 键盘 55 65
数据类型检查:
商品列类型: <class 'pandas.Series'>
商家A列类型: <class 'pandas.Series'>现在,我们尝试用错误的方式(直接使用 Series)和正确的方式(使用 .tolist())来创建图表。
import pandas as pd
from pyecharts.charts import Bar
from pyecharts import options as opts
sales_df = pd.DataFrame({
'商品': ['笔记本', '手机', '平板', '耳机', '键盘'],
'商家A': [120, 85, 64, 90, 55],
'商家B': [95, 110, 70, 80, 65]
})
# 2. 【错误示范】直接使用 Pandas Series
print("\n--- 错误示范:直接使用Series ---")
try:
bar_wrong = Bar()
bar_wrong.add_xaxis(sales_df['商品']) # 传入的是 Series
bar_wrong.add_yaxis("商家A", sales_df['商家A'])
bar_wrong.add_yaxis("商家B", sales_df['商家B'])
bar_wrong.set_global_opts(title_opts=opts.TitleOpts(title="错误示范"))
print("图表对象构建完成,X轴数据格式为:", type(sales_df['商品']).__name__)
# 构建阶段不会报错,序列化或渲染阶段才会暴露非原生数据结构
bar_wrong.dump_options()
except Exception as e:
print(f"序列化阶段发生异常: {e}")输出:
--- 错误示范:直接使用Series ---
图表对象构建完成,X轴数据格式为: Series
序列化阶段发生异常: Can't use non-native data structures as axis data to render chart关键点:图表对象可以正常构建,但这并不代表它能被正确序列化和渲染。直到调用 dump_options() 或 render() 时,pyecharts 才会因数据不是 JSON 原生结构而抛出 ValueError。所以不能只凭“构建没报错”判断数据格式可用。
# 3. 【正确示范】使用 .tolist() 转换
print("\n--- 正确示范:使用.tolist()转换 ---")
bar_correct = Bar()
bar_correct.add_xaxis(sales_df['商品'].tolist()) # 转换为list
bar_correct.add_yaxis("商家A", sales_df['商家A'].tolist()) # 转换为list
bar_correct.add_yaxis("商家B", sales_df['商家B'].tolist())
bar_correct.set_global_opts(
title_opts=opts.TitleOpts(title="商家A与商家B商品销量对比"),
xaxis_opts=opts.AxisOpts(name="商品"),
yaxis_opts=opts.AxisOpts(name="销量")
)
# 打印配置摘要,验证数据已正确传入
options = bar_correct.dump_options()
import json
options_dict = json.loads(options)
print("图表类型:", type(bar_correct).__name__)
print("X轴数据(前3项):", options_dict['xAxis'][0]['data'][:3])
print("系列1名称:", options_dict['series'][0]['name'])
print("系列1数据:", options_dict['series'][0]['data'])
print("系列2名称:", options_dict['series'][1]['name'])
print("系列2数据:", options_dict['series'][1]['data'])
print("✅ 数据已成功转换为列表格式,图表可正常渲染。")输出:
--- 正确示范:使用.tolist()转换 ---
图表类型: Bar
X轴数据(前3项): ['笔记本', '手机', '平板']
系列1名称: 商家A
系列1数据: [120, 85, 64, 90, 55]
系列2名称: 商家B
系列2数据: [95, 110, 70, 80, 65]
✅ 数据已成功转换为列表格式,图表可正常渲染。可以看到,经过 .tolist() 转换后,数据变成了纯粹的 Python list 类型,并成功集成到了图表的配置中。
三、 为什么 pyecharts 不自动转换?
你可能会问,既然这是一个如此普遍的需求,为什么 pyecharts 不内置对 NumPy 和 Pandas 数据类型的自动转换呢?这主要出于以下几点考虑:
- 保持轻量与专注:pyecharts 的核心定位是作为 ECharts 的 Python 接口。如果为了自动转换而强制引入 NumPy 和 Pandas 这两个庞大且功能繁多的第三方库,会极大地增加 pyecharts 本身的复杂性和安装体积,对于只需要基础图表功能的用户来说并不友好。
- 职责分离:数据清洗、转换是数据分析阶段的任务,而图表渲染是可视化阶段的任务。pyecharts 选择将数据格式转换的职责明确交给开发者,这符合库设计的单一职责原则。
- 灵活性:数据转换的需求千变万化(如格式化、筛选、聚合等)。
.tolist()和列表推导式提供了基础且强大的工具,开发者可以在此基础上实现任何复杂的转换逻辑,这比库内置的几种固定转换方式要灵活得多。
因此,将数据转换为正确的格式,是使用 pyecharts 进行可视化前 必不可少且由你完全掌控 的一个步骤。
📝 动手练一练
- 练习一:数据清洗与转换 假设你有一个包含杂质的销售数据列表
sales_data = [‘120’, ‘N/A’, ‘85.5’, ‘64’, ‘90.0元’]。请使用列表推导式,完成以下任务:- 过滤掉无法转换为数字的字符串(如 ‘N/A’, ‘90.0元’)。
- 将有效的字符串转换为浮点数(
float)。 - 最后,计算过滤并转换后所有数字的平均值。
点击查看参考答案
sales_data = ['120', 'N/A', '85.5', '64', '90.0元']
def is_convertible_to_float(s):
"""辅助函数:检查字符串是否能转换为浮点数"""
try:
float(s)
return True
except ValueError:
return False
# 使用列表推导式进行过滤和转换
cleaned_data = [float(item) for item in sales_data if is_convertible_to_float(item)]
print("清洗后的数据:", cleaned_data)
if cleaned_data:
average_sales = sum(cleaned_data) / len(cleaned_data)
print(f"平均销量: {average_sales:.2f}")
else:
print("没有有效数据可计算平均值。")输出:
清洗后的数据: [120.0, 85.5, 64.0]
平均销量: 89.83- 练习二:从 DataFrame 到图表数据 创建一个包含 ‘城市’ 和 ‘人口(万)’ 两列的 Pandas DataFrame,数据自拟。然后,分别提取这两列数据,并使用
.tolist()方法将其转换为列表,最后打印出转换后的结果和数据类型。
点击查看参考答案
import pandas as pd
# 创建示例 DataFrame
data = {
'城市': ['北京', '上海', '广州', '深圳'],
'人口(万)': [2189, 2487, 1868, 1768]
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)
# 使用 .tolist() 转换
city_list = df['城市'].tolist()
population_list = df['人口(万)'].tolist()
print("\n转换结果:")
print(f"城市列表: {city_list} -> 类型: {type(city_list)}")
print(f"人口列表: {population_list} -> 类型: {type(population_list)}")输出:
原始DataFrame:
城市 人口(万)
0 北京 2189
1 上海 2487
2 广州 1868
3 深圳 1768
转换结果:
城市列表: ['北京', '上海', '广州', '深圳'] -> 类型: <class 'list'>
人口列表: [2189, 2487, 1868, 1768] -> 类型: <class 'list'>本章小结
本节我们深入探讨了 pyecharts 可视化流程中至关重要的一环——数据格式。我们明白了 pyecharts 基于 JSON 序列化的工作机制,决定了它只接受 Python 原生的基础数据类型。对于来自 NumPy 和 Pandas 的强大但“非原生”的数据结构,我们掌握了两种核心的转换武器:灵活强大的列表推导式和简单直接的 .tolist() 方法。同时,我们也了解了 pyecharts 在此设计上的考量,并学会了如何主动规避因数据格式问题导致的“图表不显示”陷阱。
📋 行动清单
- 检查与转换:在将数据传入
add_xaxis()或add_yaxis()前,养成检查数据类型(type())并主动使用.tolist()进行转换的习惯。 - 掌握推导式:练习使用列表推导式来处理更复杂的数据筛选、格式化和转换任务,这是提升 Python 数据处理效率的通用技能。
- 验证配置:在图表未按预期显示时,优先使用
.dump_options()等方法输出配置摘要,检查数据是否已正确转换为列表格式。
—— 小象教研组
