宾夕法尼亚大学-Python-数据分析笔记-全-

宾夕法尼亚大学 Python 数据分析笔记(全)

1:如何运用数据专项课程简介 📊

在本节课中,我们将要学习“如何运用数据”专项课程的整体框架与核心内容。该课程旨在帮助初学者掌握数据分析、数据科学和数据分析的基础知识与实用技能。


在数字时代,数据无处不在,塑造着我们日常的决策。它正在改变行业,推动创新,并创造新的机遇。

欢迎来到我们的Coursera专项课程“如何运用数据”。这是一个关键的门户,专为任何渴望利用数据潜力的人设计,无论其先前经验如何。

数据之旅从这里开始。在这里,你将解锁数据分析、数据科学和数据分析的基础知识。本专项课程是你穿越不断发展的数据领域的综合指南,提供随着技术进步仍将保持相关性的实用技能和见解。

我们生活在一个数据触及我们存在每个角落的时代,从企业的战略制定到最小的个人便利。数据是塑造我们世界看不见的力量。然而,尽管数据无处不在,驾驭这片广阔信息海洋的能力仍未普及。

本专项课程弥合了这一差距,为你提供工具,使数据不仅可理解,而且可操作。这是关于将信息转化为洞察,并将洞察转化为影响。

数据分析、预测分析和数据可视化不仅仅是当代的流行语,更是现代技能组合的支柱,这些技能在未来技术演进时仍将保持相关性。我们与数据交互的方式也会随之变化。然而,你将在此学到的核心原则是不变的,为你提供坚实的基础,无论数字环境如何变化。


上一节我们介绍了课程的整体目标和重要性,本节中我们来看看课程的具体结构。

我们的专项课程精心构建为三个结构严谨的课程,每个课程都建立在前一个课程的基础上,确保全面而连贯的学习体验。

以下是三个核心课程的概述:

第一门课程 为你数据分析之旅奠定基石,分为三个关键模块。

  • 模块1 打开通往数据世界的大门,提供对数据分析、数据科学和数据分析的见解。它涵盖整个数据分析流程,介绍本课程至关重要的编程语言和工具,并通过案例研究让你将理论概念带入现实世界背景。
  • 模块2 深入数据整理,重点介绍SQL。你将探索数据存储和访问,通过关系数据库的视角学习SQL基础知识,并掌握数据操作技术。这个模块对于希望理解SQL以及如何为分析准备数据的人来说至关重要。
  • 模块3 将重点转向使用Python进行探索性数据分析,你将学习检查、查询和汇总数据,同时通过可视化信息来挖掘洞察。该模块旨在让你掌握数据分析库(如pandas)和可视化工具(如MatplotlibSeaborn)的实践技能。

第二门课程 将你的技能进一步带入预测领域,分为三个丰富的模块。

  • 模块1 向你介绍预测分析,涵盖线性回归和逻辑回归等基本模型。这是你开始学习如何从历史数据预测未来趋势的地方。
  • 模块2 将你的知识扩展到决策树和随机森林,更深入地探讨更复杂的监督学习模型,以增强你的预测分析能力。
  • 模块3 探索无监督学习和聚类,指导你了解模型比较的细微差别,以及在没有预定义标签的情况下识别模式的艺术。

第三门课程 是你的数据之旅的顶峰,通过三个重点模块将分析转化为行动。

  • 模块1 让你沉浸在使用Tableau进行数据可视化的学习中,你将掌握创建有影响力的视觉数据故事背后的概念和原则,重点是一维和时间序列可视化。
  • 模块2 介绍多维可视化和复杂关系,扩展你分析和可视化多表数据的能力,增强数据解读的深度和清晰度。
  • 模块3 致力于洞察呈现和数据叙事,在这里你将学习如何将分析综合成连贯且有说服力的叙述,这是向利益相关者有效传达数据洞察的关键技能。

每门课程相互关联,在前一门的基础上构建,以形成对数据分析的全面理解。


为了获得专项课程证书,按顺序完成所有三门课程是必不可少的。这份证书向潜在雇主证明了你的投入和专业知识。

本专项课程需要投入,沿途有评分作业、定期测验和实践练习,让你能够批判性和创造性地将所学知识应用于现实世界场景。

它不仅仅是一个专项课程,更是对你未来的投资,为你配备随着技术进步仍将保持相关性的长青技能。

总而言之,“如何运用数据”是成为下一代数据专业人士的门户。通过理解数据分析,你不仅仅是在跟上数字时代的步伐,更是在帮助塑造它。

加入我们这个激动人心的旅程,释放数据的全部潜力,改变你的职业生涯。欢迎来到数据分析的世界。让我们一起开始这段变革之旅。


本节课中我们一起学习了“如何运用数据”专项课程的目标、重要性以及由三门核心课程组成的详细结构。我们了解到,该课程从数据分析基础、SQL和Python技能开始,逐步深入到预测分析和高级可视化,最终目标是培养将数据洞察转化为有效行动和沟通的能力。

2:数据分析、SQL与Python探索性分析导论 🚀

在本课程中,我们将学习数据分析、SQL数据操作以及使用Python进行探索性数据分析的基础知识。课程旨在为初学者揭开数据分析的神秘面纱,并建立坚实的实践技能基础。

概述 📋

欢迎来到数据分析、SQL与Python探索性分析导论课程。这是本系列专项课程的门户课程,旨在阐明数据分析的核心要素。课程从坚实的基础开始,介绍数据、数据分析以及数据科学的广泛领域。同时,课程将引导你了解数据分析流程中的关键步骤,包括定义问题,以及理解对任何数据分析师都至关重要的工具和语言。

深入SQL数据操作 🗃️

上一节我们介绍了数据分析的基础概念,本节中我们来看看如何利用SQL进行实际的数据操作。

随着课程的深入,我们将探讨SQL的实际应用,教你如何利用SQL进行有效的数据存储、访问和操作。这包括查询数据、连接表以及使用函数来精炼数据等操作。

以下是SQL中一些核心操作的概念:

  • 查询数据:使用 SELECT 语句从数据库中检索数据。
  • 连接表:使用 JOIN 语句(如 INNER JOIN, LEFT JOIN)合并多个表中的相关数据。
  • 使用函数:应用聚合函数(如 SUM(), AVG(), COUNT())或字符串函数来处理和汇总数据。

过渡到Python探索性数据分析 🐍

掌握了SQL的数据操作后,我们将过渡到Python,探索其在探索性数据分析中的强大能力。

在Python部分,我们将探索其在探索性数据分析中的强大能力。课程将指导你加载和检查数据,以及汇总和可视化信息,以识别潜在的模式和洞察。

😡

以下是使用Python进行EDA的典型步骤:

  • 加载与检查数据:使用 pandas 库的 read_csv()read_sql() 函数加载数据,并使用 df.head()df.info() 进行初步检查。
  • 数据汇总:使用 df.describe() 获取数值型数据的统计摘要。
  • 数据可视化:使用 matplotlibseaborn 库创建图表,例如 plt.scatter(x, y) 绘制散点图,以发现趋势和异常值。

总结 🎯

在本课程中,我们一起学习了数据分析的基础知识、使用SQL进行数据操作以及利用Python进行探索性数据分析的核心技能。到课程结束时,你将熟练掌握数据分析的基础方面,能够将这些技能应用于现实世界的挑战,并为学习更复杂的预测分析和高级数据可视化主题做好准备。

3:讲师简介 🧑‍🏫

在本节课中,我们将了解本课程讲师的背景与经历,并明确本课程的目标受众。


我的名字是布兰登·克劳斯基,我是这门“如何运用数据”课程的讲师。

关于我的背景:我最初是一名音乐家,随后在广播和音频制作领域工作。

我的编程经验始于Adobe Flash,我曾使用该工具为大型制药公司开发一个实时网络会议平台。

我于2009年左右从宾夕法尼亚大学获得了计算机与信息技术硕士学位。

之后,我在宾夕法尼亚大学设计学院担任程序员。

随后,我在沃顿商学院计算部门担任应用开发人员,与教职员工合作开发技术以推进学生项目。

在此期间,我创立了自己的公司Bleak LLC,为各类公司提供编程和自由职业应用开发服务。

我后来转型进入数据与分析领域,并成为“商业人工智能与分析”部门的研究与教育主任。

2018年,我成为宾夕法尼亚大学工程学院的讲师。

关于我的更多信息:我是一名贝斯手,演奏贝斯多年。我演奏多种风格的音乐,但更偏爱放克风格的音乐。

我最近大幅减少了咖啡摄入,并学会了花更多时间冥想。

最重要的是,我是一个重视家庭的人。


本课程面向对数据、数据分析或数据工作几乎没有或完全没有先验知识或经验的学生和专业人士。

虽然本课程要求具备编程经验,但它不要求任何数据分析、数据科学或数据可视化的背景。

总的来说,本课程非常适合那些希望学习数据运作机制、通过执行数据分析获取洞察、应用数据科学技术进行预测,以及应用数据分析来解答问题和解决有趣商业问题的人士。


本节课中,我们一起了解了讲师的多元化背景——从音乐、编程到数据科学,并明确了本课程是为具备基础编程能力、但希望入门数据分析领域的初学者所设计的。

4:数据基础与问题定义 📊

在本节课中,我们将要学习数据科学的基础概念,包括数据的定义、类型、大数据的特点,以及数据分析与数据科学的关系。我们还将概述数据分析的全过程,并通过案例研究来理解其实际应用。

理解和运用数据的能力在当今世界变得日益重要,因为数据无处不在且极具价值。

什么是数据?🔍

数据是关于世界的原始事实和数字。它本身可能没有意义,但经过处理和分析后,可以转化为有价值的信息。

数据主要分为两种类型:

  • 定性数据:描述性质或特征,通常是非数值的。例如,颜色、品牌名称、客户反馈文本。
  • 定量数据:表示数量,是数值型的。例如,身高、温度、销售额。定量数据可进一步分为离散型(如员工人数)和连续型(如温度)。

认识大数据 🌐

上一节我们介绍了数据的基本类型,本节中我们来看看当数据规模变得巨大、复杂时的情况,即“大数据”。

大数据通常用4个V来描述:

  • Volume(体量):数据的规模极其庞大。
  • Velocity(速度):数据生成和流动的速度非常快。
  • Variety(多样性):数据的形式多样,包括结构化数据(如数据库表格)、半结构化数据(如JSON、XML)和非结构化数据(如文本、图像、视频)。
  • Veracity(真实性):数据的质量和可靠性。

公司利用大数据进行市场分析、预测趋势、优化运营和个性化推荐。

数据分析与数据科学 🤝

理解了数据本身后,我们来看看处理数据的两个核心领域:数据分析与数据科学。它们共同构成了数据分析学这一领域。

  • 数据分析 侧重于检查、清理、转换和建模数据,以发现有用信息、得出结论并支持决策。它更偏向于回答特定的业务问题。
  • 数据科学 是一个更广泛的跨学科领域,它使用科学方法、流程、算法和系统从结构化和非结构化数据中提取知识和见解。它结合了统计学、计算机科学和领域专业知识。

两者的关系可以概括为:数据科学为数据分析提供了更强大的方法论和工具基础,而数据分析是数据科学成果的具体应用和体现。

数据分析的全过程 🔄

现在,我们知道了处理数据的领域,接下来让我们系统地了解数据分析是如何一步步进行的。以下是数据分析的典型流程:

  1. 问题定义:明确需要解决的业务或研究问题。这是所有工作的起点。
  2. 数据收集:从各种来源(数据库、调查、传感器等)获取相关数据。
  3. 数据清洗与整理:处理缺失值、异常值,将数据转换为适合分析的格式。这个过程可以用代码来描述其核心操作:
    # 示例:使用Pandas处理缺失值
    cleaned_data = raw_data.dropna()  # 删除缺失值
    # 或
    filled_data = raw_data.fillna(method='ffill')  # 向前填充缺失值
    
  4. 数据探索与分析:通过统计和可视化方法初步了解数据,并运用模型进行深入分析。
  5. 结果解释与呈现:将分析结果转化为易于理解的见解,并通过报告、图表等方式呈现给决策者。

案例分析 📈

为了将理论应用于实践,我们将看一些案例研究。这些案例旨在说明数据分析在真实世界场景中的应用。

例如,一个零售公司可能通过分析销售数据(定量数据)和客户评论(定性数据),来定义“如何提高季度销售额”的问题,随后收集线上线下数据,清洗整理后,分析出热销产品和客户偏好,最终制定出精准的营销策略。


本节课中我们一起学习了数据的基础概念、大数据的特征、数据分析与数据科学的联系与区别,并梳理了数据分析从问题定义到结果呈现的完整流程。理解这些基础是后续学习Python、SQL等具体工具和技术,并进行有效探索性数据分析(EDA)的基石。

5:数据与数据分析导论 📊

在本节课中,我们将要学习数据的基本概念、不同类型以及大数据的特点。我们还将探讨数据分析与数据科学领域,并了解数据分析的完整流程及其在现实世界中的应用。


在当今世界,理解和运用数据的能力变得越来越重要,因为数据无处不在且极具价值。

学习数据知识对许多工作都有帮助。例如,数据工程师负责设计、构建和维护存储与处理数据所需的基础设施。或者数据分析师,他们分析和解释数据以提取洞察、趋势和模式。又或是数据科学家,他们开发并应用先进的机器学习和统计技术,从数据中提取洞察并构建预测模型。数据知识对产品经理、业务分析师、软件工程师、网络安全专家等众多其他角色也同样重要。

学习数据知识对任何受数据影响的领域都有帮助,其应用范围横跨医疗保健、金融、市场营销、教育、交通、政治学、科学和体育等众多行业。

以下是哈尔·瓦里安关于网络如何挑战管理者的一句话:“获取数据、理解数据、处理数据、从中提取价值、将其可视化并进行沟通的能力,在未来几十年将是一项极其重要的技能。”

那么,从技术上讲,什么是数据?数据是事实、统计数字、测量值或其他信息的集合。

数据可以来自传感器、调查、实验、交易、社交媒体和网络浏览等无数来源。数据可以呈现为数字、文本、图像、音频或视频等多种形式。数据可用于分析、研究和沟通等多种目的。数据还可用于获得对特定主题或现象的洞察,以解决业务问题并辅助决策。事实上,数据的最大价值在于其提供洞察和辅助明智决策的能力。


上一节我们介绍了数据的基本定义和价值,本节中我们来看看数据的多种类型。

数据有许多不同的类型。以下是主要的数据类型:

  • 结构化数据:以特定格式组织,通常存在于数据库或电子表格中。这类数据通常易于搜索、排序和分析,因为其组织良好。
  • 非结构化数据:没有预定义的格式或结构。例如包括电子邮件、社交媒体帖子和多媒体文件。这类数据通常更难分析,因为它需要更复杂的处理和分析。
  • 半结构化数据:部分结构化的数据,例如存储在XML文件或JSON格式中的数据。通常,半结构化数据比结构化数据更具挑战性,但比非结构化数据更容易分析。

除了按结构分类,数据还可以按内容分为以下类型:

  • 时间序列数据:随时间收集的数据,通常以固定间隔进行。例如包括股票价格、天气数据和网站流量。
  • 空间数据:与特定位置或地理区域相关的数据。例如包括地图、卫星图像和GPS设备的位置数据。
  • 分类数据:分为不同类别或组的数据。例如包括性别、年龄组和产品类型。
  • 数值数据:由数值组成的数据。例如包括价格、数量和测量值。
  • 文本数据:由书面或口头语言组成的数据。例如包括电子邮件、文章和客户评论。

由此可见,数据可以以各种不同的格式和规模存在。


了解了数据的多样性后,我们接下来探讨一种特殊的数据形态:大数据。

关于大数据的信息非常多。基本上,大数据是指极其庞大的数据集,其规模之大或复杂程度之高,使得传统的数据处理应用程序难以应对。

与较小规模的数据一样,大数据也可以通过计算分析来揭示模式、趋势并提取价值。

那么大数据是什么样的?许多公司每天都在收集和存储PB级的数据。作为参考,1 PB = 1000 TB,1 TB = 1000 GB,1 GB = 1000 MB。你可能为自己购买过1 TB的硬盘。

公司拥有和/或使用着占地数百英亩的大型数据中心,其中运行着大量服务器和复杂软件,以处理TB和PB级的数据。

许多公司每天都在以某种方式收集、存储和使用大数据。我们当然可以看看一些真正的大公司,如谷歌、Facebook、维基百科、苹果应用商店、Pandora和微软。

数据集增长迅速,每一项活动都会产生数据。以下是这些公司收集数据的例子:

  • 谷歌:从搜索查询、位置数据、电子邮件和YouTube视频观看量中收集数据。
  • Facebook:从用户资料、帖子、点赞和分享中收集数据,为其用户创建详细档案。
  • 维基百科:收集用户与其网站的互动数据,如页面浏览量、编辑和搜索。
  • 苹果应用商店:收集有关应用使用情况、下载量以及用户购买行为的数据。
  • Pandora:收集用户音乐偏好、收听历史和对歌曲的反馈数据。
  • 微软:从其用户设备收集数据,包括搜索查询、电子邮件和应用使用情况。

那么,公司为什么要收集所有这些数据?因为他们负担得起(存储成本低廉),并且能够将其货币化。数据经过处理和分析后可以产生价值。以下是这些公司利用数据的方式:

  • 谷歌:利用数据改进搜索结果、投放广告以及开发新产品和服务。
  • Facebook:利用数据向用户定向投放广告和推荐内容。
  • 维基百科:利用数据监控网站性能、识别改进领域并跟踪用户参与度。
  • 苹果应用商店:利用数据为用户提供相关的应用推荐、改进应用搜索结果,并帮助开发者优化他们的应用。
  • Pandora:利用数据为每个用户个性化定制收听体验。
  • 微软:利用数据改进搜索结果、开发新产品以及个性化广告。

本节课中我们一起学习了数据的核心定义、主要类型(结构化、非结构化、半结构化、时间序列、空间数据等),并深入探讨了大数据的概念及其在大型科技公司中的实际应用与价值创造方式。理解这些基础知识是步入数据分析领域的第一步。

6:数据科学与数据分析导论 📊

在本节课中,我们将要学习数据科学与数据分析的基本概念,了解它们的定义、核心任务以及典型应用场景。通过对比分析,我们将清晰地理解这两个紧密相关但又有所区别的领域。


🔍 什么是数据分析?

数据分析通常聚焦于探索、清洗、转换和总结数据,以提取有意义的见解并得出某些结论。

数据分析通常带有特定的目的,例如识别趋势或模式,或提出建议。例如,一家公司可以使用数据分析来评估按地区、产品类别或销售渠道划分的销售业绩,从而识别高绩效的细分市场和改进机会。

以下是数据分析的核心任务:

  • 探索:初步了解数据的结构和特征。
  • 清洗:处理缺失值、异常值和不一致的数据。
  • 转换:将数据转换为更适合分析的格式(例如,数据归一化)。
  • 总结:通过统计量(如均值、中位数)或可视化来概括数据。


🧠 那么,什么是数据科学?

上一节我们介绍了数据分析,本节中我们来看看数据科学。数据科学通常被认为是一个更高级的领域,它涉及使用统计和机器学习技术从数据中提取见解并构建预测模型。

数据科学通常用于解决复杂问题,例如预测客户行为、检测欺诈,或在医疗保健环境中识别高风险患者。延续前面的例子,一家公司可能会使用机器学习等数据科学技术来预测未来对产品或服务的需求。

以下是数据科学中常用的技术:

  • 统计技术:例如假设检验、回归分析。
  • 机器学习技术:例如使用 scikit-learn 库构建分类或回归模型。
# 示例:使用Python的scikit-learn进行简单的线性回归预测
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train) # 训练模型
predictions = model.predict(X_test) # 进行预测

⚖️ 总结与对比

总而言之,数据分析通常侧重于探索和解释数据以获取见解,而数据科学则更侧重于创建能够基于数据预测或解释现象的模型。

本节课中我们一起学习了数据分析和数据科学的核心定义、任务差异以及典型应用。数据分析是理解过去和现在的基础,而数据科学则在此基础上,利用更高级的技术来预测未来和解决更复杂的问题。理解这两者的关系是进入数据领域的重要第一步。

7:数据分析基础 📊

在本节课中,我们将学习数据分析的基本概念、流程及其核心要素。数据分析是一个结合了数据分析与数据科学技术的领域,旨在提取洞见、进行预测并回答问题。

数据分析的作用是帮助组织做出明智决策并推动绩效改进。

数据分析流程概述 🔄

上一节我们介绍了数据分析的定义与作用,本节中我们来看看典型的数据分析流程包含哪些关键步骤。数据分析流程通常涉及以下要素。

以下是数据分析流程的核心步骤列表:

  1. 定义问题:识别需要通过数据分析来解决的业务问题或疑问。
  2. 收集与准备数据:收集并整理数据分析所需的数据,包括清洗数据并将其转换为易于分析的格式。
  3. 探索数据:进行初步的数据分析,以识别数据中的模式、异常值和趋势。
  4. 应用统计与机器学习技术:运用数据科学技术分析数据,生成洞见并进行预测。
  5. 数据可视化:创建可视化图表,以帮助向利益相关者传达洞见和发现。
  6. 解释结果:解读分析结果,识别可操作的洞见,以帮助解决问题或回答业务问题。
  7. 传达结果:以易于理解和可操作的方式向利益相关者呈现洞见和发现。
  8. 实施解决方案:利用数据分析产生的洞见和发现来制定解决方案并采取行动。

流程步骤详解 📝

1. 定义问题

定义问题是数据分析的起点,其核心是明确分析的目标。公式可表示为:
分析目标 = 待解决的业务问题

2. 收集与准备数据

此步骤涉及数据的获取与预处理。在实际操作中,可能包括使用类似以下的Python代码进行数据清洗:

import pandas as pd
# 读取数据并处理缺失值
data = pd.read_csv('data.csv')
data_cleaned = data.dropna()

3. 探索数据

探索性数据分析旨在初步了解数据特征,例如使用描述性统计:

data_cleaned.describe()

4. 应用分析技术

此阶段运用统计模型或机器学习算法从数据中学习并预测。一个简单的线性回归模型公式为:
y = β₀ + β₁x + ε

5. 数据可视化

可视化是将复杂数据转化为直观图表的过程,例如使用Matplotlib库:

import matplotlib.pyplot as plt
plt.plot(x, y)
plt.show()

6. 解释与传达结果

将分析结果转化为业务语言,并确保其能指导决策。

7. 实施解决方案

将数据分析的结论应用于实际业务场景,例如优化库存管理、资源分配和定价策略。

总结 🎯

本节课中我们一起学习了数据分析的基础。我们明确了数据分析是一个旨在提取洞见、支持决策的领域。我们详细剖析了数据分析的标准流程,该流程始于定义业务问题,历经数据收集、清洗、探索、建模、可视化,终于结果的解释、传达以及最终解决方案的实施。本课程后续将涵盖此流程中每个环节所涉及的基本概念、技能和工具。

8:数据分析流程 📊

在本节课中,我们将通过一个真实世界的案例,学习学生数据分析团队如何运用数据分析流程,与赫斯特公司合作解决实际的商业问题。


🏢 案例背景

上一节我们介绍了数据分析流程的基本框架,本节中我们来看看它在真实商业场景中的应用。

赫斯特是一家美国跨国大众媒体和商业信息集团。它旗下拥有包括《旧金山纪事报》、《休斯顿纪事报》、《Cosmopolitan》和《Esquire》在内的报纸、杂志和电视频道。赫斯特与沃顿商学院AI与商业分析中心以及学生团队合作,旨在解决以下商业目标:通过增加数字订阅用户来提升新闻品牌的消费者收入。具体而言,赫斯特希望将访问其新闻网站的匿名用户或非订阅用户转化为付费客户或订阅用户。


📂 数据准备

为了达成目标,团队首先需要处理和理解数据。本节中我们来看看他们获取并处理了哪些数据。

赫斯特向学生团队提供了一个数据集,其中包含了访问赫斯特新闻网站的匿名用户或非订阅用户的历史信息。学生团队对数据集进行了筛选,专注于2023年1月至3月的《休斯顿纪事报》数据。他们进一步查询数据集,专门查看了用户访问的以下信息:

以下是数据集中包含的关键信息类别:

  • 页面浏览量:对特定网站页面的访问,包括流量来源和地理位置。
  • 内容信息:在网站页面上浏览的内容,包括类别、照片和URL。
  • 付费墙信息:访客遇到付费墙的事件,包括会话和时间戳。
  • 订阅信息:匿名用户转化为网站订阅者的信息,包括订阅时长和支付类型。

🔍 探索性数据分析

在准备好数据后,下一步是探索数据以发现模式。本节中我们来看看团队如何比较不同用户群体。

学生团队希望理解最终成为付费客户或订阅用户的匿名用户与那些没有转化、保持非订阅状态的用户之间的相似性和差异性。他们首先探索并总结了转化者与非转化者之间的差异。

以下是初步探索的主要发现:

  • 数据主要由非转化者构成。
  • 转化者与非转化者在日均页面浏览量上存在差异。
  • 转化者与非转化者在自上次浏览以来的天数上存在差异。
  • 转化者与非转化者在网站平均停留时间上存在差异。
  • 转化者与非转化者使用的主要设备类型不同。

🧩 用户分群与建模

为了更深入地理解用户,团队采用了更高级的分析技术。上一节我们比较了基础差异,本节中我们使用模型进行更精细的分组和预测。

为了进一步理解订阅用户与非订阅用户之间的异同,团队使用K均值聚类模型生成了转化者和非转化者的用户群。该模型根据距离将具有相似用户特征的用户分组在一起,彼此距离更近的用户属于同一个群组。K均值是最广为人知且易于理解的聚类模型之一。

公式表示聚类目标:最小化组内平方和 arg min Σ Σ ||x - μ_i||²,其中 x 是样本点,μ_i 是第 i 个簇的中心点。

随后,他们通过定义“接近程度”,识别出那些与转化者特征相似的“相似非转化者”,这些用户可以被视为潜在转化者的“相似用户”。


🎯 策略建议

基于分析结果,团队需要提出 actionable 的建议。上一节我们识别了不同类型的用户,本节中我们来看看针对每类用户的行动方案。

团队希望据此为每种类型的用户提出相应的行动建议。

以下是针对不同用户群体的具体策略:

  • 对于与转化者相似的非转化者:建议向他们展示付费墙,因为他们很可能转化为网站订阅者。
  • 对于与转化者不必然相似的非转化者:团队使用 XGBoost 预测模型来预测其转化概率。
    • 对于转化可能性较高的用户,建议额外提供一篇免费文章以进一步培养兴趣。
    • 对于转化可能性较低的用户,建议强制要求他们在网站进行注册,以获取更多用户信息。

📝 总结

本节课中,我们一起学习了数据分析流程在一个真实商业案例——赫斯特公司数字订阅增长项目中的应用。我们从理解商业目标开始,经历了数据准备、探索性分析、运用K均值聚类进行用户分群、使用XGBoost模型预测转化概率,并最终根据分析结果,为不同类型的匿名用户制定了差异化的转化策略。这个案例完整展示了如何将数据转化为具体的商业行动方案。

9:如何定义数据分析问题 📊

在本节课中,我们将学习数据分析流程的第一步:如何清晰地定义分析问题。这是整个分析工作的基石,决定了后续所有步骤的方向和范围。

数据分析流程始于定义问题。也就是说,需要识别出数据分析旨在解决的业务问题或疑问。

在定义数据分析问题时,需要考虑以下几个关键方面。

以下是定义问题时需要考虑的核心要素列表:

  • 目标:确定分析的主要目标。
    • 示例:一家零售公司希望分析客户购买数据以识别模式,从而提升销售额。
  • 范围:设定具体目标,并/或识别需要解决的具体业务问题。
    • 示例目标:分析应聚焦于客户人口统计特征和季节性趋势。
    • 示例业务问题1:我们最有价值客户的人口统计特征是什么?我们如何调整营销和促销活动来针对这些客户?
    • 示例业务问题2:销售数据中有哪些季节性趋势?我们如何调整库存水平以匹配需求?
  • 背景:理解问题的更广泛背景。
    • 示例:零售公司应考虑可能影响客户购买行为和偏好的经济状况、竞争对手策略和行业趋势。
  • 数据可用性:评估可用数据源及其质量。
    • 示例:公司可能拥有交易记录、客户档案和市场调研数据。他们需要确保数据可靠、完整,并尽可能无偏见。
  • 利益相关者:识别关键利益相关者及其期望。
    • 示例:对于零售公司,利益相关者可能包括门店经理、营销团队和高层管理人员。每位利益相关者可能有不同的关注点和优先级。
  • 约束与限制:考虑可能影响分析的约束和限制。
    • 示例:零售公司可能面临数据有限、数据收集预算有限,或需要遵守限制使用特定客户数据的隐私或安全法规。
  • 方法论:确定适合的分析技术和工具。
    • 示例:零售公司可能希望使用聚类技术来细分客户,并使用时间序列分析来识别季节性趋势。公司也可能希望使用特定的工具或编程语言进行分析。
  • 交付成果:明确期望的成果和交付物格式。

本节课中,我们一起学习了定义数据分析问题的完整框架。我们了解到,一个清晰的问题定义需要明确目标、范围、背景、数据、利益相关者、约束、方法以及最终交付成果。这是确保数据分析项目成功、高效且能产生实际业务价值的关键第一步。

10:Felix案例研究——问题定义详解 📊

在本节课中,我们将通过一个真实案例,深入探讨数据分析项目的第一步:如何清晰定义业务问题。我们将跟随一支学生数据分析师与数据科学家团队,看他们如何与金融科技公司Felix合作,解决一个实际的商业挑战。


🌍 案例背景介绍

上一节我们了解了数据分析的一般流程,本节中我们来看看一个具体的实战案例。

Felix是一家技术公司,其使命是让向拉丁美洲的跨境支付变得像在WhatsApp上发送消息一样简单。该公司是一个基于聊天的平台,专门处理从美国向墨西哥的汇款业务。

Felix与AIAB以及学生团队合作,旨在解决以下业务目标:通过在有欺诈企图之前识别不良行为者,来预测其平台上的欺诈行为。


🎯 项目范围与目标

明确了合作方与核心使命后,接下来我们需要界定项目的具体范围。

团队制定了以下项目范围,并明确了需要达成的具体目标:

  • 探索客户交易数据,识别整体的欺诈趋势。
  • 开发一个新的欺诈检测模型,该模型能够在交易流程的早期识别欺诈。

对于这个项目,团队深刻理解业务背景至关重要。


🔍 深入理解业务现状

在着手数据探索和模型构建之前,我们必须充分理解客户当前的运营情况和痛点。

Felix当时已经有一套第三方欺诈检测机制在运行。但是,每次识别出欺诈交易时,公司都会遭受退单(chargebacks) 的损失。因此,他们希望开发自己的、新的欺诈检测代理程序,使其更加健壮,从而防止这些退单发生。

此外,团队还需要深入了解Felix当前的欺诈检测模型:

  • 当前用于标记欺诈的特征(features) 是什么?
  • 这些特征在数据集中是否提供?它们能否作为新欺诈检测模型的一部分?
  • 当前检测欺诈的规则是什么?

📝 本节总结

本节课中,我们一起学习了Felix案例研究的问题定义阶段。我们了解到,一个成功的数据分析项目始于对业务目标(预测并防止欺诈)、项目范围(探索数据、开发新模型)以及现有业务上下文(现有机制的不足、对退单的关切)的清晰界定。这为后续的数据收集、分析与建模工作奠定了坚实的基础。

11:Codio平台SQL作业实践指南 🗂️

在本节课中,我们将学习如何在Codio平台上完成本课程的SQL实践作业。Codio是一个优秀的在线平台,它提供了预配置的环境,让你可以无缝地运行代码,无论你使用的是Mac、Windows还是Linux系统。

概述

我们将逐步介绍如何在Codio中处理不需要Jupyter Notebook的作业。这类作业类似于测验,但需要操作外部软件,如DBeaver和SQLite。以下是完成作业的核心步骤。

作业准备

上一节我们介绍了Codio平台的基本情况,本节中我们来看看如何开始一项具体的作业。

你在此处看到的是一项家庭作业,它不要求使用Jupyter Notebook。

请下载本页面上列出的文件,并按照本课程早期提供的PDF说明和编码演示,将这些文件加载到DBeaver中。

以下是开始作业前的准备步骤列表:

  • 向下滚动并勾选页面底部的复选框。
  • 如果是首次使用,请输入你的法定全名,然后点击“启动应用”。
  • 启动过程通常需要20秒到1分钟。如果没有任何反应,请刷新页面。

在Codio中操作

成功启动后,你将看到一个包含额外说明的指南页面。页面左侧是一个文件管理器。

如果你不熟悉如何在DBeaver中加载数据库文件,请回顾本课程早期的编码演示。

以下是完成每道题目的操作流程:

  • 阅读题目描述。
  • 在DBeaver中构思并编写查询语句。
  • 将编写好的查询语句复制到Codio中对应的SQL文件里。

请注意,你无法直接在Codio中运行查询。需要滚动到指南页面来检查你的答案。

答案检查与提交

为了测试系统,你可以先输入一个错误答案,此时你将看不到任何响应。

现在,输入正确答案并点击“检查”。如果答案正确,你将看到一个显示解决方案的文本框。

请注意,一道题可能存在多种解决方案,我们鼓励你探索不同的解题方法。

当你完成指南页面上的所有问题,并将本地工作空间中的所有查询语句复制粘贴到Codio后,即可将其标记为完成。你的分数将自动同步到Codio和Coursera平台。

总结

本节课中,我们一起学习了在Codio平台上完成SQL实践作业的完整流程。关键步骤包括:下载文件并在DBeaver中操作、在Codio中提交查询语句、以及通过指南页面检查和验证答案。记住,将代码从本地环境复制到Codio是必要步骤,并且要善用系统提供的答案反馈来学习多种解决方案。

12:SQL数据预处理导论 🗃️

在本节课中,我们将学习数据存储与访问的不同方式,并重点介绍如何从数据库中访问数据。我们将了解关系型数据库的背景知识,并深入学习用于访问和更新数据库的查询语言——SQL。

数据存储与访问方式概述

有多种方式可以存储和访问数据,它们具有不同的部署策略和存储选项。

以下是几种主要的数据存储系统:

  • 数据库
  • 数据仓库
  • 数据湖

本模块学习重点

上一节我们概述了数据存储的几种形式,本节中我们来看看本模块的核心内容。

在本模块中,我们将重点学习如何访问数据库中的数据。我们会先介绍关系型数据库的相关背景,然后深入探讨SQL语言。

SQL是一种用于访问和更新数据库的查询语言。

你将学到的SQL技能

了解了本模块的目标后,接下来我们具体看看你将掌握哪些SQL核心技能。

你将学习SQL的基础知识,从SELECT语句开始,掌握如何查询数据库中的数据。

以下是本模块涵盖的关键技能列表:

  • 学习不同类型的JOIN操作及其各自的优势。
  • 学习如何使用单行(标量)函数以及分组(聚合)函数来操作数据。
  • 学习如何创建数据库和表。
  • 学习如何插入、更新和删除数据。

实践练习安排

为了最大化实践体验,本模块包含了多个简短的SQL练习,确保你能够获得实际的操作能力。

本节课中,我们一起学习了数据存储的多种途径,明确了本模块将专注于从关系型数据库中获取数据,并预览了即将学习的SQL核心技能,包括数据查询、操作以及数据库的基本管理。通过后续的实践练习,你将逐步掌握这些技能。

13:SQL入门 🗄️

在本节课中,我们将要学习SQL的基础知识。SQL是用于管理和查询关系型数据库的标准语言,是数据分析师和数据科学家必须掌握的核心技能之一。我们将了解SQL是什么、为何重要,以及它如何应用于数据分析的各个阶段。


什么是SQL?

SQL代表结构化查询语言。一些人将其发音为“S-Q-L”,另一些人则坚持“sequel”是唯一正确的发音。SQL是一种用于管理、访问和更新关系型数据库的语言。


为何要学习SQL?

上一节我们介绍了SQL的定义,本节中我们来看看学习SQL的几个关键原因。

以下是学习SQL的主要原因:

  • 行业广泛应用:关系型数据库在各行各业被广泛用于数据存储和管理,而SQL是与这些数据库交互的标准语言。
  • 工具集成支持:许多数据分析和商业智能工具(如Tableau)都内置了对SQL的支持。许多编程语言(如Python)也提供对SQL的支持。
  • 多种系统兼容:SQL受到许多数据库管理系统(如MySQL、Oracle和SQL Server)的支持。
  • 市场需求旺盛:SQL是就业市场上备受追捧的技能。许多组织都需要能够操作关系型数据库的专业人员。


SQL与数据分析的关系

了解了SQL的重要性后,我们来看看SQL在数据分析工作流中的具体应用。

SQL与数据分析紧密相关,主要应用于以下几个环节:

  • 数据收集:SQL可用于将收集到的数据插入数据库。对应的操作是INSERT语句。
  • 数据准备:SQL可用于清理和转换数据,或者从多个表中筛选、聚合和连接数据。这涉及SELECTWHEREJOINGROUP BY等语句。
  • 数据探索:SQL可通过编写查询来检索特定的数据子集,或使用聚合函数生成汇总统计信息,从而帮助进行数据探索。常用的聚合函数包括COUNT(), SUM(), AVG(), MAX(), MIN()

此外,SQL允许高效地处理大型数据集。


总结

本节课中我们一起学习了SQL的基础知识。我们了解到SQL是用于操作关系型数据库的核心语言,因其在行业中的广泛应用、与各类工具的兼容性以及强大的市场需求而成为一项关键技能。更重要的是,我们看到了SQL贯穿于数据分析的整个流程,从数据收集、准备到探索阶段都发挥着不可或缺的作用。掌握SQL是开启数据分析之旅的重要一步。

14:关系型数据库概述 🗄️

在本节课中,我们将学习关系型数据库的基本概念,了解其核心组成部分,并认识用于管理和查询数据库的工具。

什么是关系型数据库?

关系型数据库或模式,是一个存储在相互关联的表或实体中的信息集合。

作为参考,面向对象数据库以对象的形式表示信息。

本模块将重点介绍如何使用SQL访问关系型数据库。

数据库的核心结构

上一节我们定义了关系型数据库,本节中我们来看看它的具体构成。一个数据库由多个表组成,每个表存储特定类型的事物,例如“客户”。

一个表由行和列构成。列或属性是一组特定类型的数据值。

每一列定义了实体的一个属性,例如“地址”。行是表中的一条记录。

它包含实体的一个实例,例如一位具体的客户。

而值则是单行中单个列的属性。

与Excel的类比

为了更好地理解,我们可以将关系型数据库比作Excel。

一个数据库表可以比作一个Excel工作表。

一个数据库表的列或属性可以比作Excel工作表的列。

一个数据库表的行可以比作Excel工作表的行。

一个数据库表的值可以比作Excel工作表单元格中的值。

如何访问数据库?

我们介绍了数据库的结构,那么如何实际使用它呢?你并不直接“打开”一个数据库。

数据库运行在数据库管理系统内部。

你需要连接到数据库。MySQL和SQLite是常用的开源DBMS。它们是免费的。

它们可以运行在本地计算机或云端。Oracle和SQL Server是其他常用的商业数据库系统。

这些不是免费的。在本课程中,我们将连接到SQLite数据库。

使用SQL开发工具

要连接到数据库并运行SQL,你需要使用SQL开发软件。DBeaver是一个用户友好的SQL开发工具。它是免费的。

它可以在PC和Mac上运行。

作为参考,市场上还有许多其他的SQL编辑器。

你也可以直接从命令行运行SQL代码,但通常使用图形化工具更为便捷。


本节课总结

本节课中我们一起学习了关系型数据库的基础知识。我们了解了数据库由相互关联的表组成,表则由行和列构成。我们还认识了用于管理数据库的DBMS(如MySQL、SQLite)以及用于编写和运行SQL查询的开发工具(如DBeaver)。这些概念是后续进行SQL数据操作的基础。

15:在DBeaver中连接SQLite数据库 🗄️

在本节课中,我们将学习如何使用DBeaver这款数据库管理工具来连接一个SQLite数据库文件。这是一个非常实用的操作,能让你轻松地查看和管理数据库中的内容。

概述

DBeaver是一个功能强大的开源数据库工具,支持多种数据库。本节教程将一步步指导你完成连接SQLite数据库的整个过程。

连接步骤详解

上一节我们介绍了DBeaver的基本用途,本节中我们来看看具体的连接操作。

首先,启动DBeaver,你需要创建一个新的数据库连接。

以下是创建新连接的具体步骤:

  1. 在顶部菜单栏,点击 “数据库”
  2. 在下拉菜单中选择 “新建数据库连接”

接下来,在弹出的连接类型选择窗口中,找到并选择SQLite。

  1. 在“热门”或“全部”标签页下,找到并点击 “SQLite” 图标。
  2. 然后,点击窗口右下角的 “下一步” 按钮。

现在,我们需要指定数据库文件的位置。这是连接过程中最关键的一步。

  1. 在设置页面,点击 “数据库” 输入框右侧的 “…”“浏览” 按钮。
  2. 在弹出的文件选择器中,找到并选中你的 .db.sqlite 数据库文件。
  3. 点击 “打开”

完成路径设置后,即可建立连接。

  1. 确认文件路径无误后,点击窗口底部的 “完成” 按钮。

连接成功与浏览

如果一切顺利,你的数据库连接就建立成功了。

新连接的数据库会出现在左侧的 “数据库导航器” 面板中。你可以展开它来查看数据库的结构。

例如,要查看其中包含哪些数据表:

  • 点击数据库连接名称左侧的 “+” 号展开。
  • 找到并右键点击 “表” 文件夹。
  • 选择 “查看表” 或直接双击“表”文件夹,右侧主面板就会显示所有数据表的列表。

总结

本节课中,我们一起学习了在DBeaver中连接SQLite数据库的完整流程。从创建新连接、选择数据库类型、定位数据库文件到最终成功连接并浏览表结构,每一步都是管理数据库的基础。掌握这个技能后,你就能方便地使用DBeaver来探索和分析SQLite数据库中的数据了。

16:数据查询与筛选导论 🗂️

在本节课中,我们将学习数据库的基本结构、SQL语言的两种主要类型,以及如何开始使用数据操作语言(DML)进行简单的查询。我们将从理解数据表的结构开始,逐步介绍SQL的核心概念。

理解数据表结构

上一节我们介绍了课程概述,本节中我们来看看数据表的基本构成。

Doctor 是一个表的名称。表中的每一行代表一条记录,即一位医生。

每一行中的每个值都告诉我们关于这条记录(一位医生)的某些信息。

每一列中的值包含同一种类的信息,例如,所有医生的名字。

除了存储医生个人信息的 doctor 表,我们还有一个 patient 表,用于存储患者信息,以及一个 appointment 表,用于存储医生与患者之间的预约信息。

SQL语言的两种类型

理解了表的结构后,接下来我们认识一下操作这些数据的工具——SQL语言。

SQL包含两种语言或语句类型。DDL是数据定义语言。

它用于定义表的结构。例如,CREATE TABLE 语句用于创建一个新的数据库表。

ALTER TABLE 语句用于修改或更改数据库表,而 DROP TABLE 语句用于删除一个数据库表。

另一方面,DML是数据操作语言。

它用于定义和操作表中的内容。INSERT 语句用于向数据库插入新数据。

SELECT 语句用于从数据库获取数据。

UPDATE 语句用于更新或更改数据库中的数据,而 DELETE 语句用于从数据库中删除数据。

开始使用DML语句

认识了SQL的两种语言后,本节我们将从简单的DML语句开始学习。

让我们从简单的DML语句开始。


本节课中我们一起学习了数据库表的基本结构,认识了SQL的两种核心语言——DDL(用于定义结构)和DML(用于操作数据),并了解了SELECTINSERTUPDATEDELETE等基本DML语句的作用。这些是进行数据查询与筛选的基础。

17:SQL 基础 SELECT 语句编程演示 🖥️

在本节课中,我们将学习如何使用 SQL 中最基础且最重要的 SELECT 语句。我们将通过查询一个包含医生和患者信息的数据库,来演示如何选择特定列、为列和表设置别名,以及如何获取唯一值。


选择特定列数据

上一节我们介绍了 SQL 的基本结构,本节中我们来看看如何从数据库表中提取我们关心的数据。

要从 doctor 表中查询每位医生的名和姓,我们使用以下 SELECT 语句:

SELECT doctor_first_name, doctor_last_name FROM doctor;

执行此查询后,我们将获得 doctor 表中所有医生的名和姓。



接下来,让我们从 patient 表中查询每位患者的 ID、姓、名和出生日期。

SELECT patient_id, patient_last_name, patient_first_name, patient_birth_date FROM patient;

此查询将返回 patient 表中所有患者的 ID、姓、名和出生日期信息。





为列设置别名(Alias)

在查询结果中,我们有时希望列标题显示为更易读的名称,而不是数据库中的原始列名。这可以通过为列设置别名来实现。

以下是使用 AS 关键字为 doctor 表的列设置别名的示例:

SELECT doctor_first_name AS "First Name", doctor_last_name AS "Last Name" FROM doctor;

执行此查询后,我们依然能看到每位医生的名和姓,但结果中的列标题已分别更改为“First Name”和“Last Name”。


我们同样可以为 patient 表的列设置别名。需要注意的是,AS 关键字是可选的,可以直接在列名后指定别名。

SELECT patient_first_name "First Name", patient_last_name "Last Name" FROM patient;

此查询返回每位患者的名和姓,并且列标题也已被重命名。




为表设置别名(Alias)

除了为列设置别名,我们也可以为表设置别名,这在编写涉及多个表的复杂查询时非常有用,可以简化语句。

以下是给 patient 表设置别名为 P 的示例:

SELECT patient_first_name, patient_last_name FROM patient AS P;

使用 AS 关键字将 patient 表别名为 P。请注意,在指定要选择的列时,我们可以在查询的其他地方使用这个别名 P




同样,我们也可以为 doctor 表设置别名为 D

SELECT doctor_first_name, doctor_last_name FROM doctor D;

这里,AS 关键字同样是可选的,我们可以直接为 doctor 表指定别名 D




使用 DISTINCT 关键字获取唯一值

当我们想查看某一列中有哪些不同的取值,而不是所有重复的值时,可以使用 DISTINCT 关键字。它只返回该列中互不相同的值。

首先,让我们从 doctor 表中选择所有的医生专业。但如果我们想知道医生可能有哪些不同的专业呢?

以下是使用 DISTINCT 关键字来显示所有医生的唯一专业的示例:

SELECT DISTINCT specialty FROM doctor;

此查询显示了 specialty 列中的唯一值。



同样,我们可以获取所有患者的唯一姓氏列表:

SELECT DISTINCT patient_last_name FROM patient;

此查询显示了数据库中患者的唯一姓氏。



总结

本节课中我们一起学习了 SQL SELECT 语句的基础操作。我们掌握了如何从表中选择特定的列,如何通过 AS 关键字为列和表设置更清晰的别名,以及如何使用 DISTINCT 关键字来过滤掉重复数据,获取列中的唯一值。这些是构建更复杂 SQL 查询的基石。

18:常用比较运算符 ⚖️

在本节课中,我们将学习编程中用于比较两个值关系的“比较运算符”。它们是构建条件判断逻辑的基础,在数据分析、筛选和决策流程中至关重要。

概述

比较运算符用于比较两个值,并判断它们之间的关系。这些运算符会返回一个布尔值(TrueFalse),表示比较结果是否成立。

相等与不等运算符

上一节我们介绍了比较运算符的基本概念,本节中我们来看看最基础的两个运算符:相等与不等。

  • 相等运算符 (==):用于测试两个值是否相等。
    • 公式/代码值1 == 值2
    • 示例:5 == 5 的结果是 True5 == 3 的结果是 False

  • 不等运算符 (!=):用于测试两个值是否不相等。
    • 公式/代码值1 != 值2
    • 示例:5 != 3 的结果是 True5 != 5 的结果是 False

大于与小于运算符

理解了相等性比较后,我们进一步学习用于比较数值大小的运算符。

以下是用于判断一个值是否大于或小于另一个值的运算符。

  • 大于运算符 (>):测试左侧值是否大于右侧值。
    • 公式/代码值1 > 值2
    • 示例:10 > 6 的结果是 True4 > 9 的结果是 False

  • 小于运算符 (<):测试左侧值是否小于右侧值。
    • 公式/代码值1 < 值2
    • 示例:3 < 7 的结果是 True8 < 2 的结果是 False

大于等于与小于等于运算符

除了严格的大于和小于,我们还需要判断“大于或等于”、“小于或等于”的情况。

以下是包含边界条件的比较运算符。

  • 大于等于运算符 (>=):测试左侧值是否大于或等于右侧值。
    • 公式/代码值1 >= 值2
    • 示例:7 >= 79 >= 5 的结果都是 True3 >= 6 的结果是 False

  • 小于等于运算符 (<=):测试左侧值是否小于或等于右侧值。
    • 公式/代码值1 <= 值2
    • 示例:4 <= 42 <= 5 的结果都是 True8 <= 3 的结果是 False

总结

本节课中我们一起学习了六种常用的比较运算符:==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)和 <=(小于等于)。它们构成了程序中进行条件判断的核心工具,所有运算符的运算结果都是布尔值 TrueFalse。熟练掌握这些运算符是编写逻辑判断语句的第一步。

19:记录筛选与数据排序 📊

在本节课中,我们将学习如何使用 SQL 中的 WHERE 子句筛选记录,以及如何使用 ORDER BY 子句对数据进行排序。这些是数据查询中最基础且最常用的操作。

🔍 使用 WHERE 子句筛选记录

WHERE 子句用于指定查询条件,只有满足条件的记录才会被返回。其基本语法如下:

SELECT 列名 FROM 表名 WHERE 条件;

上一节我们介绍了基本的查询语句,本节中我们来看看如何通过添加条件来精确筛选数据。

筛选 ID 小于 3 的医生

以下是查找医生 ID 小于 3 的医生姓名的示例:

SELECT first_name, last_name FROM doctors WHERE doctor_id < 3;

这条语句会返回所有 doctor_id 小于 3 的医生的 first_namelast_name 信息。

查找特定姓氏的患者

接下来,我们查找所有姓氏为 “Jones” 的患者。

SELECT * FROM patients WHERE last_name = 'Jones';

这条语句使用 WHERE 子句,并指定条件为患者的姓氏等于 “Jones”。

查找非 MD 头衔的医生

现在,让我们查找所有头衔不是 “MD” 的医生。

SELECT * FROM doctors WHERE title != 'MD';

这里使用了不等于运算符 !=,来筛选出 title 列不等于 “MD” 的记录。

使用 AND 连接多个条件

有时我们需要同时满足多个条件。以下是查找名为 “Becky Jones” 的患者的查询:

SELECT * FROM patients WHERE first_name = 'Becky' AND last_name = 'Jones';

在这个查询中,我们使用了 AND 逻辑运算符。这意味着只有同时满足 first_name 为 “Becky” last_name 为 “Jones” 的记录才会被返回。

使用 OR 连接多个条件

如果我们想查找姓氏为 “Jones” “Roberts” 的患者,可以使用 OR 运算符。

SELECT * FROM patients WHERE last_name = 'Jones' OR last_name = 'Roberts';

使用 OR 时,只要满足其中任意一个条件,记录就会被包含在结果中。

使用 LIKE 进行模式匹配

LIKE 运算符用于在文本列中进行模式匹配。它通常与通配符 %(匹配任意多个字符)和 _(匹配单个字符)一起使用。

以下是查找名字以字母 “J” 开头的患者的示例:

SELECT * FROM patients WHERE first_name LIKE 'J%';

‘J%’ 这个模式表示以 “J” 开头,后面可以是任意数量的字符。

我们也可以进行更复杂的匹配。例如,查找姓氏以 “Sa” 开头、以 “an” 结尾的医生:

SELECT * FROM doctors WHERE last_name LIKE 'Sa%an';

‘Sa%an’ 表示姓氏以 “Sa” 开头,中间有任意数量的字符,并以 “an” 结尾。

查找 NULL 值

IS NULL 用于查找某列为空值(NULL)的记录。NULL 表示该字段的值是未知的或未定义的。

以下是查找头衔未知的医生的示例:

SELECT * FROM doctors WHERE title IS NULL;

这条语句会返回所有 title 列为 NULL 的医生记录。

为了对比,我们也可以查找头衔为 NULL 空字符串的记录:

SELECT * FROM doctors WHERE title IS NULL OR title = '';

这条语句使用了 OR 来组合两个条件,返回头衔为空或未知的医生。

📈 使用 ORDER BY 对数据进行排序

ORDER BY 子句用于对查询结果进行排序。默认情况下,排序是升序(ASC),也可以指定降序(DESC)。

按单列排序

以下是选择所有患者的姓名,并按姓氏排序的示例:

SELECT first_name, last_name FROM patients ORDER BY last_name;

结果会按照 last_name 列的字母顺序(A-Z)升序排列。

按多列排序

我们也可以指定多个排序列。例如,先按姓氏升序排列,姓氏相同的再按名字升序排列:

SELECT first_name, last_name FROM patients ORDER BY last_name ASC, first_name ASC;

这条语句会先根据 last_name 排序,然后在 last_name 相同的情况下,根据 first_name 进行排序。

📝 总结

本节课中我们一起学习了 SQL 中两个核心的数据操作:筛选与排序。

  • 我们使用 WHERE 子句配合各种条件(=, !=, <, >, AND, OR, LIKE, IS NULL)来精确筛选出需要的记录。
  • 我们使用 ORDER BY 子句对查询结果进行排序,可以按单列或多列排序,并控制升序或降序。

掌握这些基础查询技能,是进行有效数据分析的第一步。

20:示例2数据库表结构详解 🗂️

在本节课中,我们将学习示例2数据库中的核心表结构。我们将逐一解析客户表、购买表、产品表和店铺表,理解它们各自存储的信息以及它们之间的关系。掌握这些表的结构是进行后续数据查询和分析的基础。

客户表 👤

上一节我们介绍了本课程的目标,本节中我们来看看数据库中的第一个核心表——客户表。

客户表用于存储个体客户的信息。该表记录了每位客户的基本数据,是关联客户购买行为的关键。

以下是客户表可能包含的主要字段:

  • customer_id:客户的唯一标识符。
  • name:客户的姓名。
  • email:客户的电子邮箱地址。
  • signup_date:客户的注册日期。

购买表 🛒

了解了客户信息如何存储后,我们接下来看看记录交易行为的购买表。

购买表用于存储客户完成的每一笔独立购买记录。它连接了客户、产品和店铺,是分析交易行为的核心表。

以下是购买表可能包含的主要字段:

  • purchase_id:每笔购买的唯一标识符。
  • customer_id:进行购买的客户ID,关联客户表。
  • product_id:被购买的产品ID,关联产品表。
  • store_id:购买发生的店铺ID,关联店铺表。
  • purchase_date:购买发生的日期和时间。
  • quantity:购买数量。
  • total_amount:该笔购买的总金额。

产品表 📦

现在,我们已经知道了交易是如何记录的,那么被交易的对象——产品,其信息又存放在哪里呢?这就是产品表的作用。

产品表用于存储可供购买的单个产品的详细信息。

以下是产品表可能包含的主要字段:

  • product_id:产品的唯一标识符。
  • product_name:产品的名称。
  • category:产品所属的类别。
  • price:产品的单价。其数据结构通常为浮点数,例如 price = 19.99

店铺表 🏪

最后,我们来了解交易发生的地点——店铺。

店铺表用于存储购买行为发生的各个实体店铺的信息。

以下是店铺表可能包含的主要字段:

  • store_id:店铺的唯一标识符。
  • store_name:店铺的名称。
  • location:店铺的地理位置或地址。
  • manager:店铺的负责人。



本节课中我们一起学习了示例2数据库的完整表结构。我们详细介绍了客户表、购买表、产品表和店铺表,明确了每张表的用途及其核心字段。理解这些表及其之间的关系(通过customer_idproduct_idstore_id等字段连接)是后续使用SQL进行数据查询、关联和分析的基石。

21:数据连接 🔗

在本节课中,我们将要学习数据连接(Join)的核心概念。数据连接是数据库操作中的一项关键技术,它允许我们从两个或多个表中收集信息,并将其呈现为一张单一的表。理解连接的工作原理对于进行有效的数据分析至关重要。

连接的基础与主键 🔑

上一节我们介绍了连接的基本定义,本节中我们来看看连接操作的基础:主键。

连接操作需要一种方式来唯一标识表中的每一行。

主键是一个列或一组列,其值能唯一标识表中的每一行。

以下是关于主键的两个关键点:

  • 主键列的值在表中必须是唯一的。
  • 主键用于在表之间建立关系。

连接类型概述 🔄

我们主要探讨三种基本的连接类型:内连接(Inner Join)、左连接(Left Join)和右连接(Right Join)。

内连接详解 🤝

内连接返回两个表中所有匹配的行。

其逻辑可以表示为以下伪代码:

FOR each row in TableA
    FIND a matching row in TableB (based on join condition)
    IF match FOUND
        COMBINE rows and OUTPUT

这意味着,只有当左表和右表中都存在满足连接条件的记录时,该记录才会出现在结果集中。

左连接与右连接详解 ↔️

上一节我们介绍了内连接,本节中我们来看看左连接和右连接,它们在某些场景下非常有用。

左连接返回左表中的所有行,以及右表中与之匹配的行。如果右表中没有匹配的行,则结果集中对应右表的列将显示为NULL值。

其逻辑可以表示为以下伪代码:

FOR each row in LeftTable
    FIND a matching row in RightTable (based on join condition)
    IF match FOUND
        COMBINE rows and OUTPUT
    ELSE
        OUTPUT LeftTable row with NULLs for RightTable columns

右连接的逻辑与左连接相反,它返回右表中的所有行,以及左表中与之匹配的行。如果左表中没有匹配的行,则结果集中对应左表的列将显示为NULL值。

外键:表关系的桥梁 🌉

连接操作通常依赖于外键来建立表与表之间的关系。

外键是一个表中的字段,它指向另一个表的主键。例如,在一个“预约”表中,可能会有Doctor_IDPatient_ID字段,它们分别是“医生”表和“病人”表主键的外键。这些外键值指向其他表的主键值,从而将数据关联起来。

总结 📝

本节课中我们一起学习了数据连接的核心知识。我们首先了解了连接的作用和主键的概念,这是进行连接的基础。接着,我们详细探讨了三种主要的连接类型:内连接、左连接和右连接,并通过伪代码解释了它们的工作原理。最后,我们介绍了外键如何作为桥梁,将不同的数据表关联起来。掌握这些连接技术,是进行复杂数据查询和分析的关键一步。

22:数据库主键与外键示例详解 🔑

在本节课中,我们将通过一个具体示例,深入理解数据库中的两个核心概念:主键与外键。我们将分析一个名为example2的数据库结构,并解释各表之间的关系。

数据库表结构概述

首先,我们来看一下example2数据库中的表。

以下是数据库中的三个核心表及其关键字段:

  • 客户表 (customer table)Cust_I 是该表的主键。它能唯一标识表中的每一行,即每一位客户。
  • 产品表 (product table)pro_Id 是该表的主键。它能唯一标识表中的每一行,即每一件产品。
  • 商店表 (store table)store_Id 是该表的主键。它能唯一标识表中的每一行,即每一家商店。

理解外键关系

上一节我们介绍了各个表的主键,本节中我们来看看这些表是如何通过外键联系在一起的。

在记录购买行为的表中,每一次购买都包含了对客户、产品和商店的引用。具体来说,它包含以下字段:

  • custom_I D:引用客户表中的Cust_I
  • prod_I D:引用产品表中的pro_Id
  • store_I D:引用商店表中的store_Id

这些字段被称为外键。它们的定义可以概括为:一个表中的字段,其值指向另一个表中的主键值。正是通过这些外键,数据库将独立的表连接成一个有意义的整体。

可视化关系图

为了更直观地理解表与表之间的关系,请参考以下结构示意图。它清晰地展示了主键如何被其他表的外键所引用。

总结

本节课中,我们一起学习了主键与外键在实际数据库中的应用。我们了解到,主键(如 Cust_Ipro_Id)用于唯一标识本表的记录,而外键(如 custom_I Dprod_I D)则用于建立表与表之间的关联,确保数据的一致性与完整性。理解这两个概念是进行有效数据管理和分析的基础。

23:SQL连接操作详解 - 内连接与左连接 🗂️

在本节课中,我们将学习SQL中两种核心的连接操作:内连接(INNER JOIN)和左连接(LEFT JOIN)。我们将通过具体的查询示例,演示如何从多个关联表中组合数据,并理解这两种连接方式的区别与应用场景。


内连接(INNER JOIN)演示

内连接用于返回两个表中匹配条件的所有行。只有当连接条件在两边表中都找到匹配项时,行才会被包含在结果集中。

示例1:列出有预约的医生及其预约时间

首先,我们需要从doctor表和appointment表中选取信息。以下是实现此查询的步骤:

  1. doctor表中选择所需列。
  2. 使用INNER JOINdoctor表与appointment表连接。
  3. 指定连接条件为doctor.DID = appointment.DID

由于这是内连接,结果将只显示有匹配预约记录的医生。

SELECT doctor.*, appointment.appointment_date, appointment.appointment_time
FROM doctor
INNER JOIN appointment ON doctor.DID = appointment.DID;

示例2:列出有预约的医生及其预约时间与患者姓名

上一节我们连接了医生和预约表,本节中我们进一步引入患者信息。以下是实现此查询的步骤:

  1. 首先,如示例1所示连接doctor表和appointment表。
  2. 再次使用INNER JOIN将上述结果与patient表连接。
  3. 指定新的连接条件为appointment.PID = patient.PID

此查询将只显示那些既有匹配预约,且预约又关联了匹配患者的医生记录。

SELECT doctor.*, appointment.appointment_date, appointment.appointment_time, patient.first_name, patient.last_name
FROM doctor
INNER JOIN appointment ON doctor.DID = appointment.DID
INNER JOIN patient ON appointment.PID = patient.PID;

示例3:查询Hopkins医生的所有预约详情

现在,我们学习如何在连接后对数据进行筛选。目标是找出Hopkins医生的所有预约及其患者信息。以下是实现此查询的步骤:

  1. 使用INNER JOIN连接doctorappointmentpatient表。
  2. 添加一个WHERE子句来过滤数据。
  3. WHERE子句中设置条件:doctor.last_name = 'Hopkins'
SELECT doctor.*, appointment.*, patient.*
FROM doctor
INNER JOIN appointment ON doctor.DID = appointment.DID
INNER JOIN patient ON appointment.PID = patient.PID
WHERE doctor.last_name = 'Hopkins';

示例4:查询特定时间且患者姓以S开头的预约

最后,我们来看一个包含多个过滤条件的复杂查询。目标是查找在2016-02-15 12:00且患者姓氏以‘S’开头的所有预约信息。以下是实现此查询的步骤:

  1. 连接doctorappointmentpatient三个表。
  2. WHERE子句中组合两个条件:
    • appointment.appointment_date = '2016-02-15 12:00:00'
    • patient.last_name LIKE 'S%'%是通配符,表示匹配任意字符)
SELECT doctor.*, appointment.*, patient.*
FROM doctor
INNER JOIN appointment ON doctor.DID = appointment.DID
INNER JOIN patient ON appointment.PID = patient.PID
WHERE appointment.appointment_date = '2016-02-15 12:00:00'
AND patient.last_name LIKE 'S%';

左连接(LEFT JOIN)演示

左连接会返回左表(FROM后的表)的所有行,即使在右表中没有匹配的行。对于不匹配的情况,右表的列将显示为NULL

示例5:列出所有医生及其预约(如有)

我们从左连接的基础用法开始。此查询将显示所有医生,无论他们是否有预约。以下是实现此查询的步骤:

  1. doctor表中选择信息。
  2. 使用LEFT JOIN将其与appointment表连接,条件仍是DID匹配。
  3. 为了清晰,按医生姓氏排序。

对于没有预约的医生,其预约日期列将显示为NULL

SELECT doctor.*, appointment.appointment_date
FROM doctor
LEFT JOIN appointment ON doctor.DID = appointment.DID
ORDER BY doctor.last_name;

示例6:列出所有患者及其预约(如有)

类似地,我们可以列出所有患者及其可能的预约。以下是实现此查询的步骤:

  1. patient表中选择信息。
  2. 使用LEFT JOIN将其与appointment表连接,条件是PID匹配。
  3. 按患者姓氏排序。

对于没有预约的患者,预约日期列将显示为NULL

SELECT patient.*, appointment.appointment_date
FROM patient
LEFT JOIN appointment ON patient.PID = appointment.PID
ORDER BY patient.last_name;

示例7:查找没有预约的医生

左连接的一个常见用途是查找在另一表中没有匹配项的行。以下是查找无预约医生的两种方法。

方法一:使用LEFT JOINWHERE过滤
此方法先进行左连接,然后筛选出右表(appointment)中匹配列为NULL的行。

SELECT doctor.*
FROM doctor
LEFT JOIN appointment ON doctor.DID = appointment.DID
WHERE appointment.DID IS NULL;

方法二:使用NOT IN子查询
此方法使用子查询先获取所有有预约的医生ID,然后主查询选择不在这个列表中的医生。

SELECT *
FROM doctor
WHERE DID NOT IN (SELECT DISTINCT DID FROM appointment);

示例8:查找有预约的患者

同样,我们也可以找出有预约的患者。以下是两种实现方法。

方法一:使用LEFT JOINWHERE过滤
此方法连接后,筛选掉预约ID为NULL的记录,只保留有匹配预约的患者。

SELECT patient.*
FROM patient
LEFT JOIN appointment ON patient.PID = appointment.PID
WHERE appointment.PID IS NOT NULL;

方法二:使用IN子查询
此方法使用子查询获取所有出现在预约表中的患者ID,然后主查询选择ID在这个列表中的患者。

SELECT *
FROM patient
WHERE PID IN (SELECT DISTINCT PID FROM appointment);

总结

本节课中我们一起学习了SQL中至关重要的两种表连接操作。

  • 内连接(INNER JOIN):仅返回两个表中匹配条件都存在的数据行,用于获取相关联的完整信息。
  • 左连接(LEFT JOIN):返回左表全部行,以及右表中匹配的行。右表无匹配时,相关列填充NULL。它常用于查找“有/无”关联关系的记录,例如“哪些医生没有预约”。

通过理解并灵活运用内连接和左连接,你可以有效地从多个数据库表中组合和筛选数据,这是进行复杂数据分析的基础。

24:单行函数详解 🧮

在本节课中,我们将学习SQL中的单行函数。单行函数对查询结果中的每一行数据进行处理,并返回一个结果。它们广泛应用于字符串操作、流程控制和日期处理等场景。


字符串函数 📝

上一节我们介绍了单行函数的基本概念,本节中我们来看看常见的字符串函数。这些函数接收一个字符串输入,并返回一个处理后的字符串值。

以下是常见的字符串函数及其功能:

  • CONCAT(字符串1, 字符串2, ...):将给定的多个字符串连接成一个字符串。
  • UPPER(字符串):将字符串中的所有字符转换为大写。
  • LOWER(字符串):将字符串中的所有字符转换为小写。
  • LEFT(字符串, 长度):从字符串左侧开始返回指定长度的子串。
  • RIGHT(字符串, 长度):从字符串右侧开始返回指定长度的子串。
  • MID(字符串, 起始位置, 长度):从字符串的指定起始位置返回指定长度的子串。
  • LTRIM(字符串):移除字符串左侧的所有空白字符。
  • RTRIM(字符串):移除字符串右侧的所有空白字符。
  • TRIM(字符串):移除字符串两侧的所有空白字符。
  • REPLACE(字符串, 目标子串, 替换子串):将字符串中所有出现的指定目标子串替换为另一个子串。
  • LENGTH(字符串):返回字符串的长度。
  • LOCATE(子串, 字符串):返回指定子串在字符串中首次出现的索引位置。

流程控制函数 ⚙️

了解了字符串处理函数后,我们接下来学习流程控制函数。这类函数根据给定的条件返回不同的值。

以下是常见的流程控制函数:

  • IFNULL(表达式, 替代值):如果给定的表达式结果为NULL,则返回指定的替代值;否则,返回表达式本身的结果。
  • IF(条件, 值1, 值2):如果条件为真,则返回值1;如果条件为假,则返回值2。


日期函数 📅

最后,我们来探讨日期函数。日期函数用于处理日期和时间值,提取特定部分或进行格式转换。

以下是常见的日期函数:

  • HOUR(日期):从给定日期时间中提取小时部分。
  • MINUTE(日期):从给定日期时间中提取分钟部分。
  • SECOND(日期):从给定日期时间中提取秒部分。
  • DAY(日期):从给定日期中提取天数。
  • DAYNAME(日期):返回给定日期对应的星期名称。
  • DAYOFMONTH(日期):返回给定日期是该月中的第几天。
  • DAYOFWEEK(日期):返回给定日期是该周中的第几天。
  • WEEKOFYEAR(日期):返回给定日期是该年中的第几周。

以下是更多日期函数:

  • MONTH(日期):从给定日期中提取月份。
  • MONTHNAME(日期):返回给定日期对应的月份名称。
  • DATE_FORMAT(日期, 格式):按照指定格式改变日期的显示形式。
  • STR_TO_DATE(字符串, 格式):将特定格式的字符串转换为日期类型。
  • DATEDIFF(日期1, 日期2):返回两个日期之间的天数差。
  • TIMEDIFF(时间1, 时间2):返回两个时间之间的时间差。
  • NOW():返回当前的日期和时间。
  • CURDATE():返回当前的日期。
  • CURTIME():返回当前的时间。


本节课中我们一起学习了SQL中的三类核心单行函数:字符串函数用于文本处理,流程控制函数用于条件判断,日期函数用于处理时间数据。熟练掌握这些函数能极大地提升数据查询和处理的灵活性与效率。

25:SQL 单行函数应用编程演示 🧑‍💻

在本节课中,我们将学习如何在 SQL 查询中应用单行函数。我们将通过几个具体的例子,演示如何使用字符串拼接、条件判断、日期计算和字符串格式化等函数来处理和转换数据,以满足特定的查询需求。


拼接医生全名与职称

首先,我们希望展示每位医生的全名(包含名、姓和职称)及其专业。

SQLite 数据库不支持 CONCAT 函数,但支持使用 || 运算符进行字符串拼接。

以下是实现此目标的基本查询:

SELECT first_name || last_name || title AS doctor_name, specialty AS specialty
FROM doctor;

这个查询将医生的名、姓和职称拼接成一个值,并显示其专业。


处理空值问题

运行上述查询后,你可能会发现结果存在一些问题。例如,第7行医生的拼接名显示为 SamuelChetonull,这是因为该医生的 title 字段值为 NULL

我们可以使用 COALESCE 函数或 CASE 表达式来处理 NULL 值,将其替换为空字符串。

SELECT first_name || last_name || COALESCE(title, '') AS doctor_name, specialty AS specialty
FROM doctor;

现在,第7行医生的名字显示为 Samuel Cheto,后面没有多余的 null,因为 NULL 已被替换为空字符串。


优化标题格式

虽然空值问题解决了,但名字和职称之间没有分隔符,阅读起来不够清晰。我们希望在有职称时,名字和职称之间用逗号和空格分隔。

我们可以使用 IIF 函数(SQLite 中的条件函数)来实现这个逻辑:

SELECT
    first_name || last_name ||
    IIF(title IS NULL OR title = '', '', ', ' || title) AS doctor_name,
    specialty AS specialty
FROM doctor;

现在,查询结果中,有职称的医生名字后会跟随一个逗号和职称,例如 Samuel Cheto, MD


规范姓名大小写

最后,我们希望规范医生姓名的大小写格式,确保名和姓的首字母大写,其余字母小写。

我们可以结合使用 SUBSTRUPPERLOWER 函数来实现:

SELECT
    UPPER(SUBSTR(first_name, 1, 1)) || LOWER(SUBSTR(first_name, 2)) ||
    UPPER(SUBSTR(last_name, 1, 1)) || LOWER(SUBSTR(last_name, 2)) ||
    IIF(title IS NULL OR title = '', '', ', ' || title) AS doctor_name,
    specialty AS specialty
FROM doctor;

运行此查询后,所有医生的姓名都将以首字母大写的形式规范显示。


计算患者年龄

上一节我们介绍了如何使用字符串函数处理文本数据,本节中我们来看看如何使用日期函数进行计算。

现在,我们希望计算每位患者的年龄。思路是计算当前日期与患者出生日期之间的天数差。

SQLite 的 JULIANDAY 函数可以将日期转换为儒略日数,便于进行日期运算。

SELECT last_name AS patient, JULIANDAY('now') - JULIANDAY(birth_date) AS days_old
FROM patient;

此查询会返回每位患者的年龄(以天为单位)。


将天数转换为年数

要将天数转换为年数,只需将天数除以 365。

SELECT last_name AS patient, (JULIANDAY('now') - JULIANDAY(birth_date)) / 365 AS age
FROM patient;

现在,年龄以带小数的年数形式显示。


取整为整数年龄

通常,我们更习惯用整数表示年龄。可以使用 CAST 函数或 ROUND 函数向下取整。

SELECT last_name AS patient, CAST((JULIANDAY('now') - JULIANDAY(birth_date)) / 365 AS INTEGER) AS age
FROM patient;

或者使用 ROUND 函数进行四舍五入:

SELECT last_name AS patient, ROUND((JULIANDAY('now') - JULIANDAY(birth_date)) / 365) AS age
FROM patient;

现在,患者的年龄以整数的形式清晰地展示出来。


基于日期部分的查询

除了计算,日期函数还常用于过滤数据。例如,我们想查询哪些医生在星期一有预约。

这需要从 appointment 表中提取预约日期的星期几信息。SQLite 的 strftime 函数可以用于提取日期的特定部分。

以下是查询在星期一有预约的医生的步骤:

SELECT d.last_name, a.appt_date
FROM doctor d
JOIN appointment a ON d.did = a.did
WHERE strftime('%w', a.appt_date) = '1';

strftime 函数中,%w 格式符表示星期几,其中 0 代表星期日,1 代表星期一,依此类推。


查询特定月份的预约

类似地,我们可以查询在特定月份(例如二月)有预约的患者。

以下是实现方法:

SELECT p.last_name, a.appt_date
FROM patient p
JOIN appointment a ON p.pid = a.pid
WHERE strftime('%m', a.appt_date) = '02';

这里,strftime('%m', ...) 用于提取月份,02 代表二月。


总结 📝

本节课中我们一起学习了 SQL 单行函数的多种应用。

我们首先使用字符串拼接运算符 ||IIF 条件函数,组合并格式化了医生的全名与职称,同时处理了空值和大小写规范问题。

接着,我们利用 JULIANDAY 日期函数计算了患者的年龄,并通过除法和类型转换将其表示为整数。

最后,我们探索了 strftime 函数的强大功能,用它来提取日期的特定部分(如星期几和月份),从而实现了基于时间条件的复杂数据过滤。

掌握这些单行函数,能让你更灵活地处理和转换数据库中的数据,使查询结果更符合实际需求。

26:聚合函数 📊

在本节课中,我们将要学习SQL中的聚合函数。聚合函数能够对一列数据进行计算,并返回一个单一的值,这对于数据汇总和统计分析至关重要。

上一节我们介绍了SQL的基本查询操作,本节中我们来看看如何对数据进行聚合计算。

什么是聚合函数? 🤔

聚合函数是SQL中用于对一组值执行计算并返回单个值的函数。它们通常与SELECT语句的GROUP BY子句结合使用,用于汇总数据。

以下是SQL中一些最常用的聚合函数及其功能描述:

  • COUNT():统计指定列中非空值的数量。
    • 公式/代码SELECT COUNT(column_name) FROM table_name;
  • AVG():计算指定列中数值的平均值。
    • 公式/代码SELECT AVG(column_name) FROM table_name;
  • MAX():找出指定列中的最大值。
    • 公式/代码SELECT MAX(column_name) FROM table_name;
  • MIN():找出指定列中的最小值。
    • 公式/代码SELECT MIN(column_name) FROM table_name;
  • SUM():计算指定列中所有数值的总和。
    • 公式/代码SELECT SUM(column_name) FROM table_name;
  • STDDEV():计算指定列中数值的标准差,用于衡量数据的离散程度。
    • 公式/代码SELECT STDDEV(column_name) FROM table_name;
  • VAR()VARIANCE():计算指定列中数值的方差,是标准差的平方。
    • 公式/代码SELECT VARIANCE(column_name) FROM table_name;

了解了这些核心函数后,我们来看一个简单的应用示例。假设我们有一个sales表,其中包含amount(销售额)列。

-- 计算总交易次数、平均销售额、最高销售额和总销售额
SELECT
    COUNT(amount) AS transaction_count,
    AVG(amount) AS average_sale,
    MAX(amount) AS max_sale,
    SUM(amount) AS total_revenue
FROM sales;

这段查询会一次性返回四个聚合结果,让我们能够快速掌握销售数据的整体情况。


本节课中我们一起学习了SQL的聚合函数。我们了解了COUNTAVGMAXMINSUMSTDDEVVARIANCE这七个核心函数的作用,并看到了如何将它们组合在一个查询中,以便高效地对数据进行统计分析。掌握这些函数是进行数据汇总和探索性数据分析(EDA)的基础。

27:聚合函数应用编程演示 🧮

在本节课中,我们将学习如何使用 SQL 中的聚合函数对数据进行汇总计算。我们将通过一系列具体的查询示例,演示如何统计行数、计算最大值最小值,以及如何结合 GROUP BY 子句进行分组聚合。


概述

聚合函数是 SQL 中用于对一组值执行计算并返回单个值的函数。本节课将重点介绍 COUNTMAXMIN 等函数,并结合 GROUP BY 子句,展示如何从不同维度(如医生、科室、时间段)对医疗预约数据进行统计分析。


基础计数查询

首先,我们从最简单的计数查询开始,了解 COUNT 函数的基本用法。

以下是几个使用 COUNT 函数的基础示例:

  1. 统计医生总数
    我们使用 COUNT 函数,并传入参数 *。这将计算 doctor 表中的所有行数。

    SELECT COUNT(*) FROM doctor;
    

    COUNT 这样的聚合函数会返回一个跨行计算的单一汇总值。

  2. 统计医生头衔数量
    这里我们同样使用 COUNT 函数,但传入一个具体的列名 D_title。这将只计算该列中的值(非空值)数量。

    SELECT COUNT(D_title) FROM doctor;
    
  3. 统计不同科室的数量
    这里我们使用 COUNT 函数,但结合 DISTINCT 关键字和列名。目的是计算 specialty 列中不同值的数量。

    SELECT COUNT(DISTINCT specialty) FROM doctor;
    

结合条件过滤的计数

上一节我们介绍了基础的计数,本节中我们来看看如何结合 JOINWHERE 子句进行条件计数。

以下是结合表连接和过滤条件的计数查询:

  1. 统计全科内科的预约数量
    这里我将从 appointment 表中选择并计算所有行数。查询需要与 doctor 表连接,以获取医生科室信息。

    SELECT COUNT(*)
    FROM appointment a
    JOIN doctor d ON a.DID = d.DID
    WHERE d.specialty = 'general internal';
    

    这将统计科室为“全科内科”的医生的预约数量。

  2. 统计没有预约的病人数量
    我们将从 patient 表计数病人 ID,然后与 appointment 表进行左连接。连接基于 patient_id 列。

    SELECT COUNT(p.patient_id)
    FROM patient p
    LEFT JOIN appointment a ON p.patient_id = a.patient_id
    WHERE a.patient_id IS NULL;
    

    接着,我们过滤查询以寻找 patient_idNULL 的记录,这意味着左表(病人表)中的病人在右表(预约表)中没有匹配的预约。


使用 GROUP BY 进行分组聚合

掌握了单值聚合后,我们进入更强大的分组聚合。GROUP BY 子句允许我们将数据行分成组,然后对每个组应用聚合函数。

以下是使用 GROUP BY 的分组统计示例:

  1. 计算每位医生的预约总数
    我们首先选择一个列进行分组或折叠(这里是 Doctor_ID),然后对另一组列应用聚合函数(这里是 COUNT(*))。

    SELECT d.DID, COUNT(*) AS num_of_appointments
    FROM doctor d
    JOIN appointment a ON d.DID = a.DID
    GROUP BY d.DID;
    

    我们将聚合值命名为 num_of_appointments。查询会基于匹配的 DID 列连接 appointment 表,然后按照我们选择的第一个列(即 Doctor_ID 列)对连接后的行进行分组。这显示了每位医生或每个医生 ID 的总行数或预约数量。

  2. 查找每位医生的最后预约时间
    这里我们再次首先选择要折叠或分组的列 Doctor_ID (DID),然后应用 MAX 聚合函数来获取所有预约日期中的最晚时间。

    SELECT d.DID, MAX(a.appointment_date) AS last_appointment
    FROM doctor d
    JOIN appointment a ON d.DID = a.DID
    GROUP BY d.DID;
    

    我们将那个最晚时间命名为 last_appointment。查询基于匹配的 DID 列连接 appointment 表的信息,然后按照我们选择的第一个列 Doctor_ID 对连接的行进行分组。这显示了每个医生 ID 或医生的最晚时间或最后预约时间。

  3. 统计每个科室的医生数量
    我们将选择 specialty 列进行分组,然后通过计数 doctor 表的行来进行聚合。

    SELECT specialty, COUNT(*) AS doctor_count
    FROM doctor
    GROUP BY specialty;
    

    然后按照我们选择的同一列(即 specialty 列)进行分组。这显示了每个科室的行数统计。


多维度分组与复杂聚合

在能够进行单列分组后,我们可以尝试更复杂的多维度分组,并同时应用多个聚合函数。

以下是涉及多表连接、多列分组或多个聚合函数的复杂查询:

  1. 查找每个科室的首个和最后预约时间
    我们将选择 specialty 列进行分组或折叠。然后获取所有预约日期中的最早时间,我们称之为 first_appointment。同时获取所有预约日期中的最晚时间,称之为 last_appointment

    SELECT d.specialty,
           MIN(a.appointment_date) AS first_appointment,
           MAX(a.appointment_date) AS last_appointment
    FROM appointment a
    JOIN doctor d ON a.DID = d.DID
    GROUP BY d.specialty;
    

    查询从 appointment 表选择,并与 doctor 表连接(我们需要两个表的信息),基于匹配的 DID 列进行连接。然后按照我们选择的第一个列(即要折叠的 specialty 列)进行分组。这显示了每个科室的首个和最后预约时间。

  2. 统计每个时间段的预约总数
    我们将选择要分组或折叠的列。这将是从 appointment_date 中提取的时间值,然后通过计数每个组的行数来进行聚合。

    SELECT TIME(a.appointment_date) AS time_slot, COUNT(*) AS appointment_count
    FROM appointment a
    GROUP BY TIME(a.appointment_date);
    

    然后按照我们选择的同一项(即从 appointment_date 中提取的时间值)进行分组。这显示了每个唯一时间段的行政或预约数量。

  3. 统计每个科室的预约总数
    我们将选择 specialty,并计数行数。查询从 appointment 表出发,连接 doctor 表的信息。

    SELECT d.specialty, COUNT(*) AS appointment_count
    FROM appointment a
    JOIN doctor d ON a.DID = d.DID
    GROUP BY d.specialty;
    

    基于两个表中匹配的 DID 列值进行连接,然后按照 specialty 分组。这显示了每个唯一科室的预约数量。

  4. 统计每个科室和每个时间段的预约总数
    这里我们将选择两列进行分组或折叠:specialtyappointmenttime,然后计数每个科室和时间段组合的行数。

    SELECT d.specialty,
           TIME(a.appointment_date) AS time_slot,
           COUNT(*) AS appointment_count
    FROM appointment a
    JOIN doctor d ON a.DID = d.DID
    GROUP BY d.specialty, TIME(a.appointment_date);
    

    基于两个表中匹配的 DID 列值连接 appointment 表和 doctor 表的信息,然后按照我们选择的那些相同列(即 specialtyappointmenttime)进行分组。这显示了每个唯一的科室与时间段组合的行数或预约数量。


总结

本节课中我们一起学习了 SQL 聚合函数的强大功能。我们从简单的 COUNT(*) 开始,逐步深入到结合 WHERE 过滤、使用 GROUP BY 进行单列及多列分组,并应用了 MAXMIN 等聚合函数。通过这些示例,你应能掌握如何对数据进行不同维度的汇总分析,这是进行数据探索和生成报告的关键技能。

28:数据创建 🗃️

在本节课中,我们将学习如何在数据库中创建新的数据表,以及如何向表中插入数据。我们将涵盖创建表的基本语法、常见的数据类型,以及两种插入数据的方法。

创建新表

要创建一个新表,需要使用 CREATE TABLE 语句。

该语句需要为新表指定一个名称,并在括号内提供一个以逗号分隔的列名及其对应数据类型的列表。

以下是创建表的基本语法结构:

CREATE TABLE table_name (
    column1 datatype constraint,
    column2 datatype constraint,
    ...
    table_constraint
);

其中,每一列的数据类型定义了该列将要存储的数据种类。

你可以为每一列指定一个可选的列约束,这是一条用于允许或限制该列值的规则。

你也可以指定一个可选的表约束,这是一条用于允许或限制表中整行数据的规则。

常见数据类型

在定义新表的列时,了解可用的数据类型至关重要。以下是几种常见的数据类型分类。

字符串数据类型

以下是定义新表列时一些常见的字符串数据类型:

  • CHAR(n):这是一个固定长度的字符串,n 代表给定的最大字符数。
  • VARCHAR(n):这是一个可变长度的字符串,n 代表给定的最大字符数。
  • TEXT:这是一个大型字符串,具有给定的最大字符数限制。

数值数据类型

以下是一些常见的数值数据类型:

  • BIT:一个非常小的整数值。
  • INT:标准整数值。
  • BIGINT:大整数值。
  • DECIMAL(p, s):一个十进制数值,p 代表总的最大位数(精度),s 代表小数点右侧的位数(标度)。

日期时间数据类型

以下是一些常见的日期时间数据类型:

  • DATE:日期,显示格式通常为 YYYY-MM-DD
  • DATETIME:日期与时间的组合,显示格式通常为 YYYY-MM-DD HH:MM:SS
  • TIMESTAMP:另一种日期与时间的组合,显示格式通常为 YYYY-MM-DD HH:MM:SS

大型对象数据类型

以下是一个常见的大型对象数据类型:

  • BLOB:二进制大型对象,具有给定的以字节为单位的最大大小。

从现有表复制数据

上一节我们介绍了如何创建一个空表,本节中我们来看看如何用现有数据填充它。一种方法是从另一个表复制记录。

要将记录从现有表复制到新表,首先使用 INSERT INTO 语句。

指定你要插入记录的新表,以及你要放入数据的新表列名的逗号分隔列表。

然后,使用 SELECT 语句从现有表中选择要插入到新表中的记录。

以下是该操作的语法示例:

INSERT INTO new_table (column1, column2, ...)
SELECT column1, column2, ...
FROM existing_table;

请注意,如果你为每一列都提供了值,并且顺序与表定义一致,那么可以省略新表列名的逗号分隔列表。并非所有字段都是必需的。

插入新记录

除了从其他表复制,我们也可以直接插入全新的数据行。

要向新表中插入记录,首先使用 INSERT INTO 语句。

指定你要插入记录的表,以及你要放入数据的表列名的逗号分隔列表。

然后,使用 VALUES 命令,后跟要插入的值的逗号分隔列表。

以下是该操作的语法示例:

INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

再次注意,如果你为每一列都提供了值,并且顺序与表定义一致,那么可以省略表列名的逗号分隔列表。


本节课中我们一起学习了在SQL中创建数据的核心操作。我们掌握了使用 CREATE TABLE 语句定义新表结构的方法,了解了常见的字符串、数值、日期等数据类型。接着,我们探讨了两种填充数据的方式:使用 INSERT INTO ... SELECT ... 从现有表复制数据,以及使用 INSERT INTO ... VALUES ... 直接插入新记录。理解这些基础语句是进行有效数据管理和分析的第一步。

29:CREATE TABLE与INSERT INTO 🗂️

在本节课中,我们将学习如何使用SQL语句创建新表(CREATE TABLE)以及如何向表中插入数据(INSERT INTO)。这是构建和管理数据库的基础。

概述

我们将通过一个模拟的医疗数据库示例,演示如何创建doctorpatientappointmentoffice表,并向这些表中插入数据。你将学会创建表结构、从其他数据库复制数据以及手动插入新记录。


创建新表

首先,我们将在演示数据库中创建一个新的doctor表。

CREATE TABLE doctor (
    D_ID INT DEFAULT 0,
    first_name VARCHAR DEFAULT NULL,
    last_name VARCHAR DEFAULT NULL,
    D_title VARCHAR(10) DEFAULT NULL,
    specialty VARCHAR(50) DEFAULT ‘no’
);

以上语句创建了一个名为doctor的表,包含医生ID、名、姓、职称和专业等列。

接下来,我们创建一个patient表。

CREATE TABLE patient (
    PID INT DEFAULT 0,
    P_first_name VARCHAR(75) DEFAULT NULL,
    P_last_name VARCHAR(75) DEFAULT NULL,
    B_date VARCHAR(20) DEFAULT NULL
);

这将在数据库中创建patient表,包含患者ID、名、姓和出生日期等列。


从其他数据库复制数据

为了从SQLite的另一个数据库复制记录,我们需要先附加该数据库。然后,我们可以将数据复制到新创建的表中。

以下是复制doctor表记录的示例:

INSERT INTO doctor (D_ID, first_name, last_name, D_title, specialty)
SELECT D_ID, first_name, last_name, D_title, specialty
FROM other_example_db.doctor;

这条语句将另一个示例数据库中doctor表的所有记录复制到当前数据库的doctor表中。

查看新doctor表的信息,可以看到它包含了所有相同的记录。

同样地,我们复制patient表的所有记录:

INSERT INTO patient (PID, P_first_name, P_last_name, B_date)
SELECT PID, P_first_name, P_last_name, B_date
FROM other_example_db.patient;

查看patient表,确认它包含了所有相同的记录。


通过查询创建并填充新表

我们还可以在一个查询中创建新表并直接填充数据。例如,创建一个appointment表:

CREATE TABLE appointment AS
SELECT *
FROM other_example_db.appointment;

这会创建一个与源表结构完全相同的appointment表,并复制所有数据。

查看新appointment表的信息,确认它包含了所有相同的记录。


手动插入新数据

现在,我们手动向表中插入新的记录。

首先,向doctor表插入一条新记录:

INSERT INTO doctor (D_ID, first_name, last_name, D_title, specialty)
VALUES (9, ‘Brandon’, ‘Kraowski’, ‘M’, ‘Dermatology’);

这将在doctor表中插入一条ID为9、名为Brandon Kraowski的皮肤科医生记录。

接下来,为这位新医生在2026年2月16日上午10点和11点安排两个预约:

INSERT INTO appointment (appointment_ID, date, D_ID)
VALUES
    (10, ‘2026-02-16 10:00’, 9),
    (11, ‘2026-02-16 11:00’, 9);

这将在appointment表中插入两条新记录。

然后,添加一名新患者Elliot Graham,注意其出生日期未知:

INSERT INTO patient (PID, P_first_name, P_last_name)
VALUES (12, ‘Elliot’, ‘Graham’);

由于未指定B_date列,该字段将为NULL。


创建并填充office

最后,我们创建一个新的office表:

CREATE TABLE office (
    office_ID INT,
    office_address VARCHAR(200),
    office_open_date DATE
);

这将创建一个包含办公室ID、地址和开业日期的office表。

初始时,该表为空。我们插入一条默认的办公室记录:

INSERT INTO office
VALUES (1, ‘Philadelphia’, ‘1994-04-11’);

注意,这里没有指定列名,SQL会默认使用所有列并按顺序插入值。


查看结果

现在,让我们查看所有表格的新信息:

  • 查询doctor表,可以看到底部新增了Brandon Kraowski的记录。
  • 查询appointment表,可以看到底部新增了两条记录。注意,由于未指定患者ID(PID),该字段为空。
  • 查询patient表,可以看到底部新增了Elliot Graham的记录,且出生日期字段为空。
  • 查询office表,可以看到插入了一条记录。

总结

在本节课中,我们一起学习了SQL的两个核心操作:CREATE TABLEINSERT INTO。我们掌握了如何创建具有特定列和数据类型的新表,如何从其他表或数据库复制数据,以及如何手动向表中插入单条或多条记录。这些是进行数据存储和管理的基础技能。

30:数据导入与导出 🗃️

概述

在本节课中,我们将学习如何将数据从文件导入到数据库表中,以及如何将数据库中的查询结果或表导出到外部文件。这是数据管理中的基础且关键的操作。


数据导入 📥

上一节我们概述了数据导入导出的重要性,本节中我们来看看如何将本地数据文件导入到数据库表中。一种方法是使用 LOAD DATA LOCAL INFILE 语句。

以下是使用该语句导入数据的关键步骤:

  1. 指定数据文件:使用 LOAD DATA LOCAL INFILE 并指定要加载的数据文件。请确保使用本地计算机上文件的完整路径。
  2. 指定目标表:使用 INTO TABLE 来指定要将数据导入的数据库表。
  3. 指定列分隔符:使用 FIELDS TERMINATED BY 来指定列分隔符,即文件中用于分隔每列数据的定界符。
  4. 指定列包围符:使用 OPTIONALLY ENCLOSED BY 来指定列包围符,即文件中可选的数据值包围字符。
  5. 指定行终止符:使用 LINES TERMINATED BY 来指定换行指示符,即数据文件中用于表示新行的字符。
  6. 指定跳过的行数:使用 IGNORE 来指定要跳过的行数,即数据文件中开头部分不加载的行数。例如,你可能希望跳过文件中的标题行。


数据导出 📤

了解了数据导入后,我们接下来学习数据导出。将结果集或表导出到外部文件的一种方法是使用数据库管理工具(如 DBeaver)中的导出选项,或你偏好的 SQL 开发软件中的类似功能。

请注意,这种方法适用于较小的结果集或表。

对于导出较大的结果集或表,你可以使用 SELECT INTO OUTFILE 语句,该语句将结果行写入指定的文件。

请注意,此输出文件必须位于数据库系统有写入权限的目录中。

关于 SELECT INTO OUTFILE 的更多信息,请查阅本模块的后续阅读材料。

要从数据库导出数据的其他方法,请查阅你的数据库服务设置的文档。


总结

本节课中,我们一起学习了两种核心的数据操作。我们掌握了使用 LOAD DATA LOCAL INFILE 语句将本地文件数据导入数据库表的方法,也了解了通过数据库管理工具或 SELECT INTO OUTFILE 语句将数据从数据库导出到文件的过程。这些是进行数据交换和管理的基础技能。

31:SQLite数据加载演示 📊

在本节课中,我们将学习如何将外部数据文件导入到SQLite数据库中一个已存在的表中。我们将通过一个具体的操作演示,展示从选择文件、配置导入设置到最终完成数据加载的完整流程。


上一节我们介绍了SQLite数据库的基本概念,本节中我们来看看如何将外部数据文件导入到已创建的表中。

首先,我们需要启动数据导入功能。在SQLite数据库管理工具中,找到并点击“导入数据”选项。

接下来,系统会提示我们选择一个要导入的文件。

我们需要在文件资源管理器中定位到目标数据文件。

在选择文件后,我们需要查看并配置导入设置。以下是关键的配置步骤:

在“属性”设置中,我们需要特别注意“列分隔符”这一项。它通常以粗体显示,用于指定数据文件中分隔各列数据的字符。在本例中,它被设置为 \t,这代表一个制表符(Tab字符)。

配置完分隔符后,我们需要进入“表映射”设置。这一步的目的是确保源文件中的数据列能正确映射到目标数据库表的对应列。

我们将目标表名设置为 offices

如果继续执行,我们可以预览到所有即将被创建或填充的数据列。

最后,执行导入操作。操作成功后,我们可以在数据库中看到数据已经成功导入到 offices 表中。


本节课中我们一起学习了将外部数据文件导入SQLite数据库的完整过程。关键步骤包括:启动导入功能、选择数据文件、配置列分隔符(如 \t)、进行表映射以匹配目标表结构,以及最终执行并验证导入结果。掌握这个流程是进行数据管理和分析的基础。

32:SQL 数据交叉表与条件聚合 📊

在本节课中,我们将学习如何在 SQL 中创建交叉表。交叉表是一种将聚合函数应用于多个列,并以表格形式呈现结果的数据汇总方法。我们将重点介绍使用 IFCASE 这两种流程控制函数来实现条件聚合。


使用 IF 函数创建交叉表

上一节我们介绍了交叉表的基本概念,本节中我们来看看如何使用 IF 函数来构建它。

IF 函数是一个流程控制函数,它根据给定条件的真假返回不同的值。其基本语法如下:

IF(condition, value_if_true, value_if_false)

以下是使用 IF 函数创建交叉表的步骤:

  1. 选择分组列:首先,使用 SELECT 语句指定需要进行分组或合并的列。
  2. 创建条件聚合列:然后,使用 IF 函数创建新的列。这些列的值是基于特定条件对原始列应用聚合函数(如 SUM, COUNT, AVG 等)计算得出的。
  3. 指定数据源与分组:最后,使用 FROM 子句指定数据来源的表,并使用 GROUP BY 子句按适当的列进行分组。

一个简单的示例如下:

SELECT
    department,
    SUM(IF(gender = 'M', salary, 0)) AS male_salary_total,
    SUM(IF(gender = 'F', salary, 0)) AS female_salary_total
FROM employees
GROUP BY department;

使用 CASE 函数创建交叉表

除了 IF 函数,CASE 表达式是另一种实现条件聚合的强大工具。它提供了处理多个条件的更清晰结构。

CASE 表达式会依次评估给定的条件,并返回第一个满足条件所对应的值。其基本语法结构如下:

CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE default_result
END

以下是使用 CASE 表达式创建交叉表的步骤:

  1. 选择分组列:首先,在 SELECT 语句中确定用于分组的列。
  2. 创建条件聚合列:接着,使用 CASE 表达式在 SELECT 列表中创建新列。在这些列内部,根据不同的条件对目标列应用聚合函数。
  3. 指定数据源与分组:使用 FROM 子句指明查询的表,并通过 GROUP BY 子句完成最终的分组操作。

一个简单的示例如下:

SELECT
    product_category,
    COUNT(CASE WHEN region = 'North' THEN order_id END) AS north_orders,
    COUNT(CASE WHEN region = 'South' THEN order_id END) AS south_orders,
    COUNT(CASE WHEN region = 'East' THEN order_id END) AS east_orders,
    COUNT(CASE WHEN region = 'West' THEN order_id END) AS west_orders
FROM sales
GROUP BY product_category;

总结 📝

本节课中我们一起学习了 SQL 中创建交叉表的两种核心方法。

  • 我们首先了解了交叉表是一种对多列进行条件聚合并以表格形式展示的数据汇总方式。
  • 然后,我们深入探讨了如何使用 IF(condition, true_value, false_value) 函数来实现简单的二元条件判断和聚合。
  • 最后,我们学习了功能更强大的 CASE...WHEN...THEN...ELSE...END 表达式,它能够清晰、灵活地处理多个复杂条件,是构建交叉表的常用选择。

掌握这两种技术,你将能够有效地对数据进行多维度的分析和汇总。

33:数据格式化编程演示 📊

在本节课中,我们将学习如何使用SQL进行数据格式化,具体目标是统计每位医生在每个时间段(如10 AM、11 AM、12 PM)的预约数量,并将结果整理成清晰的交叉表格式。

概述与目标

上一节我们介绍了数据查询的基础,本节我们将重点学习如何对查询结果进行格式化重塑。我们将通过一个具体案例:统计医生在每个时间段的预约数,并最终生成一个易于阅读的汇总表。

核心任务:生成时间段预约交叉表

我们的目标是展示每位医生在每个时间段的预约数量,每个时间段应作为独立的列显示。

以下是实现此目标的主要步骤:

  1. 使用条件聚合查询:编写SQL查询,利用条件函数(IIFCASE)将预约按小时归类到不同的时间段列中。
  2. 创建存储表:将查询结果持久化存储到一个新表中,方便后续使用。
  3. 关联详细信息:将汇总数据表与医生表连接,以获取医生的完整姓名。

接下来,我们将详细分解每个步骤。

步骤一:使用条件聚合进行查询

我们首先需要从doctor表和appointment表中提取数据,并按医生分组,计算每个时间段的预约总数。

方法A:使用 IIF 函数

IIF函数是SQLite中的一个条件函数,语法为 IIF(条件, 为真时的值, 为假时的值)

以下是查询语句:

SELECT
    d.DID AS `Doctor ID`,
    d.LastName AS `Last Name`,
    SUM(IIF(STRFTIME('%H', a.AppointmentDate) = '10', 1, 0)) AS `10 AM`,
    SUM(IIF(STRFTIME('%H', a.AppointmentDate) = '11', 1, 0)) AS `11 AM`,
    SUM(IIF(STRFTIME('%H', a.AppointmentDate) = '12', 1, 0)) AS `12 PM`
FROM doctor d
JOIN appointment a ON d.DID = a.DID
GROUP BY d.DID, d.LastName;

代码解释

  • STRFTIME(‘%H’, a.AppointmentDate) 用于从预约日期中提取小时数。
  • IIF(...) 判断小时数是否等于目标值(如10),如果是则返回1,否则返回0。
  • SUM(...) 将所有医生的1(代表有预约)累加起来,得到该时间段的总预约数。

方法B:使用 CASE 表达式

CASE表达式是更标准的SQL条件语句,功能更强大。

以下是等效的查询语句:

SELECT
    d.DID AS `Doctor ID`,
    d.LastName AS `Last Name`,
    SUM(
        CASE
            WHEN STRFTIME('%H', a.AppointmentDate) = '10' THEN 1
            ELSE 0
        END
    ) AS `10 AM`,
    SUM(
        CASE
            WHEN STRFTIME('%H', a.AppointmentDate) = '11' THEN 1
            ELSE 0
        END
    ) AS `11 AM`,
    SUM(
        CASE
            WHEN STRFTIME('%H', a.AppointmentDate) = '12' THEN 1
            ELSE 0
        END
    ) AS `12 PM`
FROM doctor d
JOIN appointment a ON d.DID = a.DID
GROUP BY d.DID, d.LastName;

两种方法执行结果完全相同,都会生成一个显示医生ID、姓氏以及各时间段预约数量的结果集。

步骤二:创建永久汇总表

为了后续分析方便,我们可以将上一步的查询结果保存到一个新表中。

首先,创建用于存储结果的新表结构:

CREATE TABLE appointments_by_time (
    DoctorID INTEGER,
    `10 AM` INTEGER,
    `11 AM` INTEGER,
    `12 PM` INTEGER
);

表结构说明

  • DoctorID:医生ID,整数类型。
  • 10 AM, 11 AM, 12 PM:均为整数类型,分别存储对应时间段的预约数量。

创建后,可以确认表为空:

SELECT * FROM appointments_by_time;

接下来,使用INSERT INTO ... SELECT语句将我们的查询结果插入新表。这里我们选用CASE版本的查询:

INSERT INTO appointments_by_time (DoctorID, `10 AM`, `11 AM`, `12 PM`)
SELECT
    d.DID,
    SUM(CASE WHEN STRFTIME('%H', a.AppointmentDate) = '10' THEN 1 ELSE 0 END),
    SUM(CASE WHEN STRFTIME('%H', a.AppointmentDate) = '11' THEN 1 ELSE 0 END),
    SUM(CASE WHEN STRFTIME('%H', a.AppointmentDate) = '12' THEN 1 ELSE 0 END)
FROM doctor d
JOIN appointment a ON d.DID = a.DID
GROUP BY d.DID;

插入完成后,再次查询该表,即可看到每位医生在每个时间段的预约统计:

SELECT * FROM appointments_by_time;

步骤三:关联医生详细信息

appointments_by_time表只有医生ID。为了生成最终报告,我们通常需要显示医生的姓名。

通过JOIN操作将汇总表与doctor表连接,即可获取完整信息:

SELECT
    d.FirstName,
    d.LastName,
    a.`10 AM`,
    a.`11 AM`,
    a.`12 PM`
FROM doctor d
JOIN appointments_by_time a ON d.DID = a.DoctorID;

查询解释

  • doctor表(别名d)中选择FirstNameLastName
  • appointments_by_time表(别名a)中选择各时间段的预约数列。
  • 通过d.DID = a.DoctorID将两表连接起来。

运行此查询,我们将得到一个包含医生全名和分时段预约数量的清晰、完整的汇总视图。

总结

本节课我们一起学习了数据格式化的关键技巧。我们掌握了如何使用 IIFCASE 表达式配合 SUM 聚合函数来创建条件计数,从而将行数据转换为列格式的交叉表。接着,我们学习了如何将查询结果保存到新表中以实现数据持久化。最后,通过表连接操作,我们整合了汇总数据与详细维度信息,生成了最终易于理解的报告。这些技能是进行数据汇总、报告生成和进一步分析的基础。

33:探索性数据分析(EDA)概述 📊

在本节课中,我们将学习探索性数据分析(EDA)的核心概念。EDA是一种分析数据以总结其主要特征并提取基本洞察的方法。我们将了解如何通过Python进行数据操作,并掌握数据聚合、汇总及可视化的关键技能。


探索性数据分析是数据分析流程中至关重要的第一步。它旨在通过可视化和统计方法理解数据集的结构、识别模式、发现异常并检验假设。

上一节我们介绍了数据分析的整体框架,本节中我们来看看探索性数据分析的具体内涵。

什么是探索性数据分析(EDA)?

探索性数据分析是一种分析数据的方法,其核心是总结数据的主要特征提取基本洞察。它不依赖于严格的建模假设,而是通过直观的探索来理解数据。

本模块的学习目标 🎯

本模块将深入探讨使用Python进行数据操作的实践方面。

以下是本模块涵盖的核心内容:

  • 数据加载、检查与查询:学习如何处理真实世界的数据。
  • 回答基本数据问题:掌握从数据中获取答案的技巧。
  • 数据聚合与汇总:学习如何对数据进行分组和统计。
  • 数据可视化:这是任何数据分析的关键部分,我们将学习如何用图形展示数据。

将使用的工具与库 🛠️

为了达成上述目标,我们将使用Python中强大的数据分析生态系统。

以下是本模块将重点使用的库:

  • 数据分析库pandasNumPy
    • pandas 用于数据操作和分析。
    • NumPy 提供高效的数值计算支持。
  • 数据可视化库Matplotlibseaborn
    • Matplotlib 是基础绘图库。
    • seaborn 基于Matplotlib,提供更美观的统计图形。

实践练习 💻

为了确保全面理解所学概念并获得实践经验,本模块包含一系列简短的Python练习。

这些练习旨在巩固所学材料,并帮助你在真实的数据分析场景中应用相关技术,从而有效提升你进行探索性数据分析的能力。


本节课中,我们一起学习了探索性数据分析(EDA)的定义及其在数据分析流程中的重要性。我们明确了本模块的学习目标,包括数据操作、汇总和可视化,并介绍了实现这些目标所需的Python核心库(pandas, NumPy, Matplotlib, seaborn)。最后,我们了解到通过配套的实践练习,可以将理论知识转化为实际技能。

35:📊 数据加载、审查与查询

在本节课中,我们将学习如何使用 pandas 模块加载、审查和查询数据。我们将从 CSV 文件中读取数据,并探索数据框的基本属性和方法。


概述

Pandas 模块提供了多种数据分析工具,它可以连接并与数据库交互,也能读写 Excel 文件和 CSV 文件。导入 Pandas 模块后,我们可以使用 read_csv 方法将 CSV 文件读取到一个数据框中。

一个数据框是一个二维的、带标签的数据结构。你可以把它想象成一个电子表格或数据库表。

在开始之前,请确认你已经下载了所需的数据文件。我们将使用一个描述 Instacart 用户历史订单的关系型数据集。该数据集包含了 Instacart 用户的杂货订单样本。对于每个用户,我们有订单信息,包括每个订单中购买的产品序列;对于每个订单,我们还有下单的星期几和一天中的小时,以及订单之间的相对时间间隔。


数据集文件说明

以下是数据集中各个 CSV 文件的说明。

产品文件 (products.csv)

此文件包含所购产品的信息。

  • product_id: 引用单个产品的标识符。
  • product_name: 产品名称。
  • aisle_id: 引用市场内货道的标识符。
  • department_id: 引用产品所属部门的标识符。

部门文件 (departments.csv)

此文件包含市场内部门的信息。

  • department_id: 引用部门的标识符。
  • department: 部门名称。

货道文件 (aisles.csv)

此文件包含市场内货道的信息。

  • aisle_id: 引用货道的标识符。
  • aisle: 货道名称。

订单文件 (orders.csv)

此文件包含客户订单的信息。

  • order_id: 引用不同订单的标识符。
  • user_id: 引用下单用户的标识符。
  • order_number: 订单编号。
  • order_dow: 订单的星期几。
  • order_hour_of_day: 订单的时间(一天中的小时)。
  • days_since_prior_order: 距离上次订单的天数。

订单产品文件 (order_products__prior.csv)

此文件包含每个订单中购买了哪些产品的信息,以及客户之前的订单内容。

  • order_id: 引用不同订单的标识符。
  • product_id: 引用产品的标识符。
  • add_to_cart_order: 订单购物车中商品的顺序 ID。
  • reordered: 指示客户以前是否订购过此产品。

加载与读取数据

现在,让我们加载并读取产品 CSV 数据文件。首先导入 pandas,然后使用 read_csv 方法将数据加载到数据框中。

import pandas as pd
df = pd.read_csv('products.csv')

我们可以看到 df 的类型是一个数据框。

type(df)
# 输出: pandas.core.frame.DataFrame

审查数据框

加载数据后,我们需要了解其基本结构。以下是几种审查数据框的方法。

查看数据维度

我们可以获取行数,并通过访问 shape 属性来获取数据框的行数和列数。

df.shape
# 输出: (行数, 列数)

查看列信息

你可以通过访问 columns 属性来检查列标题。

df.columns

通过访问 dtypes 属性,可以获取每列存储的数据类型。

df.dtypes

Pandas 数据类型简介

以下是一个描述数据框中可存储的不同数据类型的实用表格。

  • object: Python 字符串或混合类型,包含文本或混合的数字与非数字值。
  • int64: Python int 或整数。
  • float64: Python float 或浮点数(小数)。
  • bool: TrueFalse 值。
  • datetime64: 包含日期和时间值。
  • timedelta: 两个日期时间之间的差值。
  • category: 包含有限的文本值列表。

获取数值摘要

describe 方法为数据框中的数值提供各种汇总统计信息。

df.describe()

查看数据内容

了解数据结构后,我们来看看具体的数据内容。以下是查看数据的不同方法。

查看头部数据

head 方法默认显示数据的前五行。如果提供参数,它将显示给定数量的行。

df.head()      # 显示前5行
df.head(50)    # 显示前50行

查看尾部数据

tail 方法默认显示数据的最后五行。如果提供参数,它将显示最后给定数量的行。

df.tail()      # 显示最后5行
df.tail(50)    # 显示最后50行

查看随机样本

sample 方法返回给定数量的随机行。

df.sample(10)  # 随机返回10行

删除重复行

你可以使用 drop_duplicates 方法从数据框中删除重复项。默认情况下,此方法会查看所有列以识别并删除数据中的重复行。

df_deduped = df.drop_duplicates()

总结

在本节课中,我们一起学习了如何使用 pandas 加载 CSV 数据到数据框中。我们介绍了如何审查数据框的基本属性,如形状、列名和数据类型。我们还探索了多种查看数据内容的方法,包括查看头部、尾部、随机样本以及删除重复行。这些是进行数据分析和探索性数据分析(EDA)的基础步骤。

36:数据加载与审查 📊

在本节课中,我们将学习如何使用Python的Pandas库加载数据,并掌握审查数据框(DataFrame)基本信息的基本方法。我们将从导入库开始,逐步学习如何查看数据的结构、统计信息以及处理重复项。


导入库与加载数据

首先,我们需要导入数据分析的核心库——Pandas。我们通常为其设置一个简短的别名,以便后续调用。

import pandas as pd

我们将使用Instacart数据集进行演示。第一步是加载产品数据文件。

df = pd.read_csv('products.csv')

运行上述代码后,我们便创建了一个名为 df 的数据框。


检查数据框基本信息

上一节我们成功加载了数据,本节中我们来看看如何检查数据框的基本属性。

我们可以使用 type() 函数来确认 df 的类型。

type(df)

输出pandas.core.frame.DataFrame

要查看数据框的行数,可以使用 len() 函数。

len(df)

输出49688

如果想同时获取行数和列数,可以使用数据框的 .shape 属性。

df.shape

输出(49688, 4)。这表示数据框有49,688行和4列数据。


查看数据摘要统计

在了解了数据的基本规模后,我们来看看数据的数值特征。

使用数据框的 .describe() 方法,可以快速获取数值列的关键统计信息,包括计数、均值、标准差、最小值和最大值。

df.describe()

查看数据行

接下来,我们学习如何查看数据的具体内容。

使用 .head() 方法可以查看数据框的前几行。默认显示前5行。

df.head()

如果想查看指定数量的行,可以向 .head() 方法传入一个数字参数。

df.head(10)

有时,数据中可能存在重复行。在大多数情况下,我们需要移除这些重复项。假设我们有一个包含重复行的新数据框 df_with_duplicates

df_no_duplicates = df_with_duplicates.drop_duplicates()

默认情况下,.drop_duplicates() 会基于所有列删除完全重复的行。执行后,将返回一个移除了重复行的新数据框。

要查看数据框末尾的数据,可以使用 .tail() 方法。默认显示最后5行。

df.tail()

同样,可以指定查看的行数。

df.tail(50)

获取数据框详细信息

另一个有用的方法是 .info(),它可以提供数据框的简明摘要。

df.info()

对于数据框中的每一列,它会显示列名、非空值的数量以及该列的数据类型。


识别与处理重复值

假设我们的数据框存在重复行,并且希望在删除前先检查哪些行是重复的。

.duplicated() 方法会返回一个布尔序列,标记出重复的行。

duplicate_series = df_with_duplicates.duplicated()

返回的序列中,False 表示该行不重复,True 表示该行在数据框中的其他地方存在重复。


检查列的唯一值

我们还可以检查某一列中有哪些不同的值。

以下代码返回 department_id 列中的所有唯一值。

df_with_duplicates['department_id'].unique()

如果我们只想知道某一列有多少个唯一值,可以使用 .nunique() 方法。

df_with_duplicates['department_id'].nunique()

输出21。这表示 department_id 列中有21个不同的部门ID。


总结

本节课中,我们一起学习了Python数据分析的第一步:数据加载与审查。我们掌握了如何使用Pandas加载CSV文件,并运用了多种方法来探索数据框,包括检查其维度、查看摘要统计、浏览数据行、识别重复项以及分析列的唯一值。这些是进行任何数据分析前必不可少的基础操作。

37:数据查询编程演示 🧐

在本节课中,我们将学习如何使用Pandas库来查询数据。我们将从查看一个包含所有产品的数据框开始,并逐步探索多种基于索引选择数据行的方法,以及如何比较数据框中的值。


查看数据框

我们从一个包含所有产品的数据框开始。首先,让我们查看它的前几行。

以下是数据框的前五行。第一列是自动为每一行分配的索引。

索引从0开始。


基于索引选择数据行

Pandas提供了多种基于索引获取数据行切片的方法。

让我们查看数据框中列出的第100到200行。

我们可以使用 iloc 函数,在方括号内使用冒号来获取行的切片。

我们需要指定想要选择的索引范围。我们将输入 100:200

Pandas中范围的规则与Python中的规则相同:左边的索引包含在内,右边的索引不包含在内。

# 使用 iloc 选择第100到199行(索引从0开始)
df.iloc[100:200]

这是另一种实现方式。我们可以直接对数据框使用方括号,并提供一个索引范围来获取行的切片。

# 直接使用方括号选择行
df[100:200]

同样,这显示了数据框中的第二组一百行。


获取最后一行数据

现在,让我们获取数据中列出的最后一个产品的名称。

为此,我们需要获取数据框中的最后一个索引。

我们可以通过数据框的长度减1来计算最后一个索引。

我们将创建一个变量 last_index,并将其设置为数据框的长度减1。

# 计算最后一个索引
last_index = len(df) - 1

然后,我们创建另一个变量 last_product,将其设置为数据框 iloc 的切片,索引范围从 last_index 到数据框的末尾。

# 选择最后一行
last_product = df.iloc[last_index:]

这给了我们一个单行数据框,然后我们显示这一行。结果显示为“Fresh foaming cleanser”。


使用负索引的简便方法

这里有另一个非常简单的方法来实现同样的效果。使用 iloc 函数,你可以指定 -1 到数据框的末尾。

-1 是指示数据框中最后一个索引的另一种方式。

# 使用负索引选择最后一行
last_product = df.iloc[-1:]

同样,我们得到了一个包含单行的切片,即“Fresh foaming cleanser”。


比较数据框中的值

我们可以使用 eq 函数来比较数据框中的每个值,看它是否等于指定的值。

例如,如果我想检查数据框中等于19的值,我可以直接应用 eq 函数并提供一个参数19。

# 检查哪些值等于19
df.eq(19)

这将显示整个数据框。对于任何等于19的特定值,它显示为 True,否则显示为 False


总结

在本节课中,我们一起学习了如何使用Pandas进行数据查询。我们探讨了如何查看数据框、基于索引选择特定的数据行(包括使用正索引和负索引),以及如何使用 eq 函数比较数据框中的值。这些基本操作是进行有效数据分析的重要步骤。

38:Codio平台Jupyter Notebook作业指南 📘

在本节课中,我们将学习如何在Codio平台上使用Jupyter Notebook完成课程作业。Codio是一个优秀的在线平台,它为你提供了预配置的环境,让你能在Mac、Windows或Linux系统上无缝运行代码。

概述

我们将逐步介绍从打开作业到最终提交的完整流程,包括如何运行代码、排查常见错误以及确保作业正确完成。

启动作业环境

首先,你会看到一个需要Jupyter Notebook的作业页面。

你可以选择跟随本页的Jupyter Notebook指引,或者向下滚动,按照提供的PDF文件中的详细作业说明进行操作。

以下是启动环境的步骤:

  1. 向下滚动至页面底部。
  2. 勾选确认框。
  3. 如果是首次使用,请输入你的法定姓名。
  4. 点击“启动应用”按钮。

环境设置通常需要20秒到1分钟。如果页面没有反应,请尝试刷新。

启动后,你将看到一个包含额外说明的引导页面。请从该页面打开Jupyter Notebook。

在Notebook中工作

Codio环境已为你预先配置好。

要运行第一个代码单元,请按 Shift + Enter(在Mac上是 Shift + Return)。这个操作会导入整个练习所需的所有库以及参考答案。

问题已按步骤列出。请仔细遵循,在标有“你的代码在这里”的地方编写代码来回答问题。

请按顺序执行每个代码单元。测试单元会将你的变量与环境存储的答案变量进行比较。按 Shift + Enter 来验证你的变量,你将在单元格下方看到每个测试的结果。

故障排除与调试

上一节我们介绍了如何运行代码,本节中我们来看看如何处理一些常见问题。

文件路径错误

加载数据文件时,一个常见错误是文件路径不正确,这会导致“文件未找到”错误。

错误示例如下:

FileNotFoundError: [Errno 2] No such file or directory: 'wrong_path/data.csv'

代码编辑器中会高亮显示引发错误的那行代码。

修复方法是更正代码中的文件路径。例如,将路径改为正确的:

df = pd.read_csv('correct_path/data.csv')

修正后重新运行单元格,错误便会消失。

逻辑错误

如果你的代码能运行但返回错误结果,请将你的逻辑与项目要求进行对比。仔细检查变量和计算以确保准确性。

例如,假设我们将错误的数据信息存储到了变量中:

# 错误:获取了错误DataFrame的长度
num_restaurants = len(restaurant_except_df)

# 正确:应获取目标DataFrame的长度
num_restaurants = len(restaurant_location_df)

运行这类代码时可能不会报错,但后续的测试会失败,并显示断言错误,指出你的变量与答案不匹配。

修复逻辑后重新运行测试,即可通过。

查阅文档

遇到不熟悉的函数时,可以利用官方文档(如Pandas文档)来理解函数参数。例如,对于 read_csv 函数,你可以查阅其具体用法。

提交前的检查

在提交作业之前,请重置内核并按顺序运行所有单元格。在Jupyter Notebook中,选择 Kernel -> Restart & Run All

验证你的Notebook。如果所有测试都通过,即可将作业标记为完成。

总结

本节课中我们一起学习了在Codio平台使用Jupyter Notebook完成作业的完整流程。我们涵盖了从启动环境、编写和运行代码,到调试常见错误以及最终验证提交的各个环节。遵循这些步骤,你将能顺利在Codio和Jupyter Notebook中完成作业。如果遇到挑战,请回顾本指南或查阅课程资料。

祝你编程愉快,好运!

39:数据类型转换 🧱

在本节课中,我们将学习如何使用Pandas库进行数据类型转换。数据框中的列有时会存储为不理想的数据类型,例如通用的“对象”类型。通过转换数据类型,我们可以让数据更适合进行数学计算或其他分析操作。

数据类型转换基础

上一节我们介绍了数据框的基本结构,本节中我们来看看如何改变其中列的数据类型。Pandas数据框可以存储多种数据类型。有时,特定列中的值类型并非我们预期或所需。

例如,观察我们创建的名为technologies的数据框,可以看到列A和列B的数据类型是通用的“对象”类型。我们可以将这些列转换为其他类型。

使用astype()函数进行转换

一种转换数据类型的方法是使用astype()函数。以下是具体操作步骤。

首先,我们将数据框中的所有值从“对象”类型转换为整数类型。

technologies = technologies.astype(int)

运行此代码后,检查列A和列B的数据类型,可以看到它们现在的数据类型是int64。如果我们需要对这些列中的值进行数学计算,这种转换会非常有用。

转换为其他数据类型

如果我们想转换为其他数据类型,例如浮点数,同样可以使用astype()函数。

technologies = technologies.astype(float)

现在,列A和列B的数据类型显示为float64

字符串类型也是可接受的转换目标。以下是将数据框中的值转换为字符串的示例。

technologies = technologies.astype(str)

转换后,列A和列B的数据类型变为string

总结

本节课中我们一起学习了Pandas中数据类型转换的核心方法。我们了解到,使用astype()函数可以轻松地将数据框中的列从一种类型(如通用的“对象”类型)转换为更具体的类型,如整数(int)、浮点数(float)或字符串(str)。这为后续的数据分析和计算奠定了正确的基础。

40:数据清洗编程演示 🧹

在本节课中,我们将学习数据清洗的核心环节:检测与处理数据框中的缺失值。我们将通过具体的Python代码示例,演示如何识别、删除或填充缺失值,以及如何替换数据框中的特定值。

检测缺失值

上一节我们提到了数据清洗的重要性,本节中我们来看看如何具体检测数据中的缺失值。在Pandas中,缺失值通常以NaN(Not a Number)或None的形式存在。

假设我们有以下包含缺失值的数据框test_df

import pandas as pd
import numpy as np

data = {
    'name': ['Alice', None, 'Charlie'],
    'age': [25, 30, np.nan]
}
test_df = pd.DataFrame(data)
print(test_df)

输出结果中,name列的第二行和age列的第三行即为缺失值。

我们可以使用.isna()方法来检测这些缺失值。该方法会返回一个布尔值数据框,其中True表示该位置是缺失值。

missing_mask = test_df.isna()
print(missing_mask)

执行上述代码后,你会看到一个布尔矩阵,清晰地标出了每个单元格是否为缺失值。

处理缺失值:删除

检测到缺失值后,常见的处理方式之一是直接删除包含缺失值的行。Pandas提供了.dropna()方法来实现这一操作。

以下是使用.dropna()方法的示例:

cleaned_df = test_df.dropna()
print(cleaned_df)

运行后,原始数据框中第二行和第三行(因为包含缺失值)会被删除,只保留完整的行。

处理缺失值:填充

有时我们并不希望直接删除数据,而是想用其他值来填充缺失的部分。这时可以使用.fillna()方法。

例如,我们可以用字符串“filled”来填充所有缺失值:

filled_df = test_df.fillna('filled')
print(filled_df)

现在,所有原本是NaNNone的位置都被替换成了“filled”。

替换特定值

除了处理缺失值,数据清洗还经常涉及替换数据框中某些特定的值。我们可以使用.replace()方法。

让我们回到之前使用过的产品数据框示例。假设我们想将第一行中产品名“chocolate sandwich cookies”替换为其他名称。

首先,查看原始数据:

# 假设df是已有的产品数据框
print(df.head())

然后,使用.replace()方法进行替换:

df2 = df.replace('chocolate sandwich cookies', 'just for a test')
print(df2.head())

执行后,你会发现目标产品名称已被成功替换。

总结

本节课中我们一起学习了数据清洗的几个关键操作。我们首先介绍了如何使用.isna()检测缺失值,然后探讨了两种处理方式:用.dropna()删除缺失行,或用.fillna()填充缺失值。最后,我们还学习了如何使用.replace()方法替换数据框中的特定值。掌握这些方法是进行有效数据分析的重要基础。

41:数据连接与筛选 🧩

在本节课中,我们将学习如何通过连接(Join)操作,将不同数据表中的信息合并起来,并在此基础上进行数据筛选。这是数据分析中整合多源数据的关键步骤。


上一节我们介绍了数据连接的基本概念,本节中我们来看看具体的连接操作是如何进行的。

我们需要在部门数据和ILs数据中查找值,并将它们与产品数据框中的数据合并。这将为我们提供每个产品的市场部门和IL信息。

我们通过在每个表中使用公共字段或标识符来连接数据集实现这一目标。这种连接表的过程类似于我们在关系型数据库中对表进行的操作。

产品数据中的部门ID将与部门数据中的部门ID连接,产品数据中的IL ID将与ILS数据中的ILI连接。

最常见的连接类型称为内连接(Inner Join)。它基于一个连接键或公共标识符组合数据框,并返回一个新的数据框,该数据框仅包含连接值在两个表中都存在的那些行。

以下是执行连接操作的核心步骤:

  • 用于执行连接的pandas函数是 merge
  • leftright 参数中指定要连接的数据框。
  • how 参数指定 inner(这是默认选项)。
  • left_onright_on 参数中指定连接键。

其基本代码公式如下:

merged_df = pd.merge(left=left_dataframe,
                     right=right_dataframe,
                     how='inner',
                     left_on='left_key_column',
                     right_on='right_key_column')

本节课中我们一起学习了数据连接的核心概念与操作方法。我们了解到,通过内连接可以基于公共字段整合来自不同数据表的信息,从而获得更完整的数据视图,这是进行深入数据分析的基础。

42:数据连接编程演示 🧩

在本节课中,我们将学习如何使用Python的pandas库来连接(Join)不同的数据集。数据连接是数据分析中的核心操作,它允许我们基于共同的列将多个表格的信息合并在一起。

概述

我们将演示如何连接四个相互关联的表格:products(产品)、aisles(通道)、departments(部门)和orders(订单)。本节重点展示productsdepartments表的连接过程。

查看数据

首先,我们快速查看products(产品)和departments(部门)这两个数据框。

products数据框包含四列,departments数据框包含两列。我们可以观察到两个数据框都包含一个名为department_id的列。我们将使用此列作为连接两个数据框的索引。

执行内连接(Inner Join)

在声明一个新的数据框后,我们将调用pandas库中的merge函数。

以下是连接操作的代码:

joined_df = pd.merge(left=products_df,
                     right=departments_df,
                     how='inner',
                     left_on='department_id',
                     right_on='department_id')

我们指定products_df为左表,departments_df为右表。我们使用内连接方式,并指定左右两表的连接键均为department_id列。运行合并后,连接操作将匹配这两列中的值。

一旦运行merge,我们显示连接后的数据框。对于每个产品,我们都能看到其对应的详细部门信息。由于我们使用了内连接,结果中只包含products数据框里那些在departments数据框中有匹配部门的记录。

执行左连接(Left Join)

现在,让我们重新运行合并操作,但将how参数改为左连接,看看会发生什么。

以下是左连接的代码:

joined_df_left = pd.merge(left=products_df,
                          right=departments_df,
                          how='left',
                          left_on='department_id',
                          right_on='department_id')

运行此代码后,可以看到结果遵循左表(products_df)的顺序,并保留了左表的所有产品记录,然后将右表(departments_df)中任何匹配的部门信息合并进来。

左连接与内连接的区别

有时,左连接和内连接会返回相同的合并信息。但假设我们遇到一种特殊情况:左表中只有两个产品。

让我们看看在这种情况下使用左连接会发生什么。为此,我们从products数据框中选取前两个产品,存储到products_df2中。

首先,演示用内连接将部门信息与这两个产品合并。

以下是针对子集的内连接代码:

joined_df_inner_subset = pd.merge(left=departments_df,
                                  right=products_df2,
                                  how='inner',
                                  left_on='department_id',
                                  right_on='department_id')

运行并显示连接后的数据框,结果中只包含左表departments数据框里那些在右表products_df2中有匹配产品信息的部门。

接下来,使用左连接将部门信息与这两个产品合并。我们复制上面的代码,但将how参数改为'left'

以下是针对子集的左连接代码:

joined_df_left_subset = pd.merge(left=departments_df,
                                 right=products_df2,
                                 how='left',
                                 left_on='department_id',
                                 right_on='department_id')

运行此代码并显示连接后的数据框。现在,我们可以看到左表departments数据框中的所有信息,以及右表products_df2中的任何信息。对于左表中那些在右表没有匹配产品的部门,我们会看到空值(null)或NaN值。这是因为我们执行了左连接,并且部门数据框在左侧,所以它保留或“保持”了该数据框中的所有行。

总结

本节课中,我们一起学习了数据连接的基本操作。我们演示了如何使用pandas的merge函数执行内连接和左连接,理解了它们之间的关键区别:内连接只返回两个表中键值匹配的行,而左连接会返回左表的所有行,无论它们在右表中是否有匹配项,无匹配的位置会用NaN填充。这是整合来自不同来源数据的重要工具。

43:数据筛选 🎯

在本节课中,我们将学习如何使用布尔索引(Boolean Indexing)来筛选数据。这是一种在数据框(DataFrame)中查找特定行的强大方法,通过创建条件或条件组合来实现。

布尔索引简介 🔍

上一节我们介绍了数据框的基本结构,本节中我们来看看如何从数据框中提取我们感兴趣的数据行。核心方法是创建一个布尔序列(True/False值序列),其中每个值对应数据框中的一行,表示该行是否满足我们设定的条件。

创建单个条件进行筛选

首先,我们学习如何创建一个条件来筛选数据。例如,我们想在一个名为 df 的数据框中,找到“产品名称”列等于“巧克力夹心饼干”的所有行。

以下是创建和应用的步骤:

  1. 创建条件:我们生成一个布尔序列,存储在变量 cookies 中。

    cookies = df['product_name'] == 'Chocolate Sandwich Cookies'
    

    执行这行代码后,cookies 变量将包含一个与 df 行数相同的序列,其中满足条件的行对应 True,否则为 False

  2. 应用条件筛选:我们将这个布尔序列放入数据框的方括号内,即可得到筛选后的结果。

    filtered_df = df[cookies]
    

    这将返回一个新的数据框 filtered_df,其中只包含“产品名称”为“巧克力夹心饼干”的行。

组合多个条件进行筛选

我们经常需要根据多个条件来筛选数据。Python使用逻辑运算符来组合条件。

以下是组合条件的方法:

  • “或”条件(OR):使用竖线符号 |。满足任意一个条件的行为 True

    # 创建两个条件
    condition1 = df['aisle_id'] == 19
    condition2 = df['department_id'] == 19
    
    # 使用“或”运算符合并条件
    combined_condition = condition1 | condition2
    
    # 应用组合条件进行筛选
    result_df = df[combined_condition]
    

    这段代码将筛选出 aisle_id 为19 department_id 为19的所有行。

  • “与”条件(AND):使用单个“与”符号 &。必须同时满足所有条件的行为 True

    # 创建两个条件
    condition1 = df['aisle_id'] == 3
    condition2 = df['department_id'] == 19
    
    # 使用“与”运算符合并条件
    combined_condition = condition1 & condition2
    
    # 应用组合条件进行筛选
    result_df = df[combined_condition]
    

    这段代码将筛选出 aisle_id 为3 并且 department_id 为19的所有行。

总结 📝

本节课中我们一起学习了数据筛选的核心技术——布尔索引。我们掌握了如何创建单个条件来定位特定数据行,以及如何使用逻辑运算符 |(或)和 &(与)来组合多个条件,实现更复杂、更精确的数据查询。这是进行数据探索和分析的基础技能。

44:计算基础 📊

在本节课中,我们将学习如何使用Python中的Pandas库对数据框(DataFrame)进行基本的数值计算。我们将重点介绍求和、求平均值、求最大值和最小值等核心函数。


使用sum函数计算总和

上一节我们介绍了数据框的基本结构,本节中我们来看看如何计算数据中数值的总和。sum函数可以用于计算数据框各列或指定列中所有值的总和。

以下是使用sum函数的两种主要方式:

  • 计算每列的总和:对整个数据框应用sum()函数,会返回一个序列(Series),其中包含每一列数值的总和。
    df.sum()
    
  • 计算指定列的总和:通过列名选择特定的列,然后对其应用sum()函数。
    df['price'].sum()
    
    这段代码专门计算price列的总和。

使用mean函数计算平均值

了解了如何求和之后,我们自然想知道数据的平均水平。mean函数用于计算数据框指定列中所有值的平均值(均值)。

其用法与sum函数类似,通常用于单列计算。

df['price'].mean()

这段代码首先创建一个包含三行三列数据的数据框,然后计算price列和rating列的平均值。


使用maxmin函数计算极值

除了集中趋势,数据的范围也很重要。maxmin函数分别用于找出数据中的最大值和最小值。

与前面的函数一样,它们可以应用于整个数据框或单个列。

以下是具体应用:

  • 计算每列的极值:对整个数据框应用max()min()函数,会返回每列的最大值或最小值。
    df.max()  # 计算每列的最大值
    df.min()  # 计算每列的最小值
    
  • 计算指定列的极值:通过列名选择列,然后计算其极值。
    df['rating'].min()
    
    这段代码计算rating列的最小值。

本节课中我们一起学习了Pandas中四个基础的数值计算函数:sum(求和)、mean(求平均)、max(求最大值)和min(求最小值)。掌握这些函数是进行数据描述性统计分析的第一步,它们能帮助我们快速了解数据的总体情况。

45:数据计算编程演示 📊

在本节课中,我们将学习如何对数据进行聚合计算,包括求和、求平均值以及寻找最大值和最小值。这些操作是数据分析的基础,能帮助我们快速理解数据的整体特征。


跨多行数据聚合

上一节我们介绍了数据的基本结构,本节中我们来看看如何对数据框中的多行数据进行聚合计算。我们将使用一个包含每笔订单所购商品信息的数据框。

我们将从订单数据框中计算重新订购的总次数。

以下是具体步骤:

  1. 查看“reordered”列中的所有值。
  2. 使用 sum 函数计算总和。
reorder_numb = orders['reordered'].sum()

然后,我们将显示 reorder_numb 的结果。这给出了超过1900万次重新订购的总数。


计算平均值

为了演示 mean 函数,我们使用一个包含产品名称、价格和评级的测试数据框。

我们将计算所有产品的平均价格。

以下是具体步骤:

  1. 从测试数据框 test_df 中,查看“price”列的所有值。
  2. 使用 mean 函数计算平均值。
avg_price = test_df['price'].mean()

然后,我们显示 avg_price。平均价格约为11.667。

现在,让我们获取平均评级。

以下是具体步骤:

  1. 从测试数据框 test_df 中,查看“rating”列的所有值。
  2. 使用 mean 函数计算平均值。
average_rate = test_df['rating'].mean()

我们显示 average_rate,结果是4.0。


寻找最大值与最小值

我们将再次使用测试数据框 test_df 来演示最大值和最小值的查找。

首先,让我们使用 max 函数。

df_max = test_df.max()

由于我们在数据框本身上调用 max,它会给出每一列的最大值。这只对“price”和“rating”列有意义。

接着,让我们为数据框调用 min 函数。

df_min = test_df.min()

这给出了每一列的最小值。同样,这只对“price”和“rating”列有意义。

现在,让我们获取特定列的最大值和最小值。

以下是获取最高价格的步骤:

  1. 查看“price”列中的所有值。
  2. 使用 max 函数获取最大值。
max_price = test_df['price'].max()

结果是20。

以下是获取最低评级的步骤:

  1. 从测试数据框中,查看“rating”列的所有值。
  2. 使用 min 函数获取最小值。
min_rating = test_df['rating'].min()

结果是3。


本节课中我们一起学习了数据的基本聚合操作:使用 sum 进行求和,使用 mean 计算平均值,以及使用 maxmin 寻找极值。掌握这些函数是进行更复杂数据分析的第一步。

46:数据更新与创建 📊

在本节课中,我们将学习如何在Pandas DataFrame中创建和插入新的数据列。这是数据预处理和特征工程中的基础操作。

概述

上一节我们介绍了DataFrame的基本结构。本节中我们来看看如何向DataFrame中添加新的数据列。

创建新列

在DataFrame中创建新列非常简单,只需为新列指定一个唯一的名称并为其赋值即可。

例如,以下代码演示了创建新列的基本方法:

df['new_column'] = some_value

以下是创建新列的具体示例:

  1. 创建单值列df['new_column'] = 1
    • 此操作会创建一个名为“new_column”的新列,该列所有行的值均为1。

  1. 创建多值列df['new_column'] = [1, 2, 3]
    • 此操作会创建一个名为“new_column”的新列,该列包含三行,值分别为1、2和3。

插入新列

除了直接赋值创建,你还可以使用insert方法将新列插入到DataFrame的指定位置。

insert方法允许你指定新列要插入的索引位置。

其基本语法为:

df.insert(loc, column, value)
  • loc: 插入位置的整数索引(0-based)。
  • column: 新列的名称。
  • value: 要插入的数据。

总结

本节课中我们一起学习了在Pandas DataFrame中创建和插入新列的两种核心方法:通过直接赋值创建,以及使用insert方法在特定位置插入。掌握这些操作是进行数据整理和构建分析模型的重要步骤。

47:数据更新与创建 🛠️

在本节课中,我们将学习如何在Pandas数据框架中更新和创建数据。具体来说,我们将掌握三种创建新列的方法:直接赋值、使用insert函数在指定位置插入列,以及基于现有列的值进行计算来创建新列。


创建新列:直接赋值法

上一节我们介绍了课程概述,本节中我们来看看第一种创建新列的方法——直接赋值。

假设我们有一个名为Temp_Products_DF的数据框架,它是从Product_DF复制而来。我们可以通过直接指定一个新列名并为其赋值来创建列。

Temp_Products_DF[‘new_column’] = 1

以上代码意味着新列new_column中的每一行都将被赋值为1。

如果显示该数据框架,可以看到新列new_column中每一行的值都是1。


创建新列:使用insert函数

在学习了直接赋值法后,我们来看看第二种方法。insert函数允许我们在数据框架的特定位置插入新列。

以下是如何使用insert函数在索引位置1(即第二列)插入一个新列的示例:

Temp_Products_DF.insert(1, ‘insert_column’, ‘good’)

在这行代码中,我们指定了列的位置(索引1)、新列的名称(‘insert_column’)以及该列每一行的值(‘good’)。

如果现在显示Temp_Products_DF,可以看到名为insert_column的新列被添加到了product_id列的右侧(因为我们使用了索引1),并且该列每一行的值都是‘good’。


创建新列:基于现有列计算

在掌握了前两种方法后,本节我们将学习如何通过组合现有列的值来创建新列。这是一种非常实用的数据操作技巧。

假设我们有一个名为Products_department_DF的数据框架,它是由Product_DFDepartments_DF合并而成的。

我们希望创建一个新列,其值是product_name列和department列值的组合,中间用逗号分隔。

以下是实现此操作的代码:

Products_department_DF[‘new_name’] = Products_department_DF[‘product_name’] + ‘, ‘ + Products_department_DF[‘department’]

如果显示该数据框架,可以看到新增的new_name列。该列中每一行的值都是对应行的产品名称和部门名称,中间以逗号连接。


课程总结

本节课中,我们一起学习了在Pandas数据框架中创建新列的三种核心方法:

  1. 直接赋值法:通过df[‘new_column’] = value快速创建具有统一值的列。
  2. insert函数法:使用df.insert(loc, column, value)在指定位置插入新列。
  3. 基于计算创建:通过对现有列进行运算(如字符串拼接)来生成新列的值。

掌握这些数据更新与创建的基本操作,是进行有效数据分析和处理的重要一步。

48:数据汇总 📊

在本节课中,我们将学习如何使用Pandas进行数据汇总,包括分组、聚合计算以及创建数据透视表。这些是数据分析中整理和理解数据的关键技术。

分组操作(Group By) 🔍

上一节我们介绍了数据的基本结构,本节中我们来看看如何对数据进行分组。groupby方法可以根据您选择的变量将数据拆分为不同的组。这个过程与SQL中的GROUP BY语句类似。

groupby方法返回一个groupby对象,该对象提供了一个字典,其键是计算出的唯一分组,对应的值是该组的数据。例如,当我们按“通道”分组时,键将是所有可能的通道名称。

我们可以使用get_group属性来获取特定组的记录。例如,查询“特色奶酪”通道中有多少产品。

然而,这类信息本身并不十分有用。我们真正需要的是能够对每个组内的数据执行聚合计算。

聚合计算与NumPy 🧮

为了进行聚合计算,我们首先需要了解NumPy。NumPy是一个流行的Python科学计算库,常用于处理数组和矩阵,并包含大量用于操作这些数组的高级数学方法。

以下是NumPy的一些基本操作:

  • 创建数组:NumPy的array方法可以创建数组。
    import numpy as np
    # 创建一维数组
    arr_1d = np.array([1, 2, 3, 4, 5])
    # 创建二维数组
    arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
    
  • 查看形状shape方法返回给定数组的形状。
    print(arr_2d.shape)  # 输出:(2, 3)
    

对分组数据应用聚合计算 ⚙️

现在,让我们结合分组和NumPy进行聚合计算。agg方法允许我们对groupby对象中的分组数据执行聚合计算。

您可以传递一个聚合函数列表作为参数。为了演示,我们首先创建一个包含五行三列数据的数据框。

以下是具体步骤:

  1. 导入NumPy。
  2. 按“名称”列对数据进行分组并调用agg方法。
  3. 将NumPy的summeanstd方法作为参数传入。
  4. 最后,显示将这些聚合计算应用于“价格”属性的结果。

示例代码如下:

import pandas as pd
import numpy as np

# 假设df是已存在的DataFrame,包含‘name’和‘price’列
grouped = df.groupby('name')['price']
result = grouped.agg([np.sum, np.mean, np.std])
print(result)

数据透视表(Pivot Table) 📈

数据透视表是一种有用的数据汇总工具,它可以根据数据框的内容创建一个新表格。

为了创建数据透视表,我们至少需要一个索引列来进行分组。这个索引类似于groupby方法中用于分组的变量。数据透视表将沿着该索引提供有用的汇总信息,例如求和或平均值。

再次,我们首先创建一个包含五行三列数据的数据框。

现在,让我们创建一个数据透视表,并使用“名称”作为索引。请注意,默认情况下,数据透视表会计算每列的平均值。

示例代码如下:

# 假设df是已存在的DataFrame
pivot_table = df.pivot_table(index='name', values='price', aggfunc=np.mean)
print(pivot_table)

总结 📝

本节课中我们一起学习了数据汇总的核心技术。我们首先使用groupby方法对数据进行分组,然后利用NumPy库和agg方法对分组后的数据执行求和、平均值和标准差等聚合计算。最后,我们介绍了如何创建数据透视表,这是一种强大的工具,可以按照指定的索引对数据进行多维度的汇总分析。掌握这些方法将帮助您更高效地从数据中提取洞察。

49:数据汇总编程演示 📊

在本节课中,我们将学习如何使用Python的Pandas和NumPy库对数据进行汇总。我们将重点介绍groupby函数、NumPy数组的基本操作、数据透视表的创建以及聚合函数agg的使用。


使用Group By汇总数据

上一节我们介绍了数据汇总的概念,本节中我们来看看如何使用groupby函数对数据进行分组和汇总。

让我们根据aisle_id对产品数据进行分组,分组键将是所有的通道ID。

# 对产品数据框按aisle_id进行分组
grouped = product_df.groupby('aisle_id')
# 获取所有分组键
keys = grouped.groups.keys()

我们可以使用groups属性来获取特定组的记录。

如果我们想回答“通道19中有多少产品?”这个问题,可以这样做:

# 获取aisle_id为19的分组,并计算其长度(产品数量)
num_products_in_aisle_19 = len(grouped.get_group(19))

结果显示,与通道ID 19相关联的产品有375个。


NumPy数组简介

在深入更多数据汇总技巧之前,我们先简要了解一下NumPy包,它是进行数值计算的基础。

首先,我们需要导入NumPy库。

import numpy as np

接下来,我们初始化一个一维NumPy数组,它类似于一个值列表。

# 创建一个一维数组
arr1 = np.array([1, 2, 3, 4, 5])

现在,让我们初始化一个二维NumPy数组,它将有两行。

# 创建一个二维数组
arr2 = np.array([[1, 2, 3],
                 [4, 5, 6]])

我们可以检查这个二维数组的形状。

# 检查数组形状:行数和列数
shape_of_arr2 = arr2.shape  # 结果为 (2, 3),表示2行3列

从概念上讲,二维数组非常像一张表格。


创建数据透视表

了解了数组的基本概念后,我们来看看如何创建数据透视表,这是另一种对数据框中的数据进行分组和汇总的方法。

假设我们有一个名为test_df的数据框,包含三列:namepricerating

我们想创建一个数据透视表,并将name设置为索引。

# 创建数据透视表,按name分组并默认计算平均值
pivot_table = test_df.pivot_table(values=['price', 'rating'], index='name')

这样,我们可以看到每个唯一名称(A、B、C)对应的平均价格和平均评分。


使用Agg函数进行聚合计算

除了数据透视表,groupby对象还可以配合agg函数,对每个分组内的数据执行更灵活的聚合计算。

你可以传递一个聚合函数列表作为参数。例如,我们想从测试数据框中找出每个name对应的价格的总和、平均值和标准差。

以下是具体步骤:

# 按name分组,并对price列应用多个聚合函数
aggregated_data = test_df.groupby('name')['price'].agg([np.sum, np.mean, np.std])

这样,我们就得到了每个name值对应的价格总和、平均值和标准差。


总结

本节课中我们一起学习了两种从数据框中汇总信息的主要方法:

  1. 数据透视表:默认计算分组平均值。
  2. Group By 与 Agg 函数:允许我们指定要应用的聚合函数(如总和、均值、标准差)。

通过掌握这些工具,你可以更有效地对数据进行分组、汇总和分析,从而提取出有意义的见解。

50:Python数据分析与可视化入门 🐍📊

在本节课中,我们将要学习Python中两个核心的数据可视化库:Matplotlib和Seaborn。我们将了解它们的基本概念、特点以及如何协同工作,以创建清晰、美观的图表来展示数据。


Matplotlib是一个流行的Python绘图库。Matplotlib被包含在P lab包中。

它是一个非常强大的工具,可以绘制多种多样的图形,甚至制作动画。

上一节我们介绍了Matplotlib的基本概念,本节中我们来看看另一个基于它的库。

Seaborn是一个基于Matplotlib的Python数据可视化库。

Seaborn也与pandas的数据结构紧密集成。

它提供了一个高级接口,用于绘制美观且信息丰富的统计图形。

以下是Seaborn的核心特点列表:

  • 基于Matplotlib构建。
  • 与pandas数据结构深度集成。
  • 提供高级统计图形绘制接口。

此外,Seaborn也可以用来增强Matplotlib绘制的图形。

以下是Seaborn的常见用途:

  • 绘制统计关系图(如散点图、线图)。
  • 可视化分类数据分布。
  • 绘制数据分布图(如直方图、核密度估计图)。
  • 美化Matplotlib的默认图表样式。


本节课中我们一起学习了Python数据可视化的两个重要工具。我们了解到,Matplotlib是一个功能强大且灵活的基础绘图库,而Seaborn则是在其基础上构建的、专注于统计图形且与pandas无缝集成的库,两者结合使用可以高效地创建出专业的可视化图表。

51:直方图可视化 📊

在本节课中,我们将学习如何使用Python的Matplotlib库创建直方图,以可视化数据集中产品的复购次数分布。直方图是一种强大的工具,用于展示连续数据的频率分布。

什么是直方图?

直方图是一种图形表示方法,它将一组数据点组织到指定的数值范围内。

直方图通常用于展示一组连续数据(例如数值数据)的潜在频率分布。

数据准备

在开始绘制图表之前,我们需要准备好用于可视化的数据。我们将通过合并产品表和订单表来获取产品的复购信息。

以下是数据准备步骤:

  1. 导入库:首先,我们需要导入必要的库。我们将使用Matplotlib进行绘图,并使用Pandas进行数据处理。

    import matplotlib.pyplot as plt
    import pandas as pd
    
  2. 合并数据:我们将产品数据框(products_df)与订单数据框(orders_df)进行合并,以关联产品信息和其复购记录。这里使用内连接(inner join),连接键是双方共有的product_id列。

    joined_df = pd.merge(products_df, orders_df, on='product_id', how='inner')
    

  1. 数据聚合:接下来,我们使用groupby函数按产品名称分组,并计算每个产品的总复购次数(即对reordered列求和)。reset_index()方法用于将分组后的索引重置为默认的整数索引。
    grouped_df = joined_df.groupby('product_name')['reordered'].sum().reset_index()
    
    执行后,我们将得到一个包含两列的数据框:product_name(产品名称)和reordered(该产品的复购总次数)。

绘制直方图

数据准备就绪后,现在我们可以开始绘制直方图了。我们将使用Matplotlib的hist函数。

以下是绘制直方图的关键参数设置:

  • 数据:我们传入grouped_df[‘reordered’],即每个产品的复购次数列表。
  • 分箱:通过bins参数设置直方图的柱子数量,这里设为10。
  • 范围:通过range参数设置X轴(复购次数)的显示范围,这里设为[0, 100]
  • 样式:我们可以设置透明度(alpha)、柱子的填充颜色(color)和边框颜色(edgecolor)来美化图表。
  • 标签与标题:为图表添加X轴标签、Y轴标签和标题,使其含义清晰。

完整的绘图代码如下:

plt.hist(grouped_df['reordered'], bins=10, range=[0, 100], alpha=0.3, color='blue', edgecolor='black')
plt.xlabel('Times Products Reordered')
plt.ylabel('Number of Products')
plt.title('Distribution of Products Reordered')
plt.show()

解读直方图

运行上述代码后,我们将看到生成的直方图。

这张直方图展示了产品复购次数的分布情况。Y轴代表不同产品的数量,X轴代表产品被复购的次数。

例如,从图中我们可以解读出:有略多于5000种不同的产品被复购了10到20次。通过观察柱子的高度,我们可以快速了解复购次数集中在哪个区间,以及分布的形态。

总结

本节课中,我们一起学习了直方图的定义与用途,并完成了从数据准备到图形绘制的完整流程。我们使用Pandas合并与聚合数据,然后利用Matplotlib的hist函数创建了一个展示产品复购分布的直方图。通过调整参数,我们可以控制图表的分箱、范围和外观,从而更有效地传达数据背后的信息。

52:散点图可视化 📊

在本节课中,我们将学习如何使用散点图进行数据可视化。散点图是一种通过点来表示两个变量之间关系的图表,特别适用于观察非线性关系或数据中的聚类现象。

什么是散点图? 🤔

散点图是一种数据可视化方法,它使用点来表示两个不同变量的取值。其中一个变量沿 X 轴绘制,另一个变量沿 Y 轴绘制。

散点图主要用于观察变量之间的关系,尤其是当它们呈非线性关系或数据中存在聚类时。

创建示例数据 📝

假设我们有一个数据框,它展示了一组学生的学习小时数与对应的考试成绩。

以下是创建该数据框的代码,我们将其命名为 hour_score_df

import pandas as pd

# 示例数据
data = {
    'hours_studied': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'exam_score': [50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
}

hour_score_df = pd.DataFrame(data)

绘制散点图 🎨

为了了解这两组数值之间的关系,我们将创建一个散点图。我们将使用 Seaborn 库的 lmplot 函数来完成这个任务。

以下是绘制散点图的完整代码:

import seaborn as sns
import matplotlib.pyplot as plt

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/upenn-py-dtanls/img/c036f1e45022d35d76e27c3fc8b7c16f_7.png)

# 使用 lmplot 绘制散点图
sns.lmplot(x='hours_studied', y='exam_score', data=hour_score_df)

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/upenn-py-dtanls/img/c036f1e45022d35d76e27c3fc8b7c16f_9.png)

# 设置坐标轴标签和标题
plt.xlabel('Hours Studied')
plt.ylabel('Exam Score')
plt.title('Study Hours vs. Exam Score')

# 显示图表
plt.show()

解读散点图 🔍

生成的散点图中,每个点代表一名学生,包含了其学习小时数和考试成绩。

例如,对于一名学生,当他学习了 5 小时,他获得了 80 分;对于另一名学生,当他学习了 5 小时,他获得了 75 分。

此外,请注意 lmplot 在散点图中放置的回归线。这条线描绘了散点图中两个变量之间的关系。在本例中,它展示了学习小时数与考试成绩之间的关系。

总结 📚

本节课我们一起学习了散点图的创建与解读。我们了解到散点图是探索两个数值变量之间关系的强大工具,能够直观地展示数据点分布、趋势以及可能存在的聚类。通过 Python 的 Seaborn 和 Matplotlib 库,我们可以轻松地创建并自定义散点图,从而为数据分析和探索性数据分析提供有力的视觉支持。

53:热力图可视化 📊

在本节课中,我们将要学习什么是热力图,以及如何使用Python的Seaborn库来创建和自定义热力图,以直观地展示数据集中数值的分布和关系。

概述

热力图是一种二维图形化数据表示方法,其中每个单独的数值都用颜色来表示。在数据分析中,热力图常用于可视化复杂的数据集,并展示变量之间的相关性或关系。

数据准备

上一节我们介绍了热力图的基本概念,本节中我们来看看如何为创建热力图准备数据。我们将使用一个包含产品名称、价格和评分的示例数据框。

首先,我们需要导入必要的库并创建示例数据。

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

# 假设我们有一个数据框
data = {
    'product_name': ['A', 'B', 'C', 'D'],
    'price': [15, 10, 20, 25],
    'rating': [4, 3, 5, 2]
}
test_df = pd.DataFrame(data)

为了便于将产品名称作为热力图的轴标签,一个简单的方法是将数据框的索引设置为“product_name”列。

test_df.set_index('product_name', inplace=True)
print(test_df)

set_index函数将数据框的索引设置为一个已存在的列,而不是默认的数字索引。inplace=True参数表示直接在原数据框上进行修改。

创建基础热力图

数据准备就绪后,现在我们可以开始绘制热力图了。我们将使用Seaborn库的heatmap函数。

以下是绘制价格相对于产品名称的热力图的步骤:

sns.heatmap(test_df[['price']], cmap='coolwarm', annot=True)
plt.show()

在这段代码中:

  • test_df[['price']] 是我们想要可视化的数据。
  • cmap='coolwarm' 参数指定了使用的颜色映射。
  • annot=True 参数确保在每个色块上显示具体的数值。

执行上述代码后,我们将得到一个热力图,它清晰地展示了每个产品名称对应的价格。例如,产品C的价格是20,产品B的价格是10。

自定义热力图外观

我们已经学会了创建基础热力图,接下来看看如何通过更改颜色映射来定制热力图的外观,以适应不同的数据或展示需求。

以下是使用不同颜色映射绘制评分热力图的代码:

sns.heatmap(test_df[['rating']], cmap='magma', annot=True)
plt.show()

这次,我们将cmap参数设置为'magma',这会生成一个具有不同颜色风格的热力图。这个热力图展示了每个产品名称对应的评分。例如,产品C的评分是5,产品B的评分是3。

通过改变cmap参数,你可以使用Seaborn和Matplotlib支持的任何颜色映射,如'viridis''plasma''summer'等,来强调数据的不同特征。

总结

本节课中我们一起学习了热力图可视化的核心技能。我们首先了解了热力图是一种用颜色表示数值的二维数据可视化工具。然后,我们逐步实践了如何使用Pandas准备数据,特别是通过set_index方法设置索引。最后,我们重点掌握了使用Seaborn库的sns.heatmap()函数创建热力图,并通过cmapannot等参数来自定义其颜色和注释,从而有效地将数据模式直观地呈现出来。

54:条形图可视化 📊

在本节课中,我们将学习条形图(Bar Plot)的基本概念,并使用 Python 的 Seaborn 库来创建条形图,以可视化不同产品的复购次数数据。

条形图是一种用矩形条表示分类数据的图表,矩形条的高度或长度与其所代表的数值成比例。条形图常用于比较不同组别之间类别的数量、频率或其他度量值。它特别适用于一次性展示多个类别的相对数量,便于直观比较。


上一节我们介绍了条形图的基本概念,本节中我们来看看如何准备数据并创建条形图。

首先,我们需要准备数据。假设我们已经有一个名为 group_df 的数据框,其中存储了每个产品名称对应的复购次数记录。我们的目标是筛选出三种特定产品的数据:巧克力夹心饼干、有机未精炼芝麻油和二号咖啡滤纸。

以下是数据准备的步骤:

  1. 为每种产品创建一个筛选条件。
  2. 使用这些条件从 group_df 中过滤出对应的行。
  3. 将过滤后的结果存储在一个新的数据框(例如 final_df)中。

完成上述步骤后,final_df 将只包含这三种产品及其对应的复购次数。


数据准备完成后,现在我们可以开始绘制条形图。我们将使用 Seaborn 库中的 barplot 函数。

在绘图之前,通常需要设置图表的大小以获得更好的显示效果。我们可以使用 Matplotlib 的 figure 函数来设置图形尺寸。

以下是创建条形图的具体步骤:

  1. 设置图形尺寸为 10(宽)x 5(高)。
  2. 调用 sns.barplot() 函数。
  3. 指定数据源为 final_df
  4. product_name 设置为 X 轴。
  5. 将复购次数的 counts 设置为 Y 轴。
  6. 最后,调用 plt.show() 来显示图表。

运行代码后,我们将看到一个条形图。图中每个条形代表一个特定产品,条形的高度直观地显示了该产品的复购次数。例如,从图中可以清晰地看出,巧克力夹心饼干的复购次数超过了一千次。


本节课中我们一起学习了条形图的作用以及如何使用 Seaborn 库创建条形图。我们首先准备了需要可视化的特定产品数据,然后通过设置图形参数和调用绘图函数,生成了一个清晰展示产品复购次数对比的条形图。条形图是数据探索和结果展示中非常有效的工具。

posted @ 2026-03-26 12:23  布客飞龙III  阅读(43)  评论(0)    收藏  举报