数据分析学习笔记
数据分析学习笔记

数据分析学习笔记

Python 数据分析学习笔记

基于 pandas 官方文档及当前项目 Demo 代码总结,涵盖 NumPy、Pandas、Matplotlib 三大核心库。


目录


一、NumPy 基础

NumPy 是 Python 科学计算的基础库,核心是 ndarray(N 维数组)。

1.1 数组创建

import numpy as np

# 从列表创建
arr = np.array([1, 2, 3, 4])
arr2d = np.array([[1, 2], [3, 4]])

# 特殊数组
np.zeros((3, 4))          # 全 0 数组,shape=(3,4)
np.ones((2, 3))           # 全 1 数组
np.full((2, 2), 7.5)      # 填充指定值
np.eye(3)                 # 3x3 单位矩阵
np.empty((2, 3))          # 未初始化数组(值随机)

# 序列生成
np.arange(0, 10, 2)       # [0, 2, 4, 6, 8],类似 range()
np.linspace(0, 1, 5)      # [0.0, 0.25, 0.5, 0.75, 1.0],等间距 5 个点

1.2 数组属性

arr.shape      # 形状元组,如 (3, 5)
arr.ndim       # 维度数
arr.dtype      # 元素数据类型,如 int64、float64
arr.size       # 元素总数

1.3 索引与切片

arr[2:5]           # 基本切片(视图,共享内存)
arr[:, 1:3]        # 二维:所有行的第 1-2 列
arr[arr > 5]       # 布尔索引,返回满足条件的一维数组

1.4 聚合函数

np.sum(arr, axis=0)    # axis=0 列求和,axis=1 行求和
np.mean(arr)           # 平均值
np.std(arr)            # 标准差
np.min(arr) / np.max(arr)
np.argmin(arr) / np.argmax(arr)  # 最值位置

1.5 广播机制(Broadcasting)

不同形状的数组在进行运算时会自动扩展维度:

arr = np.array([[1, 2, 3], [4, 5, 6]])  # shape (2, 3)
arr + 10                      # 标量广播到每个元素
arr + np.array([1, 2, 3])     # 形状 (3,) 广播到 (2, 3)

1.6 随机数生成

rng = np.random.default_rng(seed=42)   # 推荐方式(可复现)
rng.random((2, 3))                     # [0, 1) 均匀分布
rng.standard_normal((3, 4))            # 标准正态分布
rng.integers(0, 10, size=5)            # 随机整数

# 旧版 API(不推荐)
# np.random.rand(3, 2)
# np.random.seed(42)

二、Pandas 基础

2.1 核心数据结构

DataFrame(二维表格)

import pandas as pd

df = pd.DataFrame({
    "Name": ["Braund, Mr. Owen Harris", "Allen, Mr. William Henry"],
    "Age": [22, 35],
    "Sex": ["male", "male"],
})
print(df)

Series(单列数据)

ages = pd.Series([22, 11, 23], name="Age")
print(ages)

2.2 数据读写(I/O)

# CSV 读入
titanic = pd.read_csv("data/titanic.csv")

# CSV 写出
titanic.to_csv("output.csv", index=False)

# Excel 读写
titanic.to_excel("titanic.xlsx", sheet_name="passengers", index=False)
df = pd.read_excel("titanic.xlsx", sheet_name="passengers")

常用参数:

参数 说明
sep=',' 分隔符(如 '\t' 用于 TSV)
header=0 列名所在行,None 表示无列名
index_col=0 指定某列为行索引
parse_dates=True 自动解析日期列

2.3 数据查看与检查

df.head(8)        # 查看前 N 行(默认 5)
df.tail(10)       # 查看后 N 行
df.dtypes         # 各列数据类型
df.info()         # 技术摘要:行数、列数、数据类型、内存、非空数
df.shape          # 元组 (行数, 列数)
df.describe()     # 数值列的统计信息:count、mean、std、min、25%、50%、75%、max

注意: describe() 默认只统计数值列,文本列会被自动忽略。

2.4 数据筛选与索引

选择列

titanic["Age"]            # 返回 Series
titanic[["Age", "Fare"]]  # 返回 DataFrame

条件过滤(布尔索引)

# 单条件
above = titanic[titanic["Age"] > 35]

# 多条件:使用 &(与)、|(或)、~(非)
class_23 = titanic[titanic["Pclass"].isin([2, 3])]

# 非空筛选
age_no_na = titanic[titanic["Age"].notna()]

loc:标签索引(左闭右闭)

adult_names = titanic.loc[titanic["Age"] > 35, "Name"]   # 条件 + 指定列
titanic.loc[0:5, ["Name", "Age"]]                         # 行切片(含5)+ 指定列

iloc:位置索引(左闭右开)

titanic.iloc[9:25, 2:5]          # 第 9-24 行,第 2-4 列
titanic.iloc[0:3, 3] = "wsj"     # 赋值

2.5 聚合与分组

基本统计

titanic["Age"].mean()                     # 平均值
titanic[["Age", "Fare"]].median()         # 中位数
titanic["Age"].min() / .max() / .std()   # 最小值 / 最大值 / 标准差

agg:自定义多指标聚合

titanic.agg({
    "Age": ["min", "max", "median", "skew"],
    "Fare": ["min", "max", "median", "mean"],
})

groupby:分组聚合

# 按性别分组,计算均值
titanic[["Sex", "Age"]].groupby("Sex").mean()

# 在分组数据上选择列
titanic.groupby("Sex")["Age"].mean()

# 多列分组
titanic.groupby(["Sex", "Pclass"])["Fare"].mean()

# 计算每个组的记录数
titanic.groupby("Pclass")["Pclass"].count()

value_counts:计数

titanic["Pclass"].value_counts()          # 每个类别的出现次数

2.6 排序

# 单列排序
titanic.sort_values(by="Age")

# 多列排序(先按 Pclass 降序,再按 Age 降序)
titanic.sort_values(by=["Pclass", "Age"], ascending=False)

2.7 数据重塑(长宽表转换)

长表 → 宽表:pivot

# 将每个 location 的值作为一列展示
no2.pivot(columns="location", values="value")
  • index:指定行索引(默认使用原始 index)
  • columns:指定哪一列的值成为新列名
  • values:指定填充到新列的数据

数据透视表:pivot_table

pivot_table 与 pivot 类似,但当有重复行时,会使用聚合函数合并:

air_quality.pivot_table(
    values="value",
    index="location",
    columns="parameter",
    aggfunc="mean",      # 聚合函数
    margins=True,        # 添加行列汇总
)

宽表 → 长表:melt

no2_pivoted.melt(id_vars="date.utc")

# 详细参数
no2_pivoted.melt(
    id_vars="date.utc",                        # 保留的标识列
    value_vars=["BETR801", "FR04014"],          # 需要融化的列
    value_name="NO_2",                          # 值列的新列名(默认"value")
    var_name="id_location",                     # 原列名列的新列名(默认"variable")
)

2.8 多表合并

concat:轴向拼接

# axis=0:纵向(行)拼接(上下堆叠)
air_quality = pd.concat([air_quality_pm25, air_quality_no2], axis=0)

# axis=1:横向(列)拼接

merge:数据库风格连接

# 内连接(默认):只保留两表共有的键
pd.merge(left_df, right_df, on="location")

# 左连接:保留左表所有行,右表匹配不到的填 NaN
pd.merge(air_quality, stations_coord, how="left", on="location")

# 两表列名不同时
pd.merge(air_quality, parameters_df,
         how="left", left_on="parameter", right_on="id")
how 选项 说明
'inner' 内连接(默认),取交集
'left' 左连接,保留左表所有行
'right' 右连接,保留右表所有行
'outer' 外连接,取并集

2.9 时间序列

转换为日期时间

air_quality["datetime"] = pd.to_datetime(air_quality["datetime"])

dt 访问器:提取日期组件

air_quality["datetime"].dt.month     # 月份
air_quality["datetime"].dt.hour      # 小时
air_quality["datetime"].dt.weekday   # 星期几(0=周一)
air_quality["datetime"].dt.year      # 年份
air_quality["datetime"].dt.day       # 日

按时间分组聚合

# 按星期几 + 地点分组求均值
air_quality.groupby(
    [air_quality["datetime"].dt.weekday, "location"]
)["value"].mean()

# 按每天的小时分组
air_quality.groupby(
    [air_quality["datetime"].dt.hour]
)["value"].mean().plot(kind="bar", rot=0)

日期时间作为索引

no_2 = air_quality.pivot(index="datetime", columns="location", values="value")

# 通过索引切片选择时间范围
no_2["2019-05-20":"2019-05-21"].plot()

重采样 resample

no_2.resample("MS").max()          # 每月最大值(MS = Month Start)
no_2.resample("D").mean()          # 每日均值(D = Day)

常用频率别名:

别名 说明 别名 说明
'D' 日历日 'H' 小时
'W' 周 'T' / 'min' 分钟
'MS' 月起始 'QS' 季度起始
'M' 月末 'YS' / 'AS' 年起始

2.10 文本处理

通过 .str 访问器操作字符串列:

titanic["Name"].str.lower()         # 转小写
titanic["Name"].str.split(",")      # 按分隔符拆分
titanic["Name"].str.contains("Mr")  # 是否包含子串
titanic["Name"].str.replace("Mr", "Mister")  # 替换
titanic["Name"].str.len()           # 字符串长度
titanic["Name"].str.strip()         # 去首尾空白

2.11 列操作与重命名

新增/计算列

# 新增计算列(单位转换:mg/m³ → µg/m³)
air_quality["london_mg_per_cubic"] = air_quality["station_london"] * 1.882

rename:重命名

air_quality.rename(columns={
    "station_antwerp": "BETR801",
    "station_paris": "FR04014",
    "station_london": "London Westminster",
})

三、可视化图表(Matplotlib + Pandas Plot)

3.1 Pandas 内置绘图(快速探索)

Pandas 的 plot() 方法是 Matplotlib 的包装,适合快速数据探索:

import matplotlib.pyplot as plt

# 全部列折线图
air_quality.plot()
plt.show()

# 单列折线图
air_quality["station_paris"].plot()
plt.show()

支持的图表类型

df.plot()               # 折线图(默认)
df.plot.scatter(x, y)   # 散点图
df.plot(kind="scatter", x="col1", y="col2", alpha=0.5)

df.plot.box()           # 箱线图

df.plot.bar()           # 柱状图
# 或 df.plot(kind="bar", rot=0)

df.plot.area(figsize=(12, 4), subplots=True)  # 面积图(可分面子图)

df.plot.hist()          # 直方图

3.2 Matplotlib 显式接口(推荐,更灵活)

Figure/Axes 模型

# 创建画布和坐标区
fig, axs = plt.subplots(figsize=(12, 4))

# 在坐标区上绘图
air_quality.plot.area(ax=axs)
axs.set_ylabel("NO$_2$ concentration")
axs.set_title("Air Quality Over Time")

# 保存
fig.savefig("no2_concentrations.png")

plt.show()

常用图表类型

# 折线图
ax.plot(x, y, 'o-', label="Series 1")

# 散点图
ax.scatter(x, y, s=size, c=color, alpha=0.5)

# 柱状图
ax.bar(x, height, width=0.8)

# 箱线图
ax.boxplot(data)

# 直方图
ax.hist(x, bins=50, alpha=0.75)

格式化字符串

fmt = '[marker][line][color]'
  • 标记(marker): 'o' 圆, '^' 三角, 's' 方形, 'D' 菱形, '*' 星
  • 线型(line): '-' 实线, '--' 虚线, ':' 点线, '-.' 点划线
  • 颜色(color): 'b' 蓝, 'r' 红, 'g' 绿, 'k' 黑, 'm' 品红, 'y' 黄

示例:'ro' 红色圆点, '--g' 绿色虚线, '^k:' 黑三角+点线

自定义设置

ax.set_xlabel("X Label")
ax.set_ylabel("Y Label")
ax.set_title("Title", fontsize=14)
ax.legend(loc='best')         # 图例位置:'upper right', 'upper left', 'lower left', 'center', 'best'
ax.set_xlim(0, 100)           # X 轴范围
ax.set_ylim(0, 100)           # Y 轴范围
ax.grid(True)                 # 显示网格

多子图

# 创建 2x2 子图网格
fig, axs = plt.subplots(2, 2, figsize=(12, 8))

axs[0, 0].plot(x1, y1)
axs[0, 1].scatter(x2, y2)
axs[1, 0].bar(x3, y3)
axs[1, 1].hist(data)

fig.tight_layout()  # 自动调整间距

3.3 保存图表

# 从 pyplot 保存
plt.savefig("figure.png", dpi=150, bbox_inches="tight")

# 从 Figure 对象保存
fig.savefig("figure.png", dpi=200, transparent=True)

支持的格式:png、pdf、svg、jpg 等。


附录:常用速查表

Pandas 数据查看

方法 作用
df.head(n) / df.tail(n) 前/后 N 行
df.dtypes 列数据类型
df.info() 数据结构摘要
df.describe() 数值统计信息
df.shape (行数, 列数)
df.columns 列名列表

Pandas 选择数据

方式 语法
单列 df["col"]
多列 df[["col1", "col2"]]
条件行 df[df["col"] > 10]
标签索引 df.loc[row, col]
位置索引 df.iloc[row, col]

Pandas 数据处理

操作 方法
排序 df.sort_values(by="col")
分组 df.groupby("col")["target"].mean()
聚合 df.agg({"col": ["min", "max"]})
长转宽 df.pivot(columns="col", values="val")
宽转长 df.melt(id_vars="col")
拼接 pd.concat([df1, df2], axis=0)
连接 pd.merge(df1, df2, on="key", how="left")
重命名 df.rename(columns={"old": "new"})
新建列 df["new_col"] = df["col"] * 2

Matplotlib 图表选择指南

数据类型 推荐图表 方法
时间序列趋势 折线图 plot()
两个数值变量关系 散点图 plot.scatter() / scatter()
分类比较 柱状图 plot.bar() / bar()
分布查看 直方图 / 箱线图 hist() / box()
占比/累计 面积图 area()

注:本笔记示例代码源自 _E:\PythonProject1\_ 项目中的 _pandas.demo.py_ ~ _pandas8-demo.py_,结合 pandas、NumPy、Matplotlib 官方文档整理。

相关条目

  • python
  • 集合

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注