Python 数据分析中最重要的三个库:Matplotlib、NumPy 和 Pandas,这三个库是 Python 数据分析领域的基石,它们通常配合使用,构成了一个强大而高效的数据处理、分析和可视化工具集。
1. NumPy (Numerical Python)
是什么?
NumPy 是 Python 中用于科学计算的核心库。它提供了一个高性能的多维数组对象( ndarray
)以及用于处理这些数组的工具。可以理解为 Python 中进行数值计算的基础,尤其擅长处理大型数组和矩阵。
核心数据结构
ndarray
(N-dimensional array):这是 NumPy 最重要的对象。它是一个同质的(所有元素类型相同)多维数组,其元素在 内存中是连续存储 的。这使得 NumPy 在处理大量数值数据时比 Python 内置的列表(list)更高效。
主要特点和功能
-
高效的多维数组对象:
ndarray
的速度和内存效率远高于 Python 的列表,尤其是在处理大型数据集时。 -
广播 (Broadcasting): NumPy 允许对形状不同的数组进行算术运算,而无需显式地改变数组形状。它会自动调整较小数组的形状以匹配较大数组,然后执行元素级运算。
-
向量化运算: NumPy支持对整个数组进行元素级运算,而无需编写显式的循环。例如,两个 NumPy 数组相加,会自动将对应位置的元素相加。这种向量化操作通常比 Python 循环快得多。
-
数学函数库: 提供了大量的数学函数(通用函数
ufunc
),可以对数组中的每个元素进行操作,如 sin, cos, exp, sqrt 等。 -
线性代数、傅里叶变换、随机数生成等功能: 内置了丰富的数学和统计函数模块,方便进行复杂的数值计算。
-
与其他库的集成: NumPy 是许多其他科学计算库(包括 Pandas、Matplotlib、SciPy、scikit-learn 等)的基础。
为什么重要?
-
性能: 底层实现由 C 或 Fortran 编写,计算速度非常快,是 Python 进行大规模数值计算的首选。
-
基础: 它提供了高效的数据结构和计算能力,是构建更高级数据分析库(如 Pandas)的基础。
-
简洁: 通过向量化操作,可以用更少的代码完成复杂的数值计算任务。
简单示例
import numpy as np
# 创建一个NumPy数组
arr1 = np.array([1, 2, 3, 4, 5])
print("NumPy 数组 arr1:", arr1)
print("数组类型:", type(arr1))
print("数组维度:", arr1.shape) # (5,) 表示1维,5个元素
# 创建一个二维数组 (矩阵)
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print("\nNumPy 数组 arr2 (二维):\n", arr2)
print("数组维度:", arr2.shape) # (2, 3) 表示2行3列
# 向量化运算:数组与标量相乘
arr_mult = arr1 * 2
print("\narr1 * 2:", arr_mult) # 每个元素都乘以2
# 向量化运算:两个数组相加 (要求形状相同)
arr3 = np.array([5, 4, 3, 2, 1])
arr_sum = arr1 + arr3
print("arr1 + arr3:", arr_sum) # 对应元素相加
# 广播示例:二维数组与一维数组相加
arr4 = np.array([10, 20, 30])
arr_broadcast = arr2 + arr4 # [10, 20, 30] 会被广播成 [[10, 20, 30], [10, 20, 30]]
print("\narr2 + arr4 (广播):\n", arr_broadcast)
# 使用通用函数
arr_sqrt = np.sqrt(arr1)
print("arr1 的平方根:", arr_sqrt)
# 线性代数:矩阵乘法 (使用 @ 运算符 或 np.dot())
mat1 = np.array([[1, 2], [3, 4]])
mat2 = np.array([[5, 6], [7, 8]])
mat_prod = mat1 @ mat2 # 或 np.dot(mat1, mat2)
print("\n矩阵乘法:\n", mat_prod)
2. Pandas (Panel Data)
是什么
Pandas 是一个强大的开源库,用于进行数据操作、分析和清洗。它构建在 NumPy 之上,提供了更高级、更易于使用的 带标签的数据结构,特别适合处理表格数据(类似电子表格或数据库表)。
核心数据结构
-
Series
:一维带标签的数组。可以看作是一个带有索引(index)的 NumPy 数组,或者一个定长的有序字典。它由数据(values)和与之关联的索引(index)组成。 -
DataFrame
:二维带标签的数据结构,是 Pandas 中最常用的对象。可以看作是由多个Series
组成,共享同一个索引(行索引),同时每列有自己的标签(列名)。它非常类似于电子表格或 SQL 表。
主要特点和功能
-
灵活的数据读取和写入: 支持读取多种格式的数据文件,如 CSV (
pd.read_csv
)、Excel (pd.read_excel
)、SQL 数据库 (pd.read_sql
)、JSON、HDF5 等,并能方便地将数据写入这些格式。 -
便捷的数据清洗和准备: 轻松处理缺失数据 (
isnull()
,dropna()
,fillna()
)、重复数据 (drop_duplicates()
)、数据转换、数据重塑(pivot
,melt
)等。 -
强大的数据选择、过滤和切片: 基于标签 (
.loc[]
) 或整数位置 (.iloc[]
) 进行灵活的数据子集选取。 -
数据对齐: 在进行数据操作时,Pandas 会根据索引自动对齐数据,避免因为顺序不同导致错误。
-
分组聚合 (GroupBy): 提供非常灵活的分组(
groupby()
)和聚合(agg()
,sum()
,mean()
,count()
等)功能,用于按某个或多个键对数据进行分组,然后对每个组执行计算。 -
数据合并和连接: 支持类似数据库的合并(
merge()
)和连接(concat()
)操作,用于组合来自不同来源的数据。 -
时间序列功能: 对时间序列数据有专门的支持,包括日期范围生成、频率转换、移动窗口统计等。
-
内置可视化: Pandas 的对象(Series 和 DataFrame)拥有基于 Matplotlib 的绘图方法,可以直接快速绘制数据。
为什么重要?
-
易用性: 提供了直观易懂的数据结构和丰富的操作方法,使得数据清洗、转换和分析变得非常便捷。
-
功能全面: 涵盖了数据处理、分析的绝大部分常见任务。
-
与实际数据结构匹配: DataFrame 完美契合了现实世界中常见的表格数据形式。
简单示例
import pandas as pd
import numpy as np # Pandas 内部使用 NumPy
# 创建一个Series
s = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])
print("Pandas Series:\n", s)
print("Series 值:", s.values)
print("Series 索引:", s.index)
# 创建一个DataFrame
data = {
'城市': ['北京', '上海', '广州', '深圳', '成都'],
'人口': [2154, 2487, 1530, 1756, 1633], # 假设单位万人
'面积': [16411, 6340, 7434, 1997, 14335], # 假设单位平方公里
'是否省会': [True, False, False, False, True]
}
df = pd.DataFrame(data)
print("\nPandas DataFrame:\n", df)
# 查看 DataFrame 的基本信息
print("\nDataFrame 信息:")
df.info()
# 查看 DataFrame 的前几行
print("\nDataFrame 前2行:")
print(df.head(2))
# 选择单列 (返回一个Series)
population = df['人口']
print("\n'人口' 列:\n", population)
# 选择多列 (返回一个DataFrame)
subset = df[['城市', '人口']]
print("\n'城市' 和 '人口' 列:\n", subset)
# 使用 .loc[] 按标签选择行和列
row_guangzhou = df.loc[2] # 按索引标签2选择行
print("\n索引为2的行 (广州):\n", row_guangzhou)
subset_beijing_shanghai = df.loc[0:1, ['城市', '人口']] # 选择索引为0和1行的'城市'和'人口'列
print("\n索引0和1行的'城市'和'人口'列:\n", subset_beijing_shanghai)
# 使用 .iloc[] 按位置选择行和列
first_row = df.iloc[0] # 选择第0行 (第一行)
print("\n第一行:\n", first_row)
subset_by_pos = df.iloc[[0, 4], [0, 1]] # 选择第0行和第4行,以及第0列和第1列
print("\n位置0和4行的位置0和1列:\n", subset_by_pos)
# 条件过滤
large_cities = df[df['人口'] > 1700] # 选择人口大于1700万的城市
print("\n人口大于1700万的城市:\n", large_cities)
# 添加新列
df['人口密度'] = df['人口'] / df['面积'] * 10000 # 计算人口密度 (人/平方公里)
print("\n添加'人口密度'列后的DataFrame:\n", df)
# 分组聚合 (虽然这个小例子分组意义不大,但展示用法)
# grouped = df.groupby('是否省会')['人口'].mean()
# print("\n按是否省会分组计算人口均值:\n", grouped)
3. Matplotlib
是什么?
Matplotlib 是一个用于创建出版质量图表的 Python 库。它可以生成各种静态、动态、交互式的图表,是数据可视化的重要工具。
核心概念
-
Figure (图形对象): 是最高层级的容器,包含了所有的绘图元素(如 Axes, Title, Labels)。一个 Figure 可以包含一个或多个 Axes。
-
Axes (坐标系/子图): 是绘图区域,实际的数据图形(如折线、散点、柱状图等)就是绘制在 Axes 上。每个 Axes 都有 x 轴、y 轴(对于二维图表)以及标题、标签等。通常通过
plt.subplots()
或fig.add_subplot()
创建。 -
Artist (艺术家): 图形上的所有可见元素都是 Artist 对象,例如 Line2D(线)、Text(文本)、Patch(矩形、圆形等)、Collection(散点集合)等。
两种使用接口
-
Pyplot 接口 (
matplotlib.pyplot
) : 基于状态机,提供了一系列函数(如plot()
,scatter()
,xlabel()
,title()
,show()
)。使用简单快捷,适合快速生成图表,但对于复杂图表控制稍显不足。 -
面向对象 (Object-Oriented) 接口: 通过创建 Figure 和 Axes 对象,然后调用对象的方法来创建和修改图表。更灵活和强大,适合定制复杂图表。这是 Matplotlib 推荐的用法。
主要特点和功能
-
丰富的图表类型: 支持绘制折线图 (
plot
)、散点图 (scatter
)、柱状图 (bar
)、直方图 (hist
)、饼图 (pie
)、箱线图 (boxplot
)、热力图 (imshow
) 等多种图表。 -
高度可定制: 可以精细地控制图表的每一个元素,包括线条样式、颜色、标记、文本、标题、坐标轴刻度、图例等。
-
多子图布局: 可以在同一个 Figure 中创建多个 Axes,方便进行多图对比展示 (
plt.subplots()
)。 -
导出多种格式: 可以将图表保存为多种文件格式,如 PNG、JPG、SVG、PDF 等。
-
集成性好: 可以直接使用 NumPy 数组和 Pandas DataFrame/Series 进行绘图。
为什么重要?
-
可视化: 将数据转化为图形,帮助人们更直观地理解数据的分布、趋势、关系和模式。
-
沟通: 精美的图表是数据分析结果的重要呈现方式,便于与他人沟通分析结果。
-
探索性分析 (EDA): 在数据分析的早期阶段,快速生成图表有助于发现数据中的异常和规律。
简单示例 (使用 Pyplot 接口)
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd # 展示与Pandas的结合
# 绘制简单的折线图
x = np.linspace(0, 10, 100) # 生成0到10之间100个点的数组
y = np.sin(x) # 计算每个点的sin值
plt.figure(figsize=(8, 4)) # 创建一个图形对象,并设置大小
plt.plot(x, y, label='sin(x)', color='blue', linestyle='--') # 绘制折线图
plt.xlabel('x 轴') # 设置x轴标签
plt.ylabel('y 轴') # 设置y轴标签
plt.title('简单的 sin(x) 函数图') # 设置图表标题
plt.legend() # 显示图例
plt.grid(True) # 显示网格线
plt.show() # 显示图表
# 绘制散点图
x_scatter = np.random.rand(50) # 生成50个随机x坐标
y_scatter = np.random.rand(50) # 生成50个随机y坐标
colors = np.random.rand(50) # 随机颜色
sizes = 1000 * np.random.rand(50) # 随机大小
plt.figure(figsize=(6, 6))
plt.scatter(x_scatter, y_scatter, c=colors, s=sizes, alpha=0.5) # alpha设置透明度
plt.title('随机散点图')
plt.xlabel('X 值')
plt.ylabel('Y 值')
plt.colorbar(label='颜色深浅') # 添加颜色条
plt.show()
# 使用 Pandas 数据绘制柱状图 (Pandas调用Matplotlib)
df_cities = pd.DataFrame({
'城市': ['北京', '上海', '广州', '深圳'],
'人口': [2154, 2487, 1530, 1756]
})
plt.figure(figsize=(7, 5))
df_cities.plot(x='城市', y='人口', kind='bar', legend=False) # 直接调用DataFrame的plot方法
plt.title('城市人口柱状图')
plt.xlabel('城市')
plt.ylabel('人口 (万人)')
plt.xticks(rotation=0) # x轴标签不旋转
plt.show()
三者如何协同工作?
在典型的数据分析流程中,这三个库经常按以下方式配合使用:
-
Pandas: 用于加载、清洗、处理和组织数据。将原始数据读入 Pandas DataFrame,进行缺失值处理、数据转换、格式调整、合并等操作。
-
NumPy: 在 Pandas 内部被广泛使用,也用于执行一些更底层的数值计算、数组操作或数学函数应用。当你需要在 DataFrame/Series 的数据上执行高性能的数组运算时,NumPy 的功能会非常有用。
-
Matplotlib: 用于将处理后的数据进行可视化。你可以直接使用 Matplotlib 的函数(如
plt.plot()
,plt.scatter()
)传入 NumPy 数组或 Pandas Series/DataFrame 中的数据列进行绘制。或者,更常见的是直接调用 Pandas DataFrame/Series 内置的.plot()
方法,这些方法实际上是调用了 Matplotlib 进行绘图,使用起来更加方便。
总结
-
NumPy: 提供高性能的多维数组和基础数值运算能力,是底层计算核心。
-
Pandas: 提供易用的数据结构(DataFrame, Series)和丰富的数据处理、清洗、转换功能,是数据整理和分析的主要工具。
-
Matplotlib: 提供强大的数据可视化能力,用于将数据结果呈现为图表。
这三个库共同构成了 Python 数据分析的强大生态系统,掌握它们是进行高效数据分析的关键。