一文搞定Python数据分析三剑客:NumPy、Pandas、Matplotlib全攻略
Python数据分析三剑客:NumPy、Pandas、Matplotlib全攻略
前言
在数据科学领域,Python凭借其强大的生态系统成为首选工具。其中,NumPy、Pandas和Matplotlib被誉为"数据科学三剑客",它们协同工作,构成了Python数据科学分析的基础框架。
大家往往能看见很多非常详细的教学,但却忽视了这三者是如何来协同工作的,本文将系统讲解这三个库的核心概念、使用方法及它们之间的协作关系,最后通过一个完整的数据分析流程,帮助您快速掌握Python数据科学的实战技能。
不废话,直接上流程图
数据分析流程图展示

Numpy
简介
在Python中,原生列表可以存储各种类型的数据,但当我们需要进行高效的数值计算时,列表的效率会非常低下。想象一下,如果要对一个包含100万元素的列表进行平方运算,Python需要逐个元素执行,这会非常慢。
NumPy通过ndarray(N维数组)提供了一个高效的数值计算基础。它将数据存储在连续的内存块中,使用C语言实现底层计算,避免了Python解释器的开销,使得数值计算速度提升数十倍。
数组基础:Ndarray 对象
NumPy的核心对象是ndarray(n维数组),简单来说,ndarray是一个高效、多维、同类型数据的容器
例如:
import numpy as np
# 创建一个2x3的二维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("维度:", arr.ndim) # 2(二维数组)
print("形状:", arr.shape) # (2, 3)(2行3列)
print("数据类型:", arr.dtype) # int64(64位整数)
1.数组的创建
NumPy提供了多种方式创建数组,以下是常用方法:
1.1 基本数组创建
这是最直观的创建方式,将Python列表转换为ndarray。这也是数据导入的常见方式,例如从CSV文件读取数据后,可以将其转换为ndarray进行处理。
import numpy as np
# 一维数组
data_1d = np.array([1, 2, 3, 4])
print("一维数组:", data_1d)
# 二维数组
data_2d = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
print("二维数组:\n", data_2d)
一维数组类似于列表,而二维数组则类似于表格,有行和列。在实际应用中,我们经常需要将列表数据转换为NumPy数组以便进行高效的数值运算。
1.2 特定模式数组创建
NumPy提供了多种函数来创建具有特定模式的数组,避免手动编写循环。
# 等差数组(arange)
data_arange = np.arange(1, 10, 2) # 从1开始,到10结束,步长为2
print("arange创建的数组:", data_arange)
# 全0数组
data_zeros = np.zeros(shape=(2, 3))
print("全0数组:\n", data_zeros)
# 全1数组
data_ones = np.ones(shape=(2, 3))
print("全1数组:\n", data_ones)
# 未初始化数组(空数组)
data_empty = np.empty(shape=(2, 3))
print("全空数组:\n", data_empty)
# 等间隔数组(linspace)
data_linspace = np.linspace(1, 10, 10) # 从1到10,生成10个等间隔数据
print("linspace序列数组:", data_linspace)
arange函数类似于Python的range,但返回的是数组;zeros和ones用于创建全0或全1数组;empty创建未初始化的数组,其内容取决于内存状态;linspace则用于创建指定数量的等间隔数据。
1.3 随机数组
在数据分析和机器学习中,随机数生成是常见的需求。
# 随机数组(0-1之间)
data_random = np.random.rand(3, 4)
print("随机数组:\n", data_random)
# 随机整数数组
data_randint = np.random.randint(2, 5, size=(3, 4)) # 3行4列,元素值在2-5之间
print("随机整数数组:\n", data_randint)
rand函数生成0到1之间的均匀分布随机数,而randint生成指定范围内的随机整数。这些随机数组在模拟实验和随机抽样中非常有用。
2. ndarray 的核心特性
2.1 维度(ndim)
表示数组的维度数。一维数组(如向量)的维度为1,二维数组(如矩阵)的维度为2。
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("维度:", arr.ndim) # 输出: 2
了解数组的维度有助于我们理解数据的结构,例如在图像处理中,彩色图像是三维数组(高度、宽度、颜色通道)。
2.2 形状(shape)
表示数组在每个维度上的大小。对于二维数组,shape是(行数, 列数)。
print("形状:", arr.shape) # 输出: (2, 3)
形状是数组的一个重要属性,许多操作(如重塑、广播)都依赖于形状。
2.3 数据类型(dtype)
表示数组中元素的数据类型。NumPy支持多种数据类型,如int64、float64、bool等。
print("数据类型:", arr.dtype) # 输出: int64
数据类型决定了数组元素在内存中的存储方式以及所能进行的操作。例如,整数类型和浮点数类型的运算规则不同。
2.4 元素数量(size)
表示数组中元素的总数。
print("元素数量:", arr.size) # 输出: 6
元素数量是形状各维度的乘积,通常在内存管理和性能优化时需要考虑。
3. ndarray 的基本操作
3.1 改变形状(reshape)
data = np.array([[1,2,3,4,5], [1,2,3,4,5]])
print("原形状:", data.shape) # (2,5)
data = data.reshape((5,2)) # 5行2列
print("新形状:", data.shape) # (5,2)
重塑操作不改变数据本身,只改变数据的视图。需要注意的是,重塑后的数组元素数量必须与原数组相同。
3.2 数组转置(T)
data = [[1,2,3], [4,5,6], [7,8,9]]
data_array = np.array(data)
print("转置前:\n", data_array)
print("转置后:\n", data_array.T) # 行变列
转置是矩阵运算中的常见操作,例如在计算矩阵乘法时我们就经常用到。
3.3 数组运算:向量化优势
a = np.array([1,2,3])
b = np.array([4,5,6])
# 向量化加法
print(a + b) # [5,7,9]
# 向量化乘法(点乘)
print(a * b) # [4,10,18]
向量化运算是NumPy的核心优势之一,它允许我们直接对数组进行运算,而不需要编写循环。这不仅代码简洁,而且运行效率高。
小结
你已完成基础的NumPy学习,在以上过程中,我们学习了:
- NumPy的核心对象ndarray
- ndarray的创建、属性和操作
- NumPy在数值计算中的优势
接下来,让我们开始学习Pandas吧!
Pandas
简介
Pandas是Python中用于数据操作和分析的库,它建立在NumPy之上,提供了更高级的数据结构和操作工具。Pandas的名称源自"panel data"(面板数据)和"Python data analysis"(Python数据分析)的组合。
Pandas的核心优势在于:
- 提供了DataFrame和Series数据结构,使表格数据处理更加直观
- 支持多种数据格式的导入导出
- 提供了丰富的数据处理函数,如缺失值处理、排序、分组等
- 与NumPy紧密集成,可以高效利用NumPy的向量化操作
数据结构:Series和DataFrame
1. Series:一维带索引的数据结构
Series是Pandas的核心数据结构之一,它类似于一维数组,但带有索引(标签),使得数据访问更加灵活。
第一列为索引,第二列为Series数据
1.1 Series的创建方式:
方式1:从列表创建
temperature = pd.Series([25, 28, 30, 22],
index=['北京', '上海', '广州', '成都'],
name='今日温度')
print("城市温度数据:")
print(temperature)
我们创建了一个包含四个城市温度的Series,并指定了索引为城市名称。这样,我们就可以通过城市名称来访问对应的温度数据。
方式2:从字典创建(更直观)
sales_data = pd.Series({'一月': 1500, '二月': 1800, '三月': 2200, '四月': 1900})# 前键后值
print("\n月度销售数据:")
print(sales_data)
通过字典创建Series时,字典的键会自动成为Series的索引,字典的值成为Series的数据。这种方式在已有字典数据时非常方便。
1.2 Series的索引访问方式:
index: 查看下标(索引/标签)
values: 查看下标的值
print(sales_data.index)
print(sales_data.values)
index属性返回索引对象,values属性返回NumPy数组。这让我们可以分别操作索引和数据。
iloc: 基于位置的索引(原下标,也就是默认值,计算机的记忆)
print("第一个元素 (iloc[0]):", sales_data.iloc[0])
print("前两个元素 (iloc[0:2]):", sales_data.iloc[0:2])
索引位置从0开始,注意,切片是左闭右开区间。
loc: 基于标签的索引(标签是由我们自主给的,计算机并不会自己产生)
print("一月数据 (loc['一月']):", sales_data.loc['一月'])
print("一月到三月 (loc['一月':'三月']):", sales_data.loc['一月':'三月'])
布尔索引: 条件筛选
high_sales = sales_data[sales_data > 2000]
print("高销售额月份 (>2000):", high_sales)
布尔索引允许我们根据条件筛选数据,返回满足条件的子集。
1.3 Series的运算:
算术运算: 支持向量化运算,索引会自动对齐
s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
s2 = pd.Series([4, 5, 6], index=['b', 'c', 'd'])
# 直接相加:索引对齐,顺序无关
print("直接相加:", s1 + s2) # 使用这种相加,没有对应标签的情况下会错误,显示NAN
# 使用add方法:可处理缺失值
print("安全相加:", s1.add(s2, fill_value=0)) # fill_value=0代表如果出现没有值的情况,以0代替
# 同理还有:
print(s1.sub(s2,fill_value=0))
print(s1.mul(s2,fill_value=1))
print(s1.div(s2,fill_value=1))
# 需注意的是,乘除不要设为0
Series的运算会自动对齐索引,如果某个索引在其中一个Series中不存在,结果会变为NaN。使用fill_value可以填充缺失值。
统计运算: 内置常用统计方法
data = pd.Series([10, 20, 30, 40, 50])
print("最大值:", data.max())
print("最小值:", data.min())
print("总和:", data.sum())
print("平均值:", data.mean())
print("标准差:", data.std())
2. DataFrame:二维表格型数据结构
DataFrame是Pandas的另一个核心数据结构,它类似于表格,包含行和列,每列可以有不同的数据类型。
2.1 DataFrame的创建方式(常用):
由字典创建
# 每列数据长度必须相同
data = {
'姓名': ['赵明', '钱芳', '孙强', '李娜'],
'年龄': [19, 20, 21, 19],
'数学': [85, 92, 78, 96],
'英语': [88, 85, 92, 79],
'物理': [90, 87, 85, 93]
}
df = pd.DataFrame(data)
通过字典创建DataFrame时,字典的键成为列名,字典的值(列表)成为列数据。注意,各列表的长度必须相同。
从Series创建:
student_id = pd.Series(['S001', 'S002', 'S003'], index=['赵明', '钱芳', '孙强'])
math_scores = pd.Series([85, 92, 78], index=['赵明', '钱芳', '孙强'])
df = pd.DataFrame({'学号': student_id, '数学成绩': math_scores})
我们可以将多个Series组合成DataFrame,Series的索引会成为DataFrame的行索引。
2.2 DataFrame的索引与切片:
设置行列索引
df = pd.DataFrame(data,
index=['学生A', '学生B', '学生C', '学生D'], # 行索引
columns=['姓名', '数学', '英语', '年龄']) # 列索引
在创建DataFrame时,我们可以通过index参数设置行索引,通过columns参数设置列索引。
列选择
# 选择单列(返回Series)
names = df['姓名']
# 选择多列(返回DataFrame)
subset = df[['姓名', '数学']]
选择单列返回Series,选择多列返回DataFrame。注意,多列选择时需要使用列表。
行选择
# loc基于标签
print(df.loc['学生A']) # 单行
print(df.loc['学生A':'学生C']) # 多行(包含结束位置)
# iloc基于位置
print(df.iloc[0]) # 第一行
print(df.iloc[0:2]) # 前两行
loc通过行索引标签选择行,iloc通过行位置选择行。注意,loc的切片是闭区间,iloc的切片是左闭右开。
行列混合选择
# 选择特定行列
print(df.loc['学生A', '姓名']) # 单个值
print(df.loc['学生A':'学生C', '姓名':'数学']) # 行列范围
print(df.iloc[0:2, 0:2]) # 位置范围
我们可以同时选择行和列,返回指定的数据子集。
条件筛选
# 单条件
high_scores = df[df['数学'] > 90]
# 多条件
good_students = df[(df['数学'] > 85) & (df['年龄'] < 21)]
# 字符串条件
zhao_students = df[df['姓名'].str.contains('赵')]
条件筛选返回满足条件的行。多条件时,每个条件要用括号括起来,并使用逻辑运算符(&、|、~)连接。
2.3 DataFrame的常用操作
查看数据基本信息
print("数据形状:", df.shape) # (行数, 列数)
print("列名:", df.columns) # 所有列的名称
print("索引:", df.index) # 行索引
print("数据类型:\n", df.dtypes) # 每列的数据类型
查看这些属性能帮助我们快速了解DataFrame的结构。
数据预览
print("前5行:\n", df.head(5)) # 查看前5行
print("后5行:\n", df.tail(5)) # 查看后5行
print("统计描述:\n", df.describe()) # 数值列的统计信息
head和tail方法用于查看数据的前几行或后几行。describe方法生成数值列的描述性统计,包括计数、均值、标准差、最小值、四分位数和最大值。
数据导入与导出
Pandas支持多种数据格式的导入和导出,这是数据分析流程中不可或缺的环节。
数据导入
在实际项目中,推荐使用相对路径来管理数据文件
import pandas as pd
import os
# 方法1:使用绝对路径(不推荐,可移植性差)
# fpath_excel = r"D:\数据分析\项目\data\学生成绩.xlsx"
# fpath_csv = r"D:\数据分析\项目\data\学生信息.csv"
# 方法2:使用相对路径(推荐)
# 获取脚本所在的目录
script_dir = os.path.dirname(os.path.abspath(__file__))
# 设置当前工作目录为脚本所在的目录
os.chdir(script_dir)
# 定义数据文件路径
fpath_excel = r"data\学生成绩.xlsx"
fpath_csv = r"data\学生信息.csv"
fpath_json = r"data\学生信息.json"
# CSV文件
df = pd.read_csv(fpath_csv, encoding='utf-8')
# Excel文件
df = pd.read_excel(fpath_excel, sheet_name='Sheet1')
# JSON文件
df = pd.read_json(fpath_json)
# 从URL读取
df = pd.read_csv('https://example.com/data.csv')
需要注意的是,读取CSV文件时可能需要指定编码格式,如utf-8。
还有其他的我没一一列举,但是都很好记对不对?都是read_再加上后缀名。
数据导出
# 保存为 CSV 文件
df.to_csv('output.csv', index=False, encoding='utf-8') # index=False表示不带行索引
# 保存为 Excel 文件
df.to_excel('output.xlsx', sheet_name='Sheet1', index=False)
# 保存为 JSON 文件
df.to_json('output.json', orient='records', indent=4)
# 保存为 HTML 文件
df.to_html('output.html', index=False)
导出数据时,通常我们不希望保存行索引,因此设置index=False。to_json的orient参数指定了JSON的格式,indent参数使JSON文件更易读。
数据预处理
1. 缺失值处理
缺失数据是数据分析中常见的问题,Pandas提供了丰富的处理方法。
检测缺失值:
# 检查每个单元格是否有缺失值
print(df.isnull()) # 缺省值对应的值为True,返回值为Boolean的Series或者DataFrame对象
print(df.notnull())# 缺省值对应的值为False,返回值为Boolean的Series或者DataFrame对象
# 统计每列缺失值数量
print(df.isnull().sum())
# 检查整个DataFrame是否有缺失值
print(df.isnull().any().any())
isnull和notnull方法返回与原始DataFrame形状相同的布尔值DataFrame,其中True表示缺失或非缺失。通过sum方法可以统计每列的缺失值数量。
处理缺失值
处理缺失值是数据清洗中至关重要的一步,往往你需要根据业务的具体情况来选择处理,来保证数据的质量。
# 删除缺失值
df_dropped = df.dropna() # 删除任何包含NaN的行
df_dropped_col = df.dropna(axis=1) # 删除任何包含NaN的列
# 填充缺失值
df_filled = df.fillna(0) # 用0填充
df_ffill = df.fillna(method='ffill') # 用前一个值填充
df_bfill = df.fillna(method='bfill') # 用后一个值填充
df_mean = df.fillna(df.mean()) # 用列均值填充
删除缺失值可能会损失大量数据,因此填充往往是更好的选择。填充时,可以根据业务知识选择填充值,或者使用统计量(如均值、中位数)填充。
2. 数据筛选与操作
Pandas提供了强大的数据筛选和操作功能,使数据处理更加高效。
数据排序
# 按单列排序
df_sorted = df.sort_values('数学')
# 按多列排序
df_sorted = df.sort_values(['年龄', '数学'], ascending=[True, False])
# 按索引排序
df_sorted_index = df.sort_index()
排序可以帮助我们快速找到最大值、最小值,或者按照特定顺序查看数据。多列排序时,先按第一列排序,第一列相同再按第二列排序。
数据分组
# 添加班级列用于分组
df['班级'] = ['一班', '二班', '一班', '二班']
# 单列分组
grouped = df.groupby('班级')
# 分组后聚合
result = grouped.agg({
'数学': ['mean', 'max', 'min', 'count'],
'英语': 'mean',
'年龄': 'mean'
})
分组操作是数据分析中的常见操作,它允许我们对每个组进行聚合计算。agg方法允许我们对不同的列应用不同的聚合函数。
数据转换
# 添加新列
df['数学等级'] = df['数学'].apply(lambda x: '优秀' if x > 90 else '良好')
# 类型转换
df['年龄'] = df['年龄'].astype(float)
# 重命名列
df = df.rename(columns={'数学': '数学成绩', '英语': '英语成绩'})
apply方法允许我们对Series的每个元素应用一个函数。类型转换可以确保数据类型的正确性。重命名列可以使列名更清晰。
Pandas与NumPy的协作
Pandas建立在NumPy之上,两者可以完美协作,具体如下:
1. 二者的相互转换
# DataFrame/Series 转 NumPy数组
numpy_array = df.values
series_array = series.values
# NumPy数组 转 DataFrame
df_from_numpy = pd.DataFrame(numpy_array, columns=['姓名', '年龄', '数学', '英语'])
2. 协同计算
# 使用NumPy函数处理Pandas数据
df['标准化数学成绩'] = (df['数学'] - df['数学'].mean()) / df['数学'].std()
# 在Pandas中直接使用NumPy运算
result = np.sqrt(df[['数学', '英语']])
# 布尔索引结合
high_scores = df[np.array(df['数学']) > 90]
小结
你已完成Pandas的核心学习,掌握了:
- Series和DataFrame数据结构
- 数据导入导出方法
- 缺失值处理和数据清洗技巧
- 与NumPy的协作关系
现在,让我们进入最后一个环节:数据可视化,使用Matplotlib将处理后的数据以图表形式展示。
Matplotlib
简介
Matplotlib是Python中用于数据可视化的库,可以轻松地将Pandas DataFrame中的数据可视化。
Matplotlib的核心特点:
- 提供了丰富的图表类型(折线图、散点图、柱状图等)
- 高度可定制的图表样式
- 与Pandas无缝集成
- 支持多种输出格式(PNG、PDF、SVG等)
Matplotlib架构
Matplotlib采用面向对象的设计理念,其核心架构由三个关键组件构成:
1. Figure(画布)
Figure 是 Matplotlib 中最顶层的容器,相当于整个绘图的"画布",包含了所有绘图元素。它是整个图形的顶级容器,可以包含一个或多个坐标区域(Axes)。
# 创建一个10x8英寸、300DPI的画布
fig = plt.figure(figsize=(10, 8), dpi=300)
2. Axes(坐标区域)
Axes 是 Figure 中的一个绘图区域,是实际进行数据绘制的"画布上的画布"。它是 Matplotlib 中最常用的绘图对象,包含了坐标轴、刻度、标签、图例等所有元素。
# 创建包含一个坐标区域的 Figure
fig, ax = plt.subplots(figsize=(8, 6))
# 或者在已有 Figure 上添加坐标区域
fig = plt.figure()
ax = fig.add_subplot(111) # 创建1x1网格的第一个子图
# 或者创建2x2网格的坐标区域
fig, axs = plt.subplots(2, 2) # 2x2网格的坐标轴
3. Axis(坐标轴)
Axis 是 Axes 中的坐标轴,负责管理坐标轴的细节,如刻度、刻度标签、轴标签和范围。注意:Axes 是单数,Axis 才是坐标轴。
# 设置x轴和y轴的标签
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
# 设置坐标轴范围
ax.set_xlim(0, 10)
ax.set_ylim(0, 100)
三者的关系
Figure > Axes > Axis
(画布 > 绘图区域 > 坐标轴)
Matplotlib绘图流程
1. 创建Figure:初始化画布
作用:创建绘图的基础容器,设置画布大小、分辨率等全局参数。
2. 添加Axes:指定绘图区域
作用:在画布上创建实际的绘图区域,一个画布可以包含多个绘图区域。
3. 绘制数据:在Axes上添加图表元素
作用:在指定的绘图区域上绘制实际的数据图形。
4. 设置属性:定制图表外观
作用:美化图表,添加标题、标签、图例等,使图表更专业、易读。
5. 显示/保存:plt.show()或plt.savefig()
作用:展示或保存最终的图表成果。
绘图流程图展示

常用图形绘制
1. 折线图 - 趋势分析
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 创建示例数据
dates = pd.date_range('2023-01-01', periods=12, freq='M')
sales_a = [120, 135, 148, 165, 180, 195, 210, 225, 240, 255, 270, 285]
sales_b = [100, 115, 130, 145, 160, 170, 175, 185, 195, 205, 215, 225]
fig, ax = plt.subplots(figsize=(12, 6))
# 绘制两条折线
ax.plot(dates, sales_a, marker='o', linewidth=2, label='产品A', color='#2E86AB')
ax.plot(dates, sales_b, marker='s', linewidth=2, label='产品B', color='#A23B72')
# 图表装饰
ax.set_title('月度销售趋势分析', fontsize=16, fontweight='bold', pad=20)
ax.set_xlabel('月份', fontsize=12)
ax.set_ylabel('销售额(万元)', fontsize=12)
ax.legend(loc='upper left', frameon=True, fancybox=True, shadow=True)
ax.grid(True, alpha=0.3)
# 设置x轴刻度格式
ax.xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
2. 柱状图 - 分类比较
# 创建产品数据
products = ['笔记本', '手机', '平板', '耳机', '手表']
sales_q1 = [120, 200, 80, 150, 90]
sales_q2 = [140, 220, 95, 160, 110]
x = np.arange(len(products))
width = 0.35
fig, ax = plt.subplots(figsize=(10, 6))
# 绘制分组柱状图
bars1 = ax.bar(x - width/2, sales_q1, width, label='第一季度',
color='#4CB5AE', edgecolor='grey', alpha=0.8)
bars2 = ax.bar(x + width/2, sales_q2, width, label='第二季度',
color='#D4A5A5', edgecolor='grey', alpha=0.8)
# 添加数据标签
def add_labels(bars):
for bar in bars:
height = bar.get_height()
ax.annotate(f'{height}',
xy=(bar.get_x() + bar.get_width() / 2, height),
xytext=(0, 3), # 垂直偏移
textcoords="offset points",
ha='center', va='bottom', fontsize=10)
add_labels(bars1)
add_labels(bars2)
# 图表装饰
ax.set_title('各产品季度销售额对比', fontsize=16, fontweight='bold')
ax.set_xlabel('产品类别', fontsize=12)
ax.set_ylabel('销售额(万元)', fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(products)
ax.legend()
plt.tight_layout()
plt.show()
3. 散点图 - 相关性分析
from matplotlib import colors
# 生成模拟数据
np.random.seed(42)
n_points = 100
study_hours = np.random.normal(20, 8, n_points)
exam_scores = 50 + 2 * study_hours + np.random.normal(0, 10, n_points)
fig, ax = plt.subplots(figsize=(10, 6))
# 绘制散点图
scatter = ax.scatter(study_hours, exam_scores,
c=exam_scores, cmap='viridis',
alpha=0.7, s=60, edgecolors='white', linewidth=0.5)
# 添加趋势线
z = np.polyfit(study_hours, exam_scores, 1)
p = np.poly1d(z)
ax.plot(study_hours, p(study_hours), "r--", alpha=0.8, linewidth=2)
# 图表装饰
ax.set_title('学习时间与考试成绩关系', fontsize=16, fontweight='bold')
ax.set_xlabel('每周学习时间(小时)', fontsize=12)
ax.set_ylabel('考试成绩', fontsize=12)
# 添加颜色条
cbar = plt.colorbar(scatter)
cbar.set_label('成绩分数', rotation=270, labelpad=15)
# 添加相关系数
correlation = np.corrcoef(study_hours, exam_scores)[0, 1]
ax.text(0.05, 0.95, f'相关系数: {correlation:.3f}',
transform=ax.transAxes, fontsize=12,
bbox=dict(boxstyle="round,pad=0.3", facecolor="white", alpha=0.8))
plt.tight_layout()
plt.show()
4. 饼图 - 占比分析
# 市场份额数据
categories = ['电商', '线下零售', '批发', '跨境电商', '其他']
market_share = [35, 25, 20, 15, 5]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
explode = (0.1, 0, 0, 0, 0) # 突出显示第一项
fig, ax = plt.subplots(figsize=(10, 8))
# 绘制饼图
wedges, texts, autotexts = ax.pie(market_share, explode=explode, labels=categories,
colors=colors, autopct='%1.1f%%', shadow=True,
startangle=90, textprops={'fontsize': 12})
# 美化百分比文本
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
ax.set_title('销售渠道市场份额分布', fontsize=16, fontweight='bold', pad=20)
plt.tight_layout()
plt.show()
实战案例:简单的薪资数据分析
第一步、下载数据集到本地
🔗 点击访问完整项目:数据集和Jupyter Notebook

第二步、启动jupyter notebook
如果有小伙伴没有使用过jupyter notebook的,可以先往后看,后面再自己实践。
第三步、导入并查看数据的基础信息

第四步、数据清洗(载入、去重、处理缺失值、格式调整、异常值处理)

第五步、可视化分析(部分展示,具体可看下载的笔记本)








第六步、总结分析

这是我简单展示的一个流程,但在你实际操作中,你可以完成更多的数据操作和分析,写出更多也更有价值的信息。
结束语
可能刚开始接触数据分析的你,会觉得上面的东西很繁琐,很难记忆,也不清楚自己究竟该怎么来学习数据分析,我完全理解你的感受。确实,对于刚接触数据分析的朋友来说,面对这么多的函数、方法和概念,很容易感到不知所措。
让我们换个角度来看待这个问题:学习数据分析其实很像学做菜。第一次进厨房时,看到满架的调料、各种厨具,也会觉得无从下手。但当你真正动手做几道菜后,就会发现常用的也就那几样,慢慢地就知道什么菜该放什么调料了。
数据分析也是如此。你现在不需要记住每一个函数、每一个参数,更重要的是理解整个流程——拿到数据后怎么清洗、怎么探索、怎么用合适的图表呈现结果。具体的函数用法,完全可以在用的时候查文档,或者翻回这篇文章看看。
我建议你先找个自己感兴趣的小数据集进行练习。比如分析一下电商销量、电影评分、天气变化,或者你感兴趣的任何话题。在实践中遇到问题时,再回头来看相关的知识点,这样学起来既扎实又有趣。
最后,求点赞、收藏、评论,这将成为我不断更新的动力。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)