系列文章
Python 从入门到精通
第 29 / 36 篇
从环境安装和基础语法出发,逐步学习工程实践、自动化、数据处理与 Web 开发。
-
01
Python 怎么装、怎么用 -
02
变量、数字和字符串 -
03
列表:把一组数据放在一起 -
04
元组、集合和字典 -
05
条件判断:让程序做选择 -
06
循环:重复的事交给程序 -
07
函数:把代码整理成可复用的块 -
08
模块与包:拆分你的程序 -
09
输入、输出与字符串格式化 -
10
文件读写:保存程序的数据 -
11
异常处理:程序出错时怎么办 -
12
基础阶段练习:命令行记账本 -
13
类和对象:面向对象入门 -
14
继承、组合与特殊方法 -
15
迭代器与生成器 -
16
列表推导式与生成器表达式 -
17
装饰器:给函数增加能力 -
18
上下文管理器与 with -
19
类型标注与 dataclass -
20
正则表达式:从文本中找规律 -
21
日期、时间与时区 -
22
日志与调试 -
23
虚拟环境与依赖管理 -
24
测试:让修改不再提心吊胆 -
25
网络请求:用 Python 调用 API -
26
网页解析与合规采集 -
27
操作 Excel、CSV 与批量文件 -
28
SQLite:给程序加一个数据库 -
29
数据分析入门:NumPy 与 Pandas正在阅读 -
30
画图:把数据变得直观 -
31
Flask 入门:做一个小网站 -
32
异步编程:同时处理多项任务 -
33
线程、进程与并发选择 -
34
性能分析与优化 -
35
项目结构、配置与发布 -
36
综合项目:从需求到上线
数据有了、也存进数据库了,接下来自然想:这些数据能告诉我什么?比如一年账单里吃饭花了多少、哪个月支出最高。数据分析的两大神器:NumPy(高效数值计算)和 Pandas(表格数据处理)。这一篇入门,够你用起来。
安装
pip install numpy pandas
NumPy:高效数组
NumPy 的核心是 ndarray(N 维数组),比 Python 列表快几十倍,尤其是数学运算:
import numpy as np
# 创建数组
arr = np.array([1, 2, 3, 4, 5])
print(arr) # [1 2 3 4 5]
print(arr * 2) # [ 2 4 6 8 10](向量化运算,不用循环!)
print(arr + 10) # [11 12 13 14 15]
print(arr ** 2) # [ 1 4 9 16 25]
# 对比列表:列表 * 2 是重复,数组 * 2 是每个元素乘 2
lst = [1, 2, 3]
print(lst * 2) # [1, 2, 3, 1, 2, 3]
# 常用创建方式
print(np.arange(10)) # [0 1 2 ... 9](类似 range)
print(np.zeros(3)) # [0. 0. 0.]
print(np.ones((2, 3))) # 2 行 3 列全 1
print(np.random.rand(3)) # 3 个随机数
# 统计
scores = np.array([88, 92, 76, 59, 100])
print(scores.mean()) # 83.0
print(scores.max()) # 100
print(scores.min()) # 59
print(scores.std()) # 标准差(波动程度)
print(scores.sum()) # 415
核心思想:对整个数组做运算,不用写循环——这叫向量化,又快又简洁。
Pandas:表格数据的主角
Pandas 两个核心结构:
- Series:一列数据(带索引)
- DataFrame:二维表格(多个 Series 组成),像 Excel 表
import pandas as pd
# 从字典创建 DataFrame
df = pd.DataFrame({
"姓名": ["小明", "小红", "小刚", "小丽"],
"城市": ["敦化", "延吉", "长春", "敦化"],
"分数": [88, 92, 76, 95],
"年龄": [18, 17, 19, 18],
})
print(df)
# 姓名 城市 分数 年龄
# 0 小明 敦化 88 18
# 1 小红 延吉 92 17
# 2 小刚 长春 76 19
# 3 小丽 敦化 95 18
读取数据
# 读 CSV(数据分析的入口,最常见)
df = pd.read_csv("sales.csv")
# 读 Excel
df = pd.read_excel("sales.xlsx")
# 读数据库
import sqlite3
conn = sqlite3.connect("ledger.db")
df = pd.read_sql_query("SELECT * FROM records", conn)
# 先看看数据长什么样
print(df.head()) # 前 5 行
print(df.info()) # 列名、类型、非空数量
print(df.describe()) # 数值列的统计摘要(均值、最大最小、分位数)
选择和筛选
# 选列
print(df["分数"]) # 一列(Series)
print(df[["姓名", "分数"]]) # 多列(DataFrame)
# 按条件筛选行(最常用!)
high = df[df["分数"] >= 90]
print(high)
# 姓名 城市 分数 年龄
# 1 小红 延吉 92 17
# 3 小丽 敦化 95 18
# 多条件:& 且、| 或
filtered = df[(df["分数"] >= 90) & (df["城市"] == "敦化")]
print(filtered)
# 排序
print(df.sort_values("分数", ascending=False)) # 按分数降序
# 取某几行
print(df.iloc[0]) # 第一行(按位置)
print(df.iloc[1:3]) # 第 2-3 行
print(df.loc[df["姓名"] == "小明"]) # 按条件定位
记住 df[条件] 就是筛选,条件是”对每一行判断真假”。多条件要加括号,用 & 和 |(不是 and/or!)。
分组统计:groupby
这是数据分析最常用的操作——”按类别汇总”:
import pandas as pd
df = pd.DataFrame({
"类别": ["吃饭", "交通", "吃饭", "购物", "交通", "吃饭"],
"金额": [12.5, 5.0, 8.0, 99.0, 3.0, 15.0],
})
# 按类别分组求和
print(df.groupby("类别")["金额"].sum())
# 类别
# 交通 8.0
# 吃饭 35.5
# 购物 99.0
# 分组后多个统计
print(df.groupby("类别")["金额"].agg(["sum", "mean", "count"]))
# sum mean count
# 类别
# 交通 8.0 4.00 2
# 吃饭 35.5 11.83 3
# 购物 99.0 99.00 1
# 实战:月消费报表
# df.groupby(df["日期"].str[:7])["金额"].sum() # 按月份聚合
缺失值和清洗
真实数据永远有坑:缺值、重复、类型不对。
import pandas as pd
df = pd.DataFrame({"姓名": ["小明", None, "小刚"], "分数": [88, 92, None]})
# 看缺失
print(df.isnull()) # 每个位置是否缺失
print(df.isnull().sum()) # 每列缺失数量
# 处理缺失:删掉有缺失的行 / 填充
df_drop = df.dropna() # 删缺失行(数据少时慎用)
df_fill = df.fillna({"姓名": "未知", "分数": 0}) # 按列填充
# 去重
df2 = df.drop_duplicates()
# 类型转换(读 CSV 时数字常变成字符串)
df["分数"] = pd.to_numeric(df["分数"], errors="coerce") # 转数字,转不了的变 NaN
导出
df.to_csv("output.csv", index=False, encoding="utf-8-sig") # Excel 打开不乱码
df.to_excel("output.xlsx", index=False)
# index=False:不把行号写进文件,99% 的情况都要加
新手坑
坑 1:筛选用 and/or 报错。DataFrame 筛选必须用 & | 且每个条件加括号——df[df.a > 1 and df.b < 2] 会报 ValueError。
坑 2:改副本不生效。df[df["分数"] > 90]["新列"] = 1 会警告(SettingWithCopyWarning),改的是副本。要用 df.loc[条件, "新列"] = 1。
坑 3:中文乱码。导出 CSV 用 encoding="utf-8-sig"。
小结
- NumPy 数组:向量化运算(整个数组直接算),比列表快得多
- Pandas 两个核心:Series(一列)、DataFrame(表格)
df[条件]筛选行,多条件用&/|加括号groupby("列")["数值列"].sum()分组统计,报表神器- 清洗:isnull 查缺失、dropna/fillna 处理、drop_duplicates 去重
- 导出加
index=False,CSV 用 utf-8-sig
练习
- 用 pandas 读一个 CSV(可自己造),按类别分组统计金额,找出花最多的类别
- 给 DataFrame 加一列”是否及格”(分数 >= 60 为 True)
- 思考:
df[df["分数"] > 90]里的条件到底返回了什么?为什么它能当”筛选器”用?提示:打印一下df["分数"] > 90看看