Data-Science-For-Beginners 第 07 课实战指南:用 Python 与 Pandas 处理表格、文本与图像数据
Data-Science-For-Beginners 第 07 课实战指南用 Python 与 Pandas 处理表格、文本与图像数据【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners本篇指南围绕 07-python 课程文档 展开系统讲解如何基于 Python 的 Pandas、NumPy、Matplotlib 生态完成数据科学中最核心的三类任务表格数据Series/DataFrame的转换与聚合、文本数据的结构化抽取、图像数据的能力边界。学完本文你将掌握 Series 索引对齐、resample/rolling/groupby等关键操作并能读懂仓库中 COVID-19 扩散建模与 CORD-19 论文分析两个完整实战 Notebook 的实现原理。为什么选择 Python 做数据处理数据库提供了高效的数据存储与查询方式但在许多场景下复杂的数据处理无法仅靠 SQL 完成最灵活的方式就是自己编写程序来操纵数据。数据处理可以用任何编程语言实现但有一些语言在数据操作层面更“高级”数据科学从业者通常偏好以下三种Python通用编程语言因简洁性常被视为初学者最佳选择之一。它拥有大量辅助库可以解决诸如从 ZIP 归档提取数据、将图片转为灰度图等实际问题除数据科学外还广泛用于 Web 开发。R为统计数据处理而生的传统工具箱拥有庞大的 CRAN 库仓库但它不是通用编程语言很少在数据科学领域之外使用。Julia专为数据科学开发的语言旨在提供比 Python 更好的性能是科学实验的好工具。本课程的焦点是用 Python 做简单数据处理假设读者已具备该语言的基础知识。课程考虑三类数据形态表格数据tabular data、文本text和图像images通过少量示例帮助你理解各种可能性并让你知道遇到问题时去哪里找解决方案——当某个操作不会写时上网搜索例如 StackOverflow通常能找到大量 Python 典型任务的代码样例。核心库生态与导入方式处理表格数据时最重要的两个库是Pandas用于操作DataFrame其概念类似关系型表格可以拥有命名列并对行、列以及整体 DataFrame 执行各种操作。NumPy用于操作张量多维数组。数组中所有元素是同一底层类型比 DataFrame 更简单但提供更丰富的数学运算且开销更小。此外还有两个值得了解的库Matplotlib数据可视化与绘图库SciPy包含附加科学计算函数库在前期概率与统计课程中已接触过。Python 程序开头通常这样导入这些库import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import ... # 需要指定具体要用的子包配套的入门 Notebook notebook.ipynb 中包含了与下文讲解完全对应的可运行代码包括导入、Series、DataFrame、过滤、apply、iloc、groupby与绘图各环节建议边读边执行。仓库还提供了 R 语言版本的对照练习 R/notebook.ipynb从源码结构看它使用 dplyr、tidyverse、ggplot2 等 R 包实现了与 Pandas 相同的数据处理案例可作为跨语言对照阅读。Series带索引的时间序列Series是值序列类似 list 或 NumPy 数组主要区别在于它带有一个索引index对 Series 做运算例如相加时会考虑索引对齐。索引可以简单到默认整数行号也可以是复杂结构比如日期区间。日期索引 Series 的创建以分析冰淇淋店销量为例生成一段时间内每天销量的 Seriesstart_date Jan 1, 2020 end_date Mar 31, 2020 idx pd.date_range(start_date, end_date) print(fLength of index is {len(idx)}) items_sold pd.Series(np.random.randint(25, 50, sizelen(idx)), indexidx) items_sold.plot()这里pd.date_range构造了从 1 月 1 日到 3 月 31 日的日频日期索引np.random.randint(25, 50, sizelen(idx))生成等长随机整数作为每日销量索引对齐后 Series 即成为一条时间序列。索引对齐的陷阱与 fill_value假设每周为朋友办派对时额外多拿 10 盒冰淇淋可以创建一个按周索引的 Seriesadditional_items pd.Series(10, indexpd.date_range(start_date, end_date, freqW))两个 Series 相加时必须使用add并指定fill_value而不是直接写total_items items_sold.add(additional_items, fill_value0) total_items.plot()为什么不能直接total_items items_sold additional_items因为additional_items只在每周的某一个日期上有值其余索引点上是缺失值NaN。按索引对齐相加时NaN加上任何数都是NaN结果会充满空值。指定fill_value0后缺失的一侧按 0 填充才能得到正确的总量。这一“索引对齐”机制是 Pandas 时间序列运算中最容易踩的坑配套的 notebook.ipynb 中先演示了直接相加产生NaN的错误结果再展示fill_value0的修正方式。重采样resample时间序列还可以用不同时间间隔重采样。例如计算月均销量并画柱状图monthly total_items.resample(1M).mean() ax monthly.plot(kindbar)resample(1M)把日频数据聚合成月频.mean()计算每个月内的均值再用kindbar输出柱状图。这一模式在 COVID-19 实战中会被rolling滚动窗口进一步复用。DataFrame表格操作的核心DataFrame本质上是具有相同索引的一组 Series 的集合。有两种构造方式a pd.Series(range(1, 10)) b pd.Series([I,like,to,play,games,and,will,not,change], indexrange(0, 9)) df pd.DataFrame([a, b]) # Series 作为行得到一张横向表得到形如两行九列的横向表第 0 行是数字 1..9第 1 行是单词。另一种是用字典把 Series 作为列并命名列df pd.DataFrame({ A: a, B: b })得到以 A、B 为列、索引 0..8 的表格A 列 1..9B 列各单词。同样的布局也可以通过转置前一张表得到df pd.DataFrame([a, b]).T.rename(columns{ 0: A, 1: B })其中.T是 DataFrame 的转置操作行列互换rename把列名改成与上例一致。列选择与行过滤列选择df[A]返回一个Seriesdf[[B,A]]返回一个新的 DataFrame注意双层方括号可同时选多列并调整列序。行过滤只保留A列大于 5 的行写df[df[A]5]。过滤的底层机制值得注意df[A]5返回一个布尔 Series逐元素标记 True/False把这个布尔 Series 当作索引使用时Pandas 返回对应的行子集。因此不能使用任意 Python 布尔表达式例如df[df[A]5 and df[A]7]是错误的——and作用于整个 Series 无法按元素工作。正确写法是对布尔 Series 使用运算符并注意括号不可省略df[(df[A]5) (df[A]7)]创建可计算列与 apply用直观表达式即可创建新的计算列例如计算 A 列相对其均值的偏差df[DivA] df[A] - df[A].mean()实际过程是先计算出一个 Series再把它赋给左边从而新增一列。因此不能使用与 Series 不兼容的操作# 错误写法 - df[ADescr] Low if df[A] 5 else Hi df[LenB] len(df[B]) # - 错误结果后一句虽然语法正确但结果错误它把 SeriesB的长度9赋给了该列的所有行而不是每行元素各自的长度。对这类需要“逐元素执行”的复杂表达式应使用applydf[LenB] df[B].apply(lambda x: len(x)) # 或 df[LenB] df[B].apply(len)经过上述操作后DataFrame 变为四列ABDivALenB01I-4.0112like-3.0423to-2.0234use-1.0345Python0.0656and1.0367Pandas2.0678very3.0489much4.04iloc 与 groupby 聚合按行号选择df.iloc[:5]取前 5 行适合基于位置的切片。分组聚合类似 Excel 的透视表。按LenB分组计算A的均值df.groupby(byLenB)[[A,DivA]].mean()若同时需要均值和组内元素个数使用更灵活的aggregate并配合rename美化列名df.groupby(byLenB) \ .aggregate({ DivA: len, A: lambda x: x.mean() }) \ .rename(columns{ DivA: Count, A: Mean })输出结果LenBCountMean111.000000213.000000325.000000436.333333626.000000这里aggregate接受一个“列名 - 聚合函数”的字典DivA列取len计数A列取lambda x: x.mean()均值。这正是 COVID 实战中“按国家汇总各州数据”所用的核心模式。从磁盘加载数据前面演示了如何从 Python 对象构造 Series 和 DataFrame但真实数据通常以文本文件或 Excel 表格形式存在。Pandas 提供了从磁盘直接加载数据的简单方式例如读取 CSV 文件df pd.read_csv(file.csv)仓库中 data/ 目录提供了多个可直接用于练习的真实数据集如 data/birds.csv、data/honey.csv、data/mushrooms.csv以及 COVID 实战使用的 data/COVID/ 目录含 time_series_covid19_confirmed_global.csv、time_series_covid19_deaths_global.csv、time_series_covid19_recovered_global.csv 三个时间序列文件。从 CSV 表头可以看出其结构前两列为Province/State,Country/Region随后是Lat,Long再往后是按1/22/20形式命名的逐日计数列——这种“宽表”布局正是后续按国家聚合的典型输入。打印与绘图数据科学家经常需要探索数据因此可视化能力很重要。当 DataFrame 很大时通常只需确认前几行是否正确df.head()在 Jupyter Notebook 中执行head()会以美观的表格形式渲染。前面也用过plot函数可视化某些列plot支持通过kind参数绘制多种图形类型若需要更复杂的图可以直接用底层的 Matplotlib 库。更深入的可视化内容在课程后续章节第 3 部分专门讲解。实战一COVID-19 扩散建模课程 notebook-covidspread.ipynb 演示了如何对 COVID-19 感染人数数据来自约翰霍普金斯大学 CSSE 的公开数据集做完整的建模流程建议从头到尾阅读并运行。核心实现链条如下1. 加载数据支持在线/本地双来源。Notebook 中通过切换base_url决定数据源——在线从 GitHub 原始地址读取或改为本地data/COVID/目录的副本base_url https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/ # base_url 本地路径指向仓库内 data/COVID/ 的三份 CSV infected pd.read_csv(base_url time_series_covid19_confirmed_global.csv) recovered pd.read_csv(base_url time_series_covid19_recovered_global.csv) deaths pd.read_csv(base_url time_series_covid19_deaths_global.csv)2. 探索与预处理。用value_counts()查看Province/State列可以推断出澳大利亚、中国等国提供了省级细分。既然目标是按国家分析就用groupby(Country/Region).sum()把各区域数据加总到国家级infected infected.groupby(Country/Region).sum() recovered recovered.groupby(Country/Region).sum() deaths deaths.groupby(Country/Region).sum()加总后 DataFrame 以Country/Region为索引于是可以用.loc[US]取某国数据。对于日期以外的元数据列Lat、Long、Province/State可以用切片[3:]跳过或干脆drop(columns[...])删除让索引干净地映射到日期。3. 逐日新增与平滑。定义辅助函数把三国的时间序列组装成一个以日期为索引的 DataFramedef mkframe(country): df pd.DataFrame({ infected: infected.loc[country], recovered: recovered.loc[country], deaths: deaths.loc[country]}) df.index pd.to_datetime(df.index) return df新增病例数用diff()逐日差值计算能直观反映疫情推进速度df[ninfected] df[infected].diff()原始曲线受报告节奏影响波动剧烈用 7 日滚动均值平滑后即可看出趋势df[ninfav] df[ninfected].rolling(window7).mean()4. 人口归一化。加载 data/UID_ISO_FIPS_LookUp_Table.csv 获取各国人口由于该表同时包含国家级和省级记录需要先筛选出Province_State为空isna()的行再取Population然后用infected * 100 / pop把绝对值换算成感染百分比便于跨国比较。5. 计算 Rt基本再生数的时变估计。Notebook 用一个巧妙的滚动窗口比值估算时变 Rt——“未来 4 天新增”与“过去 4 天新增”之比df[Rt] df[ninfected].rolling(8).apply(lambda x: x[4:].sum() / x[:4].sum())当 Rt 曲线跌破 1 时说明扩散在收敛图中红色虚线标出阈值 1。绘图时先replace(np.inf, np.nan)处理除零产生的inf再fillna(methodpad)前向填充缺口最后axhline(1, ...)画出阈值线ax df[df.index 2020-05-01][Rt].replace(np.inf, np.nan).fillna(methodpad).plot(figsize(10, 3)) ax.set_ylim([0, 6]) ax.axhline(1, linestyle--, colorred)6. 二阶信号新增病例的差分。对ninfected再做一次diff()并滚动平滑可以清晰看到疫情处于上升期还是下降期红色虚线为 0 阈值。课程还为学习者保留了延伸挑战assignment.md 给出了带评分标准的完整任务清单把 5-6 个国家的 Rt 曲线画在同一张图上对比分析死亡/康复数与感染数的相关性通过感染率与死亡率的时间错位估算典型病程长度计算随时间变化的病死率提示可先把一条时间序列按病程天数平移再计算。实战二CORD-19 论文文本分析课程 notebook-papers.ipynb 展示了如何把非结构化文本变成结构化表格对象是 CORD-19 数据集数千篇 COVID 相关论文含元数据与摘要。注意本仓库不包含该数据集副本运行前需要自行下载metadata.csvKaggle 数据集或其历史发布地址均不在本仓库内。Notebook 中的加载方式df pd.read_csv(https://datascience4beginners.blob.core.windows.net/cord/metadata.csv.zip, compressionzip) df.head()1. 时间维度把publish_time转成datetimepd.to_datetime画直方图可以看到竟有可追溯到 1880 年的“冠状病毒”相关文献。2. 从摘要中提取关键词计数。定义药物与诊断两组关键词列表10 种药物hydroxychloroquine、chloroquine、tocilizumab、remdesivir、azithromycin、lopinavir、ritonavir、dexamethasone、heparin、favipiravir、methylprednisolone及若干诊断然后逐篇摘要统计词频并作为新列写入 DataFrame——这是把文本转成表格列的核心一步medications [hydroxychloroquine, chloroquine, tocilizumab, ...] # 对每行摘要统计各关键词出现次数新增列 df[medication]一个细节匹配时给关键词前面加空格 keyword in text避免子串误命中。之后用dfm.sum()得到全局提及量排序并用set_index(Name).plot(kindbar)画条形图。3. 按月的治疗策略趋势。把publish_time设为索引筛选 2020-01 到 2021-07按(year, month)分组求和dfmt dfm.groupby([dfm.index.year, dfm.index.month]).sum()可视化后能看到 2020 年 1 月与 2021 年 1 月的异常尖峰——原因是部分论文日期缺失被归入这些月份。处理方法把这两个月置为np.nan再fillna(methodpad, inplaceTrue)前向填充最后用并排子图观察各药物热度演变如 hydroxychloroquine 先升后降、favipiravir 稳步上升。还可以进一步用apply(lambda x: x / x.sum(), axis1)计算各月相对提及占比用plot.area()画堆叠面积图即课程中的治疗效果图。4. 药物-诊断对应矩阵与可视化。用双重循环统计“同一篇摘要中同时出现某药物与某诊断”的次数得到 NumPy 共现矩阵m形状为药物数 × 诊断数然后plt.imshow(m, interpolationnearest, cmaphot)画成热图更好的呈现是用Sankey桑基图——因为 Matplotlib 不支持该图型Notebook 中改用 Plotly 的go.Sankey对象绘制“诊断 - 药物”流向图。课程留白任务见 assignment.md包括构建药物间共现矩阵并画热图用弦图chord diagram可视化以及用正则表达式从摘要中提取药物剂量如take 400mg of chloroquine daily中的 400mg建立“药物 × 剂量”表格。图像数据理解其能力边界近两年发展出的强大 AI 模型让我们能够“理解”图像许多任务可以直接借助预训练神经网络或云服务完成课程文档列举了三类典型能力图像分类Image Classification把图片归入预定义类别可用 Custom Vision 等服务快速训练自己的分类器目标检测Object Detection检测图像中的不同物体计算机视觉服务可识别大量常见物体也可用 Custom Vision 训练特定目标的检测模型人脸检测Face Detection包括年龄、性别、情绪识别可经由 Face API 实现。这些云服务都提供 Python SDK因此可以方便地嵌入数据探索工作流。仓库文档还给出了两个探索图像数据的案例方向用计算机视觉从 Instagram 照片中尽可能多提取信息、再构建可解释模型来分析“什么让照片获得更多点赞”以及用 Face API 从活动照片中提取人物情绪、研究“什么让人快乐”配套仓库为 Face Studies Workshop。与前两节的表格、文本不同图像属于非结构化数据处理路径是先用视觉模型抽取结构化特征再回到 Pandas 体系做分析——这正是本课“提取结构化数据”思想的一致的延伸。小结无论数据是结构化的表格还是非结构化的文本与图像Python 都能覆盖数据处理与理解的完整步骤这也是它成为多数数据科学家首选工具的原因——它提供了最灵活的数据处理方式。若你对数据科学之旅是认真的深入学习 Python 是值得的投入。延伸阅读仓库文档列出的学习资源名称供检索外部链接见原文档 README.md书籍Wes McKinney《Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython》Pandas 官方《10 minutes to Pandas》教程与 Pandas 可视化文档Python 入门路径Microsoft Learn 的“Take your First Steps with Python”学习路径、Turtle 图形与分形的趣味课程。完整可运行的练习代码分布在三个 Notebook 中notebook.ipynbPandas 基础、notebook-covidspread.ipynb时间序列建模依赖 data/COVID/ 与 data/UID_ISO_FIPS_LookUp_Table.csv 本地数据、notebook-papers.ipynb文本抽取需自备 CORD-19 metadata.csv。按 assignment.md 中的评分标准完成延伸任务即是对本课全部知识点的综合检验。【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →