目录
Matplotlib
Matplotlib 是一个功能强大的 Python 绘图库,广泛用于数据可视化。
1. 导入 Matplotlib 并创建图布
首先,我们需要导入 Matplotlib 和 NumPy,并创建图布(figure)。图布是所有绘图的容器,可以包含一个或多个子图(axes)。
import matplotlib.pyplot as plt
import numpy as np
# 创建一个图布
fig = plt.figure(figsize=(8, 6), dpi=100)
figsize=(width, height)
: 图布的宽度和高度(以英寸为单位)。dpi
: 每英寸的点数(决定图像的分辨率)。
2. 实现基础绘图
Matplotlib 提供了多种图表类型。以下示例展示了如何创建折线图、柱状图、散点图和直方图。
2.1 折线图
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('X axis')
plt.ylabel('Y axis')
plt.show()
2.2 柱状图
categories = ['A', 'B', 'C', 'D']
values = [3, 7, 2, 5]
plt.bar(categories, values)
plt.title('Bar Chart')
plt.show()
2.3 散点图
x = np.random.rand(100)
y = np.random.rand(100)
plt.scatter(x, y)
plt.title('Scatter Plot')
plt.show()
2.4 直方图
data = np.random.randn(1000)
plt.hist(data, bins=30)
plt.title('Histogram')
plt.show()
3. 完善绘图辅助功能
为了让图表更加清晰和美观,可以添加标题、标签、图例和网格线。
3.1 添加标题和标签
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('X axis')
plt.ylabel('Y axis')
plt.show()
3.2 添加网格线
plt.plot(x, y)
plt.grid(True)
plt.title('Sine Wave with Grid')
plt.show()
3.3 添加图例
plt.plot(x, y, label='Sine')
plt.plot(x, np.cos(x), label='Cosine')
plt.legend()
plt.title('Sine and Cosine')
plt.show()
4. 在一个坐标系下绘制多个图像
可以在同一坐标系内绘制多个图形,通过多次调用 plot()
实现。
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x, y1, label='Sine')
plt.plot(x, y2, label='Cosine')
plt.legend()
plt.title('Multiple Plots on Same Axes')
plt.show()
5. 在一个图形窗口创建多个子图
Matplotlib 允许在一个图形窗口中创建多个子图。你可以使用 add_subplot()
或 subplots()
方法。
5.1 使用 add_subplot()
方法
fig = plt.figure()
ax1 = fig.add_subplot(2, 1, 1) # 创建一个2行1列的布局,添加第1个子图
ax2 = fig.add_subplot(2, 1, 2) # 创建第2个子图
ax1.plot(x, np.sin(x))
ax1.set_title('Sine Wave')
ax2.plot(x, np.cos(x))
ax2.set_title('Cosine Wave')
plt.tight_layout() # 自动调整子图间的间距
plt.show()
5.2 使用 subplots()
方法
subplots()
是一种便捷的方法,它不仅可以创建图布,还可以一次性创建多个子图。
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
axs[0, 0].plot(x, np.sin(x))
axs[0, 0].set_title('Sine')
axs[0, 1].plot(x, np.cos(x))
axs[0, 1].set_title('Cosine')
axs[1, 0].plot(x, np.tan(x))
axs[1, 0].set_title('Tangent')
axs[1, 1].plot(x, np.log(x+1))
axs[1, 1].set_title('Logarithm')
plt.tight_layout()
plt.show()
Numpy
NumPy 是 Python 中用于科学计算的基础库,它提供了支持大规模多维数组与矩阵运算的功能。此外,NumPy 还包含许多数学函数,可以方便地操作这些数组。
ndarray 介绍
在 NumPy 中,最重要的对象是 ndarray
,这是一个多维数组对象,用于存储元素为相同类型的集合。ndarray
支持向量化操作,性能上要优于传统的 Python 列表。
ndarray 的基本属性
ndim
: 数组的维度。shape
: 数组的形状,表示各维度大小的元组。size
: 数组元素的总个数。dtype
: 数组元素的数据类型。
创建数组
1. 创建全零数组
使用 np.zeros()
可以创建全零数组。
import numpy as np
# 创建一个3x3的全零数组
zeros_array = np.zeros((3, 3))
print(zeros_array)
2. 创建全一数组
使用 np.ones()
可以创建全一数组。
# 创建一个2x4的全一数组
ones_array = np.ones((2, 4))
print(ones_array)
3. 创建固定范围的数组
使用 np.arange()
或 np.linspace()
创建特定范围内的数组。
# 使用arange创建一个从0到9的数组
range_array = np.arange(10)
print(range_array)
# 使用linspace创建一个从0到1的等间距数组,包含5个元素
linspace_array = np.linspace(0, 1, 5)
print(linspace_array)
4. 创建随机数组
NumPy 提供了多种方法来创建随机数组,如 np.random.rand()
、np.random.randint()
。
# 创建一个3x3的随机浮点数组,值在0到1之间
random_array = np.random.rand(3, 3)
print(random_array)
# 创建一个2x2的随机整数数组,值在0到10之间
random_int_array = np.random.randint(0, 10, size=(2, 2))
print(random_int_array)
数组的基本操作
1. 数组的访问和切片
可以像访问列表一样访问 NumPy 数组的元素,并可以进行切片操作。
array = np.array([1, 2, 3, 4, 5])
# 访问第一个元素
print(array[0])
# 访问最后一个元素
print(array[-1])
# 切片操作,获取数组中的一部分
print(array[1:4])
2. 改变数组形状
使用 reshape()
可以改变数组的形状,但元素总数必须匹配。
array = np.arange(12)
reshaped_array = array.reshape((3, 4))
print(reshaped_array)
3. 数组的合并与拆分
可以使用 np.concatenate()
合并数组,使用 np.split()
拆分数组。
array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])
# 合并两个数组
merged_array = np.concatenate((array1, array2))
print(merged_array)
# 拆分数组
split_array = np.split(merged_array, 3)
print(split_array)
多维数组
多维数组是 ndarray
的一个重要特性,可以处理高维数据(2D、3D 及以上)。多维数组的操作与一维数组相似,但需要考虑多个维度。
1. 创建多维数组
# 创建一个2x3x4的三维数组
multi_dim_array = np.zeros((2, 3, 4))
print(multi_dim_array)
2. 访问多维数组元素
多维数组元素的访问可以通过多个索引完成,每个索引对应数组的一个维度。
# 创建一个2x3的二维数组
array_2d = np.array([[1, 2, 3], [4, 5, 6]])
# 访问第一行第二列的元素
print(array_2d[0, 1]) # 输出: 2
# 访问整个第二行
print(array_2d[1, :]) # 输出: [4 5 6]
3. 改变多维数组的形状
可以使用 reshape()
改变数组形状,但元素总数必须匹配。
array = np.arange(12)
reshaped_array = array.reshape((3, 4)) # 将一维数组变为3x4的二维数组
print(reshaped_array)
4. 多维数组的切片操作
多维数组支持切片操作,可以选取数组的子集。
# 创建一个3x4的二维数组
array_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# 获取第二行的前两列
print(array_2d[1, :2]) # 输出: [5 6]
# 获取第二列
print(array_2d[:, 1]) # 输出: [ 2 6 10]
ndarray 的运算
NumPy 支持对 ndarray
进行各种数学运算,包括加减乘除、幂运算等。
array = np.array([1, 2, 3, 4])
# 数组元素加2
print(array + 2)
# 数组元素乘3
print(array * 3)
# 数组元素求平方
print(array ** 2)
数组间运算
数组间运算包括点对点的加减乘除运算,以及矩阵运算。
array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])
# 点对点加法
print(array1 + array2)
# 点对点乘法
print(array1 * array2)
# 矩阵乘法
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])
print(np.dot(matrix1, matrix2)) # 或者使用 matrix1 @ matrix2
Pandas
Pandas 是一个用于数据操作和分析的 Python 库,特别适合处理结构化数据。它提供了两个核心数据结构:Series
和 DataFrame
,能够处理各种类型的数据。
Pandas 数据结构
1. Series
Series
是 Pandas 中的一维数据结构,可以看作是带标签的数组。每个元素都有一个索引,可以通过索引快速访问数据。
import pandas as pd
# 创建一个带有默认索引的Series
s1 = pd.Series([1, 2, 3, 4])
# 创建一个带有自定义索引的Series
s2 = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
# 创建一个从字典生成的Series
data = {'a': 100, 'b': 200, 'c': 300}
s3 = pd.Series(data)
# 访问Series元素
first_element = s2['a']
2. DataFrame
DataFrame
是 Pandas 中最常用的二维数据结构,类似于数据库中的表格或 Excel 表格。它由多个 Series
组成,每列可以有不同的数据类型。
# 创建一个空的DataFrame
df1 = pd.DataFrame()
# 从列表生成DataFrame
data_list = [['Alice', 24], ['Bob', 27], ['Charlie', 22]]
df2 = pd.DataFrame(data_list, columns=['Name', 'Age'])
# 从字典生成DataFrame
data_dict = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [24, 27, 22]}
df3 = pd.DataFrame(data_dict)
# 从嵌套字典生成DataFrame
data_nested_dict = {'Name': {0: 'Alice', 1: 'Bob'}, 'Age': {0: 24, 1: 27}}
df4 = pd.DataFrame(data_nested_dict)
# 查看DataFrame的基本信息
df_info = df3.info()
# 访问DataFrame元素
first_row = df3.iloc[0] # 通过位置访问
name_column = df3['Name'] # 通过列名访问
Pandas 中的索引、赋值和排序
1. 索引
Pandas 提供了多种索引方式,可以通过 .loc
和 .iloc
来进行标签或位置的索引。
# 通过标签索引
name_alice = df3.loc[0, 'Name'] # 获取第一行 'Name' 列的值
# 通过位置索引
age_bob = df3.iloc[1, 1] # 获取第二行第二列的值
# 切片操作
subset_df = df3.loc[0:1, 'Name':'Age'] # 获取第一行到第二行、'Name' 列到 'Age' 列的数据
2. 赋值
Pandas 允许通过索引直接修改数据。
# 修改DataFrame中的值
df3.loc[0, 'Age'] = 25 # 将 'Age' 列第一行的值修改为 25
# 增加新列
df3['City'] = ['New York', 'Los Angeles', 'Chicago'] # 新增 'City' 列,并赋值
3. 排序
可以使用 sort_values()
按值排序,使用 sort_index()
按索引排序。
# 按列值排序
df_sorted_by_age = df3.sort_values(by='Age') # 按 'Age' 列升序排序
# 按索引排序
df_sorted_by_index = df3.sort_index() # 按行索引排序
Pandas 中的统计函数
Pandas 提供了多种统计函数,可以对数据进行描述性统计分析。
# 基本统计信息
df_description = df3.describe() # 返回数值型数据的汇总统计
# 单独计算统计量
mean_age = df3['Age'].mean() # 计算 'Age' 列的平均值
sum_age = df3['Age'].sum() # 计算 'Age' 列的总和
# 计数操作
age_count = df3['Age'].count() # 计算 'Age' 列中非空值的数量
Pandas 中的累计统计函数和自定义函数
Pandas 支持累计统计函数,并允许自定义函数应用于数据。
1. 累计统计函数
# 累计和
cumsum_age = df3['Age'].cumsum() # 计算 'Age' 列的累计和
# 累计乘积
cumprod_age = df3['Age'].cumprod() # 计算 'Age' 列的累计乘积
2. 自定义函数
你可以使用 apply()
方法将自定义函数应用于 Series
或 DataFrame
。
# 自定义函数应用到列上
df3['Age_double'] = df3['Age'].apply(lambda x: x * 2) # 将 'Age' 列的值乘以 2
# 自定义函数应用到整个DataFrame上
df3_transformed = df3.applymap(lambda x: str(x).upper() if isinstance(x, str) else x) # 将所有字符串转换为大写
Pandas 中绘图方式介绍
Pandas 提供了便捷的绘图功能,可以通过 plot()
方法快速生成各种类型的图表。
# 绘制柱状图
df3['Age'].plot(kind='bar', title='Age Distribution')
# 绘制折线图
df3['Age'].plot(kind='line', title='Age Trend')
# 绘制直方图
df3['Age'].plot(kind='hist', title='Age Histogram')
Pandas 中文件的读取和写入
Pandas 提供了与多种文件格式的交互功能,支持文件的读取和写入操作。
1. 读取文件
# 读取CSV文件
df_csv = pd.read_csv('data.csv') # 从文件 'data.csv' 中读取数据
# 读取Excel文件
df_excel = pd.read_excel('data.xlsx') # 从文件 'data.xlsx' 中读取数据
# 读取SQL数据库
import sqlite3
conn = sqlite3.connect('database.db')
df_sql = pd.read_sql('SELECT * FROM table_name', conn) # 从SQLite数据库中读取数据
2. 写入文件
# 写入CSV文件
df3.to_csv('output.csv', index=False) # 将数据写入到 'output.csv' 文件中,不包含行索引
# 写入Excel文件
df3.to_excel('output.xlsx', index=False) # 将数据写入到 'output.xlsx' 文件中,不包含行索引
缺失值的处理
Pandas 提供了多种方法来处理数据中的缺失值。
1. 删除缺失值
# 删除包含缺失值的行
df_cleaned = df3.dropna() # 删除包含 NaN 的行
# 删除包含缺失值的列
df_cleaned_columns = df3.dropna(axis=1) # 删除包含 NaN 的列
2. 填充缺失值
# 用指定值填充缺失值
df_filled = df3.fillna(0) # 将所有缺失值填充为 0
# 用前一个有效值填充缺失值
df_filled_ffill = df3.fillna(method='ffill') # 前向填充
# 用后一个有效值填充缺失值
df_filled_bfill = df3.fillna(method='bfill') # 后向填充
数据离散化
数据离散化是将连续变量转换为离散变量的过程,Pandas 提供了 cut()
和 qcut()
函数来实现这一功能。
# 使用 cut() 将年龄分为三个区间
df3['Age_group'] = pd.cut(df3['Age'], bins=3, labels=['Young', 'Middle', 'Old'])
# 使用 qcut() 按照分位数离散化
df3['Age_quantile'] = pd.qcut(df3['Age'], q=4, labels=False) # 将 'Age' 列按四分位数分为4组
数据表的合并
Pandas 提供了多种方法来合并多个数据表,常用的方法包括 merge()
、join()
和 concat()
。
# 创建两个DataFrame用于合并
df_left = pd.DataFrame({'key': ['A', 'B', 'C'], 'value_left': [1, 2, 3]})
df_right = pd.DataFrame({'key': ['A', 'B', 'D'], 'value_right': [4, 5, 6]})
# 使用 merge() 进行合并
df_merged = pd.merge(df_left, df_right, on='key', how='inner') # 按照 'key' 列进行内连接
# 使用 concat() 进行合并
df_concat = pd.concat([df_left, df_right], axis=0, ignore_index=True) # 按行合并,忽略原始索引
交叉表和透视表介绍
Pandas 的交叉表和透视表功能用于汇总和聚合数据,是数据分析中的常用工具。
1. 交叉表
交叉表用于计算两个或多个分类变量之间的关系。
# 创建一个交叉表
cross_tab = pd.crosstab(df3['City'], df3['Age_group']) # 按城市和年龄组创建交叉表
2. 透视表
透视表是用来汇总和计算分类数据的统计表格,类似于 Excel 的透视表功能。
# 创建一个透视表
pivot_table = df3.pivot_table(values='Age', index='City', columns='Age_group', aggfunc='mean') # 计算不同城市和年龄组的平均年龄
分组聚合介绍
分组聚合是数据分析中常用的操作,通过对数据进行分组,可以对不同组的数据应用聚合函数,得到分组统计结果。
# 按城市分组并计算年龄的平均值
grouped = df3.groupby('City')['Age'].mean() # 计算不同城市的平均年龄
# 多列分组聚合
grouped_multi = df3.groupby(['City', 'Age_group'])['Age'].agg(['mean', 'sum']) # 按城市和年龄组分组,并计算平均值和总和