news 2026/9/12 23:39:26

Data-Science-For-Beginners 学习指南:Working with Data——从关系数据库到 Python 数据准备的完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Data-Science-For-Beginners 学习指南:Working with Data——从关系数据库到 Python 数据准备的完整实战

Data-Science-For-Beginners 学习指南:Working with Data——从关系数据库到 Python 数据准备的完整实战

【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners

本指南围绕开源课程 Data-Science-For-Beginners 第二章「Working with Data」展开,该章位于仓库 2-Working-With-Data/,共包含四节循序渐进的课程:关系数据库、非关系数据库、Python 与 Pandas 数据处理、数据准备与清洗。读完本文,你将掌握表的建模与主外键概念、SQL 的 SELECT/WHERE/JOIN 查询、NoSQL 与文档数据库的实践方法、Pandas 中 Series/DataFrame 的核心操作,以及缺失值与重复数据的处理策略,并了解仓库内配套的示例数据(SQLite 机场库、Cosmos DB 样例 JSON、COVID 数据集、表单 CSV)如何落地这些技能。

章节总览:一条从存储到清洗的数据管线

「Working with Data」对应仓库目录 2-Working-With-Data/,其学习目标非常明确:掌握在应用程序中管理、操作和利用数据的各种方法。四个子主题构成一条完整的数据处理链路:

  1. 关系数据库(Relational Databases)——理解表、主键、外键与 JOIN,用 SQL 检索多表数据;
  2. 非关系数据库(Non-relational Databases)——认识电子表格与四类 NoSQL 存储,并通过 Cosmos DB Emulator 实操文档数据库;
  3. 使用 Python 处理数据(Working with Python)——掌握 Pandas 的 Series、DataFrame 核心操作,并用真实 COVID 数据完成挑战;
  4. 数据准备(Preparing Data)——用 Pandas 处理缺失值、重复数据等"脏数据"问题。

这种编排反映了一个核心理念:数据库擅长高效存储与查询,而数据科学工作中大量的探索性分析、变换与可视化,则需要借助 Python 这样更灵活的工具来完成。接下来我们逐一深入。

一、关系数据库:从一张表到多表建模

1.1 一切始于表

关系数据库的核心构件是表(table),其本质与电子表格一致:行(row)存放具体数据,列(column)描述数据的含义。以存储城市信息为例:

CityCountry
TokyoJapan
AtlantaUnited States
AucklandNew Zealand

列名CityCountry描述所存数据的含义,每一行则是一个城市的完整信息。这个朴素模型是理解关系数据库的起点。

1.2 单表方案的局限

当我们想在表中加入更多维度时,单表方案会暴露出严重问题。以城市年度降雨量为例,如果按"每行一条降雨记录"的方式存储:

CityCountryYearAmount
TokyoJapan20201690
TokyoJapan20191874
TokyoJapan20181445

城市名和国家被反复复制,浪费存储且毫无必要——Tokyo 只有一个名字。若改用"每年一列"的方式:

CityCountry201820192020
TokyoJapan144518741690
AtlantaUnited States177911111683
AucklandNew Zealand13869421176

虽然避免了行重复,但每新增一个年份就要修改表结构,而且把年份当作列会让检索和计算变得笨拙。这正是需要多张表与关系(relationship)的原因:通过拆分数据避免重复,并在操作数据时获得更大灵活性。

1.3 关系核心:主键与外键

拆分数据的第一步,是为每个实体确定唯一标识。**主键(Primary Key,常缩写为 PK)**是表中唯一标识某一行的值。虽然理论上可以用城市名这类自然值做主键,但实践中几乎总应使用数字等自动生成的标识符——主键不应随业务数据变化而变化,否则会破坏关系。大多数情况下主键是自动生成的数字。

拆分后的cities表:

city_idCityCountry
1TokyoJapan
2AtlantaUnited States
3AucklandNew Zealand

随后建立rainfall表,不再重复城市全部信息,而是引用cities表的 id:

rainfall_idcity_idYearAmount
1120181445
2120191874
3120201690
4220181779
5220191111
6220201683
7320181386
832019942
9320201176

rainfall表中的city_id列指向cities表的主键,在关系数据库术语中称为外键(Foreign Key,常缩写为 FK)——它是来自另一张表的主键,本质上是一个引用或指针:city_id = 1即引用 Tokyo。

补充说明:本课中 "id" 与 "primary key" 互换使用。这些概念同样适用于后续课程将遇到的 PandasDataFrame——虽然 DataFrame 不使用 "primary key" 这一术语,但行为上非常相似。

1.4 SQL 检索:SELECT 与 WHERE

数据拆分到多张表后,需要用结构化查询语言(SQL)把它们取回来。SQL 是关系数据库(MySQL、SQL Server、Oracle 等)的标准检索与修改语言。

最基础的是SELECT ... FROM ...SELECT列出想看的列,FROM列出来源表。显示全部城市名:

SELECT city FROM cities; -- Output: -- Tokyo -- Atlanta -- Auckland

SQL 语法不区分大小写,selectSELECT等价;但表名、列名是否区分大小写取决于具体数据库。最佳实践是把所有内容都当作区分大小写来对待,且约定俗成将 SQL 关键字全部大写。

WHERE子句实现过滤:

SELECT city FROM cities WHERE country = 'New Zealand'; -- Output: -- Auckland

1.5 多表 JOIN:把数据缝起来

要把citiesrainfall两张表的数据合并,需要执行JOIN:在两张表之间建立一条"接缝",将两表中对应列的值匹配起来。本示例以rainfall.city_id匹配cities.city_id,采用的连接类型是inner join——任何在另一张表中没有匹配行的记录都不会显示。由于每个城市都有降雨数据,因此全部行都会返回。

分两步检索 2019 年所有城市的降雨量。第一步先连接两张表:

SELECT cities.city, rainfall.amount FROM cities INNER JOIN rainfall ON cities.city_id = rainfall.city_id

第二步加上WHERE过滤出 2019 年:

SELECT cities.city, rainfall.amount FROM cities INNER JOIN rainfall ON cities.city_id = rainfall.city_id WHERE rainfall.year = 2019 -- Output -- city | amount -- -------- | ------ -- Tokyo | 1874 -- Atlanta | 1111 -- Auckland | 942

小结:关系数据库的核心思想是把信息分散到多张表中,需要展示或分析时再通过连接把它们合并回来,从而在计算与数据操作上获得高度灵活性。

1.6 实战作业:用 SQLite 查询机场数据

仓库在 2-Working-With-Data/05-relational-databases/airports.db 提供了一个基于 SQLite 的机场数据库文件,配套作业见 assignment.md。该库包含两张表:

Cities
id (PK, integer)
city (text)
country (text)
Airports
id (PK, integer)
name (text)
code (text)
city_id (FK to id inCities)

由于一些城市可能有多个机场,所以拆成两张表,练习的核心正是 JOIN。可在 Visual Studio Code 中安装 SQLite 扩展,通过SQLite: Open database打开airports.db,用SQLite: New query新建查询窗口,以Ctl-Shift-Q(Mac 为Cmd-Shift-Q)执行 SQL。需要完成的查询包括:查询Cities表全部城市名、查询爱尔兰全部城市、查询全部机场名称及其所在城市与国家、查询英国伦敦的全部机场。这套练习能把上述主外键与 JOIN 知识直接落地。

二、非关系数据库:电子表格与四类 NoSQL

数据并不局限于关系数据库。本节聚焦非关系数据,覆盖电子表格基础和 NoSQL 两大主题。

2.1 电子表格:工作簿、工作表与单元格

电子表格因上手门槛低而广受欢迎。以 Microsoft Excel 为例,一个工作簿(workbook)包含一个或多个工作表(worksheet),工作表由标签页标识;表内的矩形称为单元格(cell),即行与列的交叉点——列用字母标记、行用数字标记,部分表格会在前几行放表头来描述数据含义。

仓库中提供了两个真实范例文件:

  • CocaColaCo.xlsx:用于"Soda Profits"作业,要求计算 FY'15~'18 的毛利润(Gross Profit = Net Operating revenues − Cost of goods sold),并用AVERAGE 函数计算全部毛利润的平均值;
  • InventoryExample.xltm:一个含 "Inventory List"、"Inventory Pick List"、"Bin Lookup" 三个工作表的库存示例,用于讲解公式与函数——**公式(formula)**以等号开头对单元格数据执行运算(如用 QTY × COST 计算库存价值),**函数(function)**则是预定义公式(如SUM),需要按特定顺序传入参数才能得到正确结果。

2.2 NoSQL 四大家族

NoSQL 是非关系数据存储方式的统称,可理解为 "non-SQL"、"non-relational" 或 "not only SQL"。常见分类有四类:

  • 键值存储(Key-value):将唯一键与对应值配对,底层通常借助哈希表与合适的哈希函数实现;
  • 图数据库(Graph):用节点(node)与边(edge)描述数据之间的关系——节点代表现实世界中的实体(如学生、银行账单),边代表实体间的关系,节点与边都可带属性;
  • 列族存储(Columnar):与关系结构类似按行列组织,但每一列被划分为列族(column family),同一列族下的数据作为整体被检索和更新;
  • 文档存储(Document):在键值存储概念上扩展,由一系列字段(field)与对象值(object value)组成,下一节将详细展开。

2.3 文档数据库实战:Cosmos DB Emulator

Cosmos DB 完全符合 "Not Only SQL" 的定义——它的文档数据库恰恰依赖 SQL 查询数据,因此上一节学到的 SQL 基础可以直接迁移使用。其Emulator允许在本地创建和探索文档数据库。

文档是字段与对象值的集合,字段描述对象值代表什么。一个典型文档如下(示例数据保存在 PersonsData.json,以及从 Twitter API 抓取后存入的推文数据 TwitterData.json):

{ "firstname": "Eva", "age": 44, "id": "8c74a315-aebf-4a16-bb38-2430a9896ce5", "_rid": "bHwDAPQz8s0BAAAAAAAAAA==", "_self": "dbs/bHwDAA==/colls/bHwDAPQz8s0=/docs/bHwDAPQz8s0BAAAAAAAAAA==/", "_etag": "\"00000000-0000-0000-9f95-010a691e01d7\"", "_attachments": "attachments/", "_ts": 1630544034 }

我们关注的是firstnameidage这些业务字段,其余带下划线的字段由 Cosmos DB 自动生成。

Emulator 操作要点:启动后点击 "Start with Sample" 生成名为 SampleDB 的示例库,其中含Persons容器(container,存放文档集合),可在 Items 下浏览四个文档;点击 SQL Query 按钮即可运行查询——SELECT * FROM c返回容器内全部文档,SELECT * FROM c where c.age < 40返回年龄小于 40 的文档。这与关系数据库的 SQL 体验几乎一致,只是作用对象从表变成了文档集合。

挑战任务:将 TwitterData.json 上传到一个新建的独立容器(新容器按钮 → 选择 SampleDB → 设置 partition key 为/id→ 用Upload Item上传),再尝试用LIKE关键字找出text字段包含 "Microsoft" 的文档。

大多数 API 返回的 JSON 数据可以直接存入文档数据库,这正是文档模型在现代数据工程中被广泛使用的原因。

三、使用 Python 与 Pandas 处理数据

数据库能高效存储和查询,但最灵活的数据处理方式是编写自己的程序。数据科学中最常用的语言是Python(通用、易上手、库生态庞大)、R(专为统计处理设计的工具箱)与Julia(面向高性能科学计算)。本节聚焦 Python。

3.1 核心库与导入方式

处理表格数据最常用的两个库:

  • Pandas:操作DataFrame(类似关系表,具命名列,可对行、列与整体做丰富操作);
  • Numpy:处理张量(多维数组),类型统一、数学操作更多、开销更小。

此外还有可视化库Matplotlib和科学计算库SciPy。标准导入写法:

import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import ... # 按需指定所需子包

3.2 Series:带索引的值序列

Series是一系列值,与列表或 numpy 数组类似,但带有索引(index)——运算时会考虑索引对齐。索引可以是默认的整数行号,也可以是日期区间等复杂结构。完整代码见配套笔记本 notebook.ipynb。

以冰淇淋店日销量分析为例,先生成时间序列:

start_date = "Jan 1, 2020" end_date = "Mar 31, 2020" idx = pd.date_range(start_date, end_date) print(f"Length of index is {len(idx)}") items_sold = pd.Series(np.random.randint(25, 50, size=len(idx)), index=idx) items_sold.plot()

每周派对额外准备 10 盒冰淇淋,用周频索引构建另一个 Series:

additional_items = pd.Series(10, index=pd.date_range(start_date, end_date, freq="W"))

两个 Series 相加时必须用add(..., fill_value=0)而不是+

total_items = items_sold.add(additional_items, fill_value=0) total_items.plot()

原因在于:additional_items在多数索引点上没有值(缺失值),直接用+会得到大量NaN(Not a Number)——任何数与NaN相加结果都是NaN

时间序列还可以按不同时间间隔重采样(resample),例如按月计算平均销量:

monthly = total_items.resample("1M").mean() ax = monthly.plot(kind='bar')

3.3 DataFrame:同索引 Series 的集合

DataFrame 本质上是共享同一索引的一组 Series。既可以把 Series 作为行合并(pd.DataFrame([a, b])),也可以作为列并用字典命名(pd.DataFrame({'A': a, 'B': b})),还可以转置得到相同布局:

df = pd.DataFrame([a, b]).T.rename(columns={0: 'A', 1: 'B'})

其中.T表示转置(行列互换),rename用于重命名列。基于此 DataFrame,本课演示了 Pandas 最核心的几类操作:

  • 列选择df['A']返回一个 Series;df[['B','A']]返回列子集的 DataFrame;
  • 行过滤df[df['A'] > 5]仅保留满足条件的行。其机制是df['A'] > 5返回布尔 Series,再用布尔 Series 作索引筛选。注意不能写df[df['A']>5 and df['A']<7],必须用&运算符并加括号:df[(df['A']>5) & (df['A']<7)]
  • 新建计算列df['DivA'] = df['A'] - df['A'].mean()计算 A 相对均值的偏离。但直接df['LenB'] = len(df['B'])是错误写法——它把整个 Series 的长度赋给了所有行,正确做法是使用apply
    df['LenB'] = df['B'].apply(lambda x: len(x)) # 或 df['LenB'] = df['B'].apply(len)
  • 按序号选行df.iloc[:5]取前 5 行;
  • 分组聚合:类似 Excel 透视表。按LenB分组求均值:
    df.groupby(by='LenB')[['A', 'DivA']].mean()

    同时求组内个数与均值,可用aggregate

    df.groupby(by='LenB') \ .aggregate({'DivA': len, 'A': lambda x: x.mean()}) \ .rename(columns={'DivA': 'Count', 'A': 'Mean'})

3.4 读取数据、打印与绘图

Pandas 读取 CSV 只需一行:df = pd.read_csv('file.csv')。探索大 DataFrame 时常用df.head()查看前几行(在 Jupyter Notebook 中会以表格形式美观呈现);plot函数可通过kind=参数支持多种图形类型,更复杂的图形则可直接使用 Matplotlib。

3.5 实战挑战:分析 COVID 数据

挑战 1——COVID 传播建模:使用约翰斯·霍普金斯大学 CSSE 提供的各国感染人数数据,完整示例见 notebook-covidspread.ipynb,从顶部逐格阅读并执行。配套作业 assignment.md 要求进一步:绘制 5~6 个国家的有效传染数 Rₜ 对比图、分析死亡/治愈与感染数的相关性、通过视觉对比推断病程时长、计算病死率及其随时间的变化。

挑战 2——COVID 论文分析:CORD-19 数据集收录了数千篇 COVID 论文(含元数据、摘要,约半数有全文)。简化版分析示例见 notebook-papers.ipynb。作业要求构建药物共现矩阵并热力图可视化,进阶目标是用正则表达式抽取剂量(如 "take 400mg of chloroquine daily" 中的400mg)并构建药物-剂量 DataFrame。

非结构化数据:文本和图像这类非结构化数据,需要通过"提取"步骤转成结构化形式(如从文本提取关键词、用神经网络识别图像中的对象、从视频流获取人物情绪),再套用前述 Pandas 处理流程。

最有用的建议:当你不确定如何用 Python 完成某类数据处理时,先在互联网上搜索——Stack Overflow 上通常有大量针对常见任务的现成代码片段。

四、数据准备:让"脏数据"变得可分析

原始数据往往存在不一致,会干扰分析与建模,即所谓的"脏数据"。本节的完整演示见 notebook.ipynb。

4.1 为什么清洗如此重要

  • 易用与可复用:数据组织规范、标准化后,更易检索、使用和分享;
  • 一致性:数据科学常需合并多个来源的数据集,统一各数据集的标准化规范才能保证合并后仍然可用;
  • 模型准确性:清洗后的数据能提升依赖它的模型的准确率。

常见的清洗目标包括:探索数据集(用查询、可视化、抽样发现需清理之处)、格式化(解决空白字符、日期、数据类型等不一致,不同国家对日期和数字的表示标准可能不同)、去重(重复会带来不准确结果,但合并数据集中的重复也可能携带额外信息需保留)、以及缺失数据处理。

4.2 快速摸清 DataFrame:info / head / tail

面对 6 万行 400 列的数据,先用 Pandas 内建工具快速掌握整体情况。本课用经典的鸢尾花(Iris)数据集演示:

import pandas as pd from sklearn.datasets import load_iris iris = load_iris() iris_df = pd.DataFrame(data=iris['data'], columns=iris['feature_names'])
  • iris_df.info()打印内容摘要:150 个条目、4 列、无空值、全部为 float64 类型;
  • iris_df.head()查看前 5 行;
  • iris_df.tail()查看最后 5 行。

仅凭这些元信息就能立刻对数据集的规模、形状与内容形成直观印象。

4.3 处理缺失数据

Pandas 用两种值表示缺失:NaN(IEEE 浮点规范中的特殊值,仅表示缺失的浮点值)和 Python 的None(用于非浮点缺失值)。两者各有限制,但合起来覆盖了绝大多数场景。

检测缺失值isnull()notnull()返回布尔掩码:

import numpy as np example1 = pd.Series([0, np.nan, '', None]) example1.isnull() # 0 False # 1 True # 2 False # 3 True

注意:0是合法整数不算缺失,''是字符串对象也不算缺失。布尔掩码可以直接作为 Series/DataFrame 的索引来定位缺失(或存在)的值。

删除缺失值dropna()直接移除缺失值。对 Series:

example1 = example1.dropna()

DataFrame 有两个维度,删除方式更丰富。默认dropna()删除包含任一空值的整行dropna(axis='columns')删除含空值的整列;how参数控制删除条件(默认how='any',可设how='all'只删全空的行/列);thresh参数则精细控制——保留非空值数量达到阈值的行/列:

example2.dropna(axis='rows', thresh=3)

填充缺失值fillna()返回缺失值被替换后的副本。可以填统一值(如0)、前向填充method='ffill'(用上一个有效值填充)、后向填充method='bfill'(用下一个有效值回填),DataFrame 还可指定axis方向。注意前向填充时若前方无可用值,空值会保留:

example3.fillna(0) example3.fillna(method='ffill') example3.fillna(method='bfill') example2.fillna(method='ffill', axis=1)

取用哪种策略(删除、替换、如何替换)应由数据的具体情况决定,没有放之四海皆准的方案。

4.4 去除重复数据

duplicated()返回布尔掩码,标记某行是否为前面行的重复;drop_duplicates()返回删除重复后的副本。两者默认考虑全部列,也可指定列子集:

example4 = pd.DataFrame({'letters': ['A','B'] * 2 + ['B'], 'numbers': [1, 2, 1, 3, 3]}) example4.duplicated() # 0 False # 1 False # 2 True # 3 False # 4 True example4.drop_duplicates() example4.drop_duplicates(['letters'])

重复数据会改变分析结果并带来不准确结论,去除重复是几乎所有数据科学项目的必经步骤。

实战作业:仓库提供了一份表单收集的 CSV 记录 data/form.csv 及其可视化问题描述,作业见 assignment.md,可配合 assignment.ipynb 与表单页面 index.html 实践,运用本节技术诊断表单数据采集的准确性与一致性。

五、章节配套资源与学习路径建议

围绕第二章,仓库还提供了可直接复用的数据与延伸材料:

  • 示例数据:除上述文件外,data/ 目录还汇集了 COVID 时间序列、鸟类观测、糖尿病、蜂蜜、蘑菇、出租车等 CSV/TSV 数据集,可配合各节练习使用;
  • 手绘笔记(Sketchnotes):sketchnotes/05-RelationalData.png、sketchnotes/06-NoSQL.png、sketchnotes/07-WorkWithPython.png、sketchnotes/08-DataPreparation.png 为四节课提供了可快速回顾的可视化笔记;
  • 进阶路径:第四章「4-Data-Science-Lifecycle/15-analyzing」的数据探索课程与本章的数据准备互为补充,建议按章节顺序学习,先建立数据存储与操作的基础,再进入分析与建模环节。

结语

从关系数据库的表建模、主外键与 JOIN,到 NoSQL 的电子表格与四类文档/键值/图/列族存储,再到 Pandas 的 Series/DataFrame 操作与数据清洗策略,「Working with Data」章节完整覆盖了数据科学工作流中"获取与准备"的关键环节。学完本章,你应该能够:用 SQL 在多表之间检索关联数据、在本地 Emulator 中探索文档数据库、用 Pandas 灵活完成表格数据的变换与可视化,并有策略地处理缺失值与重复数据——这些能力将直接支撑你在后续章节中开展探索性分析与建模。

【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 23:39:19

告别Postman:15款接口测试工具全面测评与选型指南

当你在同事的电脑上看到那个黄色纸飞机图标时&#xff0c;大概率就是 Postman。它不是不好用&#xff0c;只是我们往往习惯了它&#xff0c;就默认它是唯一的选择。做了这么多年 API 开发与测试&#xff0c;我的真实感受是&#xff1a;Postman 的生态确实完整&#xff0c;但它的…

作者头像 李华
网站建设 2026/9/12 23:37:13

openpi 完整上手指南:从安装到微调,5 条命令跑通 VLA 模型

openpi 完整上手指南&#xff1a;从安装到微调&#xff0c;5 条命令跑通 VLA 模型 【免费下载链接】openpi 项目地址: https://gitcode.com/GitHub_Trending/op/openpi openpi 是 Physical Intelligence 团队开源的机器人智能体工具包&#xff0c;内置 π₀、π₀-FAST…

作者头像 李华
网站建设 2026/9/12 23:35:31

Python Flask实现社区物业报修系统:从设计到部署全解析

我接手过不少类似的项目&#xff0c;也经常在交流群里看到有人把“Python-flask社区物业报修交流系统的设计与实现”和“Pycharm django”并列写在题目里。说实话&#xff0c;这个标题本身就藏着一个很典型的新手困惑&#xff1a;Flask、Django、PyCharm这三个词到底什么关系&a…

作者头像 李华
网站建设 2026/9/12 23:34:43

Windows代码签名避坑指南:EV证书、时间戳与SmartScreen信任机制详解

1. 为什么普通代码签名证书已经扛不住Windows SmartScreen的“红屏警告”了&#xff1f; 去年底&#xff0c;我帮一家做PC端工具软件的创业团队上线新版本&#xff0c;打包完直接发给测试同事——结果三台不同配置的Win10/Win11机器&#xff0c;全部弹出醒目的红色SmartScreen…

作者头像 李华