3.1 项目背景
2020年7月9日,世界气象组织发布《未来五年全球气温预测评估》.数据显示2020—2024年,预计全球气温每年都有可能比工业化前的平均气温(1850—1900年期间气温年平均值)升高至少1℃,北极的升温幅度可能是全球平均水平的两倍以上。据美国陆军工程兵团估计,美国阿拉斯加州沿海小镇基瓦利纳将逐渐被海水淹没,并将于2025年被海水彻底淹没。全球变暖正给人类社会和经济生活带来日益显著的影响。
作为一名数据分析师,你的第一个任务是获取与全球气温有关的数据,对其进行处理、初步分析和简单可视化,并回答以下问题。
(1)近年来全球气温的变化趋势是什么?
(2)是否存在全球气温升高的情况?
(3)不同地区的升温幅度是否有差异?
(4)能否用通俗易懂的方式向公众展示你的工作成果?
3.2 技能图谱

3.2.1 Pandas概述
NumPy
是什么:NumPy 是一个用于科学计算的 Python 库,它提供了支持多维数组和矩阵运算的功能,还包含大量的数学函数。
作用:主要用于快速处理大量的数字数据,特别是涉及到向量和矩阵运算时。
特点:
高效的多维数组对象:提供强大的 N 维数组(ndarray),支持大量的数组运算。
丰富的数学函数库:可以进行如加减乘除、线性代数、统计分析等各种复杂计算。
内存紧凑:与 Python 自带的列表相比,NumPy 数组占用更少的内存,运行更快。
Pandas
是什么:Pandas 是一个数据分析和数据处理的 Python 库,专为处理表格数据而设计,类似于 Excel 中的电子表格。
作用:用于对数据进行清理、变换、分析和可视化,是数据科学和机器学习工作流程中的核心工具之一。
特点:
强大的数据结构:包括
DataFrame(二维表格)和Series(一维序列),便于数据操作。灵活的数据操作:可以方便地对数据进行切片、过滤、聚合、合并等操作。
数据清洗功能:提供了处理缺失数据和重复数据的方法。
与其他库的集成:能够与
NumPy、Matplotlib等库无缝集成,实现更复杂的分析和可视化。
总结:
NumPy 负责数值计算,
Pandas 负责数据的管理和分析。
3.2.2 Pandas数据结构
DataFrame 和 Series 总结
Pandas 数据结构:DataFrame(二维带标签表格),Series(一维带标签数据结构)

Pandas DataFrame 结构图解释
总体结构:
DataFrame:一个二维的数据结构,其中每一列可以包含不同类型的数据(数值、字符串、布尔等)。它类似于一个电子表格或 SQL 表格,非常适用于处理各种数据类型。
轴标签(Axis Labels):
位置:图中顶部的橙色区域。
作用:用于标识每一列的名称,这些名称在数据操作中用作列的引用。
位置:图中左侧的蓝色条形区域。
作用:用于标识每一行的唯一索引。默认情况下是从 0 开始的整数序列,但也可以设置为其他值,如时间序列或唯一标识符。
索引(Index):
列名(Columns):
数据区域:
位置:图中的浅灰色网格区域。
作用:存储实际的数据值,每个数据值都通过其行索引和列名称进行定位和访问。
数据选择:
解释:当从
DataFrame中选择单列数据时,结果是一个Series对象。Series是一维带标签的数据结构,它类似于数组,可以存储任意数据类型,且保留了来自DataFrame的行索引。每个Series对象不仅具有单一的数据类型,还可以由用户指定或自动生成索引。作用:允许对单列数据进行操作和分析,而不影响原始 DataFrame。
Series:
轴方向(Axis Direction):
轴0:指的是行方向,通常用于跨行的操作,如计算总和、平均值等。
轴1:指的是列方向,通常用于跨列的操作,如添加或删除列等。
应用示例
索引和选择数据:
import pandas as pd
# 创建 DataFrame 示例
# 创建一个包含姓名、年龄和城市信息的字典
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 22],
'城市': ['北京', '上海', '广州']
}
# 使用字典创建一个 Pandas DataFrame
df = pd.DataFrame(data)
# 选择单列,得到一个 Series
series = df['姓名']
# 输出 DataFrame 和 Series
print("输出 DataFrame:")
print(df)
print("输出 Series:")
print(series)

总结对比
结构:
DataFrame 是一个二维的、带有标签的表格数据结构,类似于 Excel 表格,包含行和列索引,每列可以包含不同的数据类型。
Series 是一种一维的、带标签的数据结构,类似于数组或列表,只有一个索引轴,每个数据项都有一个与之对应的标签(索引)。
数据类型:
DataFrame 中的每一列必须包含相同类型的数据(例如,整型、浮点型或字符串等),但是不同的列之间可以有不同的数据类型。。
Series 中通常所有数据类型相同。
应用:
DataFrame 适用于处理复杂的表格数据。
Series 适用于处理简单的一维数据。
通过理解 DataFrame 和 Series 的特点和应用场景,可以更好地选择合适的数据结构进行数据处理和分析,从而提高数据分析的效率和效果。
一、DataFrame 与 Series 的联系
组成关系:
DataFrame 是由多个 Series 组成的。每一列可以看作是一个 Series。
Series 是 DataFrame 的基本组成单元。一个 DataFrame 可以看作是由多个具有相同索引的 Series 组成的二维数据结构。
数据结构:
Series 是一维的,包含数据和一个索引。
DataFrame 是二维的,包含行和列,每列是一个 Series,并且所有列共享同一个索引。
操作:
对 DataFrame 的列进行操作时,可以单独将一列作为一个 Series 进行操作。
可以将多个 Series 合并成一个 DataFrame。

3.3 数据获取
本书用到的数据均从 Kaggle 和和鲸社区免费下载。
【数据下载:】https://wwtf.lanzoul.com/iY8VB2b6170d
本教程涉及的数据及其结构的描述:
文件名称:
city_temperature.csv数据覆盖期间:1995年至2020年
记录总数:2,906,327 条
数据列说明
Region(洲):地理区域划分,如亚洲、欧洲等。
Country(国家):国家名称,如中国、美国等。
State(地区):国家内部的州或省份,适用于部分国家。
City(城市):具体的城市名称。
Month(月):记录数据的月份。
Day(日):记录数据的日期。
Year(年):记录数据的年份。
AvgTemperature(日均气温):当天的平均气温,单位为华氏度(°F)。转换为摄氏度的公式为:
摄氏度 = (华氏度 - 32) / 1.8
数据特点
数据单位:气温数据使用华氏度表示,这与中国常用的摄氏度不同。
数据完整性:文件中存在一些字段值缺失的情况,需要在数据预处理阶段进行处理。
数据应用场景
气候分析:可以用于分析不同城市和地区的气候变化模式。
环境研究:有助于研究全球变暖对各地区气温的影响。
教育用途:可作为教学数据,帮助学生了解数据分析的基本方法和技巧。
数据处理建议
缺失值处理:检查和处理缺失数据,如填补或删除缺失记录。
数据类型转换:将气温从华氏度转换为摄氏度,以符合国内的常规使用习惯。
时间序列分析:利用年、月、日字段创建时间序列,进行时间序列相关的分析。
| 洲 | 国家 | 州或省份 | 城市 | 月 | 日 | 年 | 日均气温 |
|---|---|---|---|---|---|---|---|
| Region | Country | State | City | Month | Day | Year | AvgTemperature (°F) |
| Africa | Algeria | Algiers | 1 | 1 | 1995 | 64.2 | |
| Africa | Algeria | Algiers | 1 | 2 | 1995 | 49.4 | |
| Africa | Algeria | Algiers | 1 | 3 | 1995 | 48.8 | |
| Africa | Algeria | Algiers | 1 | 4 | 1995 | 46.4 | |
| Africa | Algeria | Algiers | 1 | 5 | 1995 | 47.9 |
3.4 数据读入
【例 3-1】读取“city_temperature.csv”的数据
# 导入NumPy库,该库用于支持大型的、 多维数组和矩阵,以及对这些数组进行各种数学运算
import numpy as np
# 导入Pandas库,这是一个用于数据操作和分析的库,提供了数据结构和操作工具
import pandas as pd
# 导入Matplotlib库中的pyplot模块,用于绘制各种静态、动态和交互式的图形
import matplotlib.pyplot as plt
# 使用 pd.read_csv 函数读取CSV文件,并将文件加载到一个DataFrame中。【数据存放在当前路径目录下】
data = pd.read_csv('./city_temperature.csv')出现警告:
DtypeWarning: Columns (3) have mixed types. # 指定了CSV文件中的第3列即State列具有混合类型。
Specify dtype option on import or set low_memory=False. #在导入时指定数据类型选项或设置low_memory=False以避免这种警告。报错的原因:
是的,默认情况下,Pandas 在读取大型 CSV 文件时会进行分块读取。这是为了节省内存空间并提高读取速度。以下是详细解释:
分块读取的原理
当 pd.read_csv 函数读取大型 CSV 文件时,Pandas 会默认启用 low_memory 参数,其值为 True。这意味着它会将文件分成多个小块逐步读取,而不是一次性将整个文件读入内存。这样做的目的是为了减少内存消耗,特别是在处理非常大的数据集时。
为什么会产生混合类型警告
在分块读取时,Pandas 会尝试猜测每个小块的数据类型。如果一个列在不同的小块中包含不同的数据类型(例如某些小块中是数字,其他小块中是字符串),Pandas 会发出 DtypeWarning 警告,提示该列包含混合类型。
综上所述,数据表中的第3列("State"列)中存在两种类型的数据:缺失值(NaN,浮点数类型)和表示州名的字符串(例如 "Alabama")。这表明在数据集中,某些记录的州名信息缺失,导致数据类型混合。
使用命令 data['State'].unique() 可以查看'State'列所有的唯一值
使用命令data[data['State'].isna()]可以查看'State'列所有的nan的行
解决方法一
# 添加 dtype={'State': object} 参数指定了 State 列的数据类型为 object,即字符串类型【混合类型】。
data = pd.read_csv('./city_temperature.csv', dtype={'State':object})object: 在Pandas中,object类型通常用于表示字符串,或也可以用于存储任意类型的 Python 对象,包括数字、列表、甚至混合类型的数据。
解决方法二
# 设置low_memory=False,Pandas会一次性读取整个文件,而不是分块读取,这样可以避免这种警告。
data = pd.read_csv('./city_temperature.csv', low_memory=False)【例 3-2】读入city_temperature.csv文件时指定State列的数据类型
# 添加 dtype={'State': object} 参数指定了 State 列的数据类型为 object,即字符串类型【混合类型】。
data = pd.read_csv('./city_temperature.csv', dtype={'State':object})3.5 数据检查
【知识点】
以下是对Pandas DataFrame data 结构和属性的精练总结:
数据规模:
data.shape提供了 DataFrame 的总行数和列数。行数检查:
data.shape[0]返回 DataFrame 的总行数。列数检查:
data.shape[1]返回 DataFrame 的列数。列标签:
data.columns列出所有列名称。数据类型:
data.dtypes显示每列的数据类型,区分字符串和数值类型。
【例 3-3】查看data变量存储的数据集规模
# 获取 data DataFrame 的维度,即行数和列数。
data.shape
# 运行结果:
# (2906327, 8)【例 3-4-1】查看data的行数
# 使用 shape 属性的第一个元素(索引 0)来获取 DataFrame 的行数。
data.shape[0]
# 运行结果:
# 2906327【例 3-4-2】查看data的列数
# 使用 shape 属性的第二个元素(索引 1)来获取 DataFrame 的列数。
data.shape[1]
# 运行结果:
# 8【例 3-5】查看data的列标签
# 获取 DataFrame 的所有列名称。
data.columns
#运行结果:
Index(['City', 'Region', 'Country', 'State', 'Month', 'Day', 'Year',
'AvgTemperature'],
dtype='object')【例 3-6】查看data各列数据类型
# 列出 DataFrame 中每列的数据类型。
data.dtypes
#运行结果:
City object
Region object
Country object
State object
Month int64
Day int64
Year int64
AvgTemperature float64
dtype: object3.6 数据内容访问
3.6.1 采用[]方式
【知识点】
[] 操作符主要用于列选择,或进行切片指定行范围,返回的是DataFrame,
[] 操作符不能同时选择行和列
1. 单列选择:data['ColumnName']
2. 多列选择:data[['ColumnName1', 'ColumnName2']]
3. 行范围选择:data[start_index:end_index] 注意:行索引默认从0开始,左闭右开
4. 条件过滤(单条件):data[data['ColumnName'] == value]
5. 条件过滤(多条件):data[(data['ColumnName1'] == value1) & (data['ColumnName2'] == value2)]【例 3-7】显示所有的Country列
data['Country']
# 运行结果
0 Algeria
1 Algeria
2 Algeria
3 Algeria
4 Algeria
...
2906322 US
2906323 US
2906324 US
2906325 US
2906326 US
Name: Country, Length: 2906327, dtype: object【例 3-8】显示所有的Country列和City列
data[['City', 'Country']]

【例 3-9】显示第223条记录(即索引为222的行)
data[222:223]
# 解释
# data[222:223] 返回一个DataFrame,包含第223条记录(索引为222的行)。
# 由于Pandas的切片是左闭右开的,所以 data[222:223] 只包含起始索引222的那一行,而不包含结束索引223。
【例 3-10】显示行索引为100-150的记录
data[100:151]

【例 3-11】显示所有的Region为Asia的记录
data[data['Region']=='Asia']
条件生成:比较
data['Region']与'Asia',生成布尔序列。数据过滤:用布尔序列筛选
'Region'为'Asia'的行。结果返回:返回新 DataFrame,仅含
'Asia'行。

【例 3-12】查询所有的Country为China,并且City为Guangzhou的记录
data[(data['Country']=='China') & (data['City']=='Guangzhou')]
条件设置:设置
'Country'等于'China'且'City'等于'Guangzhou'的条件。逻辑组合:使用
&操作符组合两个条件。结果过滤:返回满足这两条件的行组成的新 DataFrame。

3.6.2 采用.iloc或.loc方式
【知识点】


loc 和 iloc 是 Pandas 中用于数据选择和操作的两种主要方法。它们的用法各有特点,具体如下:
loc 语法:loc 是基于标签(label)的选择方法,允许通过行和列的标签来选择数据。
用法
data.loc[row_labels, column_labels]
行选择:通过
标签选择行,通常使用行索引标签,可以是单个标签、标签列表、标签范围,或者布尔索引。列选择:通过
列名选择列。支持布尔索引:可用于基于条件的过滤。
示例
# 选择单行
data.loc[0] # 选择索引标签为 0 的行
# 选择多行
data.loc[0:5] # 选择索引标签从 0 到 5 的行(包含 5)
# 选择单列
data.loc[:, 'City'] # 选择名为 'City'的列
# 选择多列
data.loc[:,['City','AvgTemperature']] # 选择'City','AvgTemperature'两列
# 条件选择
data.loc[data['AvgTemperature'] > 100] # 选择满足条件的行iloc 语法
iloc 是基于整数位置(index)的数据选择方法。
iloc 的整数位置指的是行或列在 DataFrame 中的位置索引
位置索引(整数位置):是指行或列在 DataFrame 中的实际物理位置,从 0 开始递增的整数。这个是
iloc用来定位行或列的依据。
用法
data.iloc[row_positions, column_positions]
行选择:通过整数位置选择行。
列选择:通过整数位置选择列。
示例
# 选择单行
data.iloc[0] # 选择位置为 0 的行
# 选择多行
data.iloc[0:5] # 选择位置从 0 到 4 的行(不包含 5)
# 选择单列
data.iloc[:, 0] # 选择位置为 0 的列
# 选择多列
data.iloc[:, [0, 1]] # 选择位置为 0 和 1 的两列
# 选择特定行和列
data.iloc[0:5, 0:2] # 选择前 5 行和前 2 列loc和iloc的区别

loc和iloc总结
loc
基于标签(Label-based): 使用行标签和列标签进行访问。
适用于行标签和列标签: 可以使用行标签(行名)和列标签(列名)来选择数据。
包含结束点: 切片选择时包含结束点,遵循
左闭右闭的原则。
iloc
基于位置(Integer-location based): 使用行索引和列索引进行访问。
适用于整数位置索引: 可以使用整数索引来选择数据,索引从0开始。
不包含结束点: 切片选择时不包含结束点,遵循
左闭右开的原则。
主要区别
索引类型:
loc使用标签索引,iloc使用整数位置索引。结束点:
loc的切片选择包含结束点,iloc的切片选择不包含结束点。适用范围:
loc适用于标签索引,适合处理带有自定义行标签的DataFrame;iloc适用于整数位置索引,适合处理需要按位置选择数据的场景。
注意:
如果在创建 DataFrame 时没有指定索引(index),Pandas 会自动使用整数索引(从 0 开始)作为行标签。在这种情况下,行标签和整数位置是相同的,因此可以使用 loc 或 iloc 进行索引,两者的效果相同。
【例 3-13】显示所有的Country值(与【例3-7】比较)
data.loc[:,'Country']
data.iloc[:,2]
data.loc['Country'] # 错误代码,可以更改为data['Country']
data.loc[:,1] # 错误代码[原因:loc使用的列标签]【例 3-14】显示第222条的记录(与【例3-9】比较)
切片操作
data.iloc[221:222]

按位置(整数索引)
data.iloc[221]

在 Pandas 中,data.iloc[221:222] 和 data.iloc[221] 区别:
data.iloc[221:222]:这是一个切片操作,选择从索引 221 到 221(不包括 222)的行。
结果是一个
DataFrame,即使只包含一行数据。data.iloc[221]:这是一个单点索引操作,直接选择索引为 221 的行。
结果是一个
Series对象,代表了该行的数据。
总结来说,前者返回一个包含指定行的 DataFrame,而后者返回一个具体行数据的 Series。
【例 3-15】显示第222条记录(与【例3-14】比较)
基于标签进行选择。如果数据框(帧)的标签是默认的整数索引,这两种方法的效果是相同的
data.loc[221]

data.loc[221:222]

在 Pandas 中,data.loc[221] 和 data.loc[221:222] 有如下区别:
data.loc[221]:这是一个单点索引操作,直接选择索引值为 221 的行。
结果是一个 Series 对象,包含该行的所有列数据。
data.loc[221:222]:这是一个切片操作,选择从索引 221 到 222(包括 222)的行。
结果是一个 DataFrame 对象,即使只包含一行数据。
【例 3-16】显示索引为100到150的记录中的Country、City、AvgTemperature列
data.iloc[100:150,[0,2,7]]

等同于.loc
data.loc[100:150,['City','Country','AvgTemperature']]

【例 3-17】显示索引为100、110、190、200记录中的City和Region
data.iloc[[100,110,190,200],[0,1]]
# 等同于
data.iloc[[100,110,190,200]]['City','Region']等同于
data.loc[[100,110,190,200],["City","Region"]]

【例 3-18】显示索引为100、110、190、200的记录中除第1列之外的所有列
data.iloc[[100,110,190,200],1:]
# 1::从第 2 列开始选择,直到最后一列。【例 3-19】显示所有的Region为Asia的记录(与【例3-11】比较)
data.loc[data['Region']=='Asia']
# 等同于
data[data['Region']=='Asia']解释:
条件生成:data['Region'] == 'Asia' 生成一个布尔序列,其中 True 表示 Region 列值为 'Asia'。
数据过滤:使用布尔序列作为索引,data.loc[...] 选择所有布尔序列中为 True 的行。
结果返回:返回一个新的 DataFrame,只包含 Region 列值为 'Asia' 的行。
3.6.3 采用表达式方式
【知识点】
data.query() 是 Pandas 中的一种方法,用于对 DataFrame 进行查询和过滤。
data.query('条件表达式')
条件表达式:一个字符串,完整的布尔条件表达式,表示查询条件。字符串条件需要用双引号(")括起来,例如 Country == "China"。
注意
简洁性:使用字符串表达式进行查询,语法简单,代码更具可读性。
直接使用列名:在表达式中直接使用列名,不需要加引号或使用方括号。
逻辑运算符:支持使用
and、or、not等逻辑运算符,或者使用&、|和~。字符串处理:字符串值需要用双引号(
")括起来。带空格的列名:对于带有空格或特殊字符的列名,使用反引号(
``)括起来。**动态变量**:可以通过@` 符号在表达式中引用 Python 变量。
【例 3-20】显示2020年所有的记录。
data.query('Year == 2020')
等同于:
data.loc[data['Year']==2020]
data[data['Year']==2020]
data.loc[data.iloc[:,6]==2020]
【例 3-21】查询所有的Country为China,并且City为Guangzhou的记录
data.query('Country=="China" and City=="Guangzhou" ')
# 等同于
data.loc[(data['Country']=='China') & (data['City']=='Guangzhou')]
data[(data['Country']=='China') & (data['City']=='Guangzhou')]
【例 3-22】查询1995年1月1日中国广州市的记录
data.query('Country=="China" and City=="Guangzhou" and Month==1 and Day==1 and Year==1995 ')
# 等同于
data.loc[
(data['Country'] == "China") &
(data['City'] == "Guangzhou") &
(data['Month'] == 1) &
(data['Day'] == 1) &
(data['Year'] == 1995)
]
# 或者
data[
(data['Country'] == "China") &
(data['City'] == "Guangzhou") &
(data['Month'] == 1) &
(data['Day'] == 1) &
(data['Year'] == 1995)
]
【例 3-23】查询 New York City 所有日均气温低于10度的记录
data.query(' City=="New York City" and AvgTemperature <10 ')
# 等同于
data.loc[
(data['City'] == "New York City") &
(data['AvgTemperature'] < 10)
]
# 或者
data[
(data['City'] == "New York City") &
(data['AvgTemperature'] < 10)
]
【例 3-24】查询 2020年Paris 和 London 的所有气温记录
data.query(' Year==2020 and (City=="Paris" or City=="London") ')
# 等同于,【& 表示“且”条件,| 表示“或”条件。】
data.loc[
(data['Year'] == 2020) &
((data['City'] == "Paris") | (data['City'] == "London"))
]
# 或者
data[
(data['Year'] == 2020) &
((data['City'] == "Paris") | (data['City'] == "London"))
]
# 只显示满足条件的'AvgTemperature'列的内容
data.query(' Year==2020 and (City=="Paris" or City=="London") ')['AvgTemperature']3.6.4 数据可视化
【例 3-25】显示中国广州市 1995年到2020年的年均气温变化【数据可视化】。
.plot() 是 Pandas 库中用于数据可视化的一个方法,它基于 Matplotlib 库,提供了快速绘制图表的功能。通过调用 .plot(),可以将 DataFrame 或 Series 中的数据以各种图表形式呈现出来。
.plot() 基本功能
默认行为:对数值型数据进行可视化,默认情况下,
.plot()会绘制折线图。调用对象:可以在 DataFrame 或 Series 上调用。
常用参数
kind:指定图表类型,如'line'(折线图)、'bar'(柱状图)、'barh'(水平柱状图)、'hist'(直方图)、'box'(箱形图)、'pie'(饼图)、'scatter'(散点图)等。x和y:用于 DataFrame,指定 x 和 y 轴的数据列。title:设置图表的标题。xlabel和ylabel:设置 x 和 y 轴的标签。figsize:设置图表的大小,使用元组指定如(width, height)。color:指定线条或条形的颜色。
折线图
# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
data = pd.read_csv('./city_temperature.csv', dtype={'State':object})
# 筛选广州的数据
guangzhou_data = data.query('Country == "China" and City == "Guangzhou"')
# 计算每年的平均气温
# 按照年份对数据进行分组,并计算每年 "AvgTemperature" 列的平均值,结果赋值给 annual_avg_temp
annual_avg_temp = guangzhou_data.groupby('Year')['AvgTemperature'].mean()
print(annual_avg_temp)
# 绘制折线图
annual_avg_temp.plot(kind='line',
title='Average Temperature in Guangzhou',
xlabel='Year',
ylabel='Temperature (°F)')
# 显示图形
plt.show()

柱型图
# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
data = pd.read_csv('./city_temperature.csv', dtype={'State':object})
# 筛选广州的数据
guangzhou_data = data.query('Country == "China" and City == "Guangzhou"')
# 计算每年的平均气温
annual_avg_temp = guangzhou_data.groupby('Year')['AvgTemperature'].mean()
print(annual_avg_temp)
# 绘制柱形图
annual_avg_temp.plot(kind='bar',
title='Average Temperature in Guangzhou',
xlabel='Year',
ylabel='Temperature (°F)'
)
# 设置 y 轴的显示范围从 67 到 75
plt.ylim(67, 75)
# 显示图形
plt.show()

直方图
显示广州每年的平均气温分布情况
# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
data = pd.read_csv('data/city_temperature.csv', dtype={'State':object})
# 筛选广州的数据
guangzhou_data = data.query('Country == "China" and City == "Guangzhou"')
# 计算每年的平均气温
annual_avg_temp = guangzhou_data.groupby('Year')['AvgTemperature'].mean()
# 绘制条形图
annual_avg_temp.plot(kind='hist',
title='Average Temperature in Guangzhou',
xlabel='Temperature (°F)',
ylabel='Number of Years'
)
# 显示图形
plt.show()
温度集中范围:大多数年份的平均气温集中在 72°F 到 74°F 之间,表明广州的年平均气温相对稳定,主要分布在这个范围。
温度分布趋势:在 68°F 到 70°F 区间和 71°F 到 72°F 区间分别有少数年份,显示了一些波动,但整体趋势还是集中在较高的平均气温范围。
偏态:该直方图表现出一种右偏分布(较低温度的年份较少),意味着广州整体上具有较温暖的气候,极少数年份可能会出现较低的平均温度。
实验
【练习3.1】读取“city_temperature.csv”的数据
# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
# 使用 pd.read_csv 函数读取CSV文件,并将文件加载到一个DataFrame中。
data = pd.read_csv('data/city_temperature.csv', dtype={'State':object})【练习3.2】查看“city_temperature.csv”的行数和列数。
data.shape
【练习3.3】查看“city_temperature.csv”的行数
data.shape[0]
【练习3.4】查看“city_temperature.csv”的列数
data.shape[1]
【练习3.5】查看 DataFrame 的列标签(列名)。
# 包括索引数据类型、列数据类型、非空值数量等信息
data.columns【练习3.6】打印有关DataFrame的简要信息
# 包括索引数据类型、列数据类型、非空值数量等信息
data.info()
【练习3.7】 查看DataFrame中每列的数据类型。
data.dtypes
【练习3.7】使用pd.concat方法合并Series
import pandas as pd
# 创建两个Series
s4 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
s5 = pd.Series([4, 5, 6], index=['a', 'b', 'c'])
# 使用pd.concat合并它们
result = pd.concat([s4, s5], axis=1, sort=False)
print(result)
# 运行结果
0 1
a 1 4
b 2 5
c 3 6【练习3-8】 显示City列的值。
data['City']
【练习3-9】 显示City和Temperature列的值。
data[['City', 'Temperature']]
【练习3-10】 显示除了AvgTemperature之外的列的内容
data.columns[:-1]
# 运行结果:
Index(['City', 'Region', 'Country', 'State', 'Month', 'Day', 'Year'], dtype='object')
# 使用切片操作 [:-1],选择所有列名,除了最后一个列名。
# :-1 表示从起始位置(第一个列名)到倒数第二个列名(不包含最后一个列名)。
data[data.columns[:-1]]
【练习3-11】 显示2001年1月1日的所有中国城市的行数据。
# 从 DataFrame data 中筛选出所有符合条件的行
data.query('Country=="China" and Year==2001 and Month==1 and Day==1')
【练习3-12】 显示2001年1月1日的所有中国城市的行数据,只显示City和AvgTemperature列。
data.query('Country=="China" and Year==2001 and Month==1 and Day==1')[['City','AvgTemperature']]

【练习3-13】 显示所有AvgTemperature大于95的中国城市数据。
data.query('Country=="China" and AvgTemperature>95')

【练习3-14】 显示索引为第0,50,100,150行数据中的Month、Day、Year列。
data.columns
# 运行结果
Index(['City', 'Region', 'Country', 'State', 'Month', 'Day', 'Year', 'AvgTemperature']
data.iloc[[0,50,100,150],4:7]
第二种方法
data.iloc[0:151:50, 4:7]
iloc 方法
iloc 是 Pandas 中用于基于整数位置(即索引)来选择数据的方法。它允许你按照行和列的位置索引进行数据选择。
语法和参数
data.iloc[行选择, 列选择]
行选择:指定要选择的行的索引范围。列选择:指定要选择的列的索引范围。
示例代码
data.iloc[0:151:50, 4:7]
详细解释
行选择
0:151:50:0:151:表示行索引范围从 0 到 150(不包括 151)。50:表示步长为 50,即每隔 50 行选取一行。综合起来,
0:151:50表示从索引 0 开始,每隔 50 行选取一行,直到索引 150。列选择
4:7:4:7:表示列索引范围从 4 到 6(不包括 7)。即选择索引为 4、5、6 的列。
总结
data.iloc[0:151:50, 4:7] 的作用是从 DataFrame 中选择:
行索引范围从 0 到 150,每隔 50 行选取一行,具体行索引为 0、50、100、150。
列索引范围从 4 到 6,具体列索引为 4、5、6。
最终,返回一个新的 DataFrame,包含指定的行和列。
【练习3-15】 显示第0,50,100,150,…,第2906300行的数据
data.iloc[::50]
# ::50 表示从起始位置到结束位置,每隔 50 行选取一行。
'''
sequence[::step]:
start 省略,表示从序列的开始位置。
stop 省略,表示到序列的末尾。
step 表示步长,即每隔多少个元素选择一个。
'''
【练习3-16】 显示所有偶数行
data.iloc[::2]
【练习3-17】 显示所有奇数行,并且倒序显示。
data.iloc[-2::-2]
'''
解释
start=-2: -2 表示从倒数第二行开始,到结束。
stop 省略: 省略 stop 表示一直切片到 DataFrame 的开头。
step=-2: -2 表示以步长为 2 进行反向切片,即每隔 2 行向上选择一行。
'''
【练习3-18】 显示第0行到倒数第10行之间的数据(不包括倒数第10行)。
data[:-10]

【练习3-19】 显示第0行到倒数第10行之间的数据(使用head()实现)。
data.head(-10)
'''
解释
当 n 是正数时,例如 data.head(10),返回 DataFrame 的前 10 行。
当 n 是负数时,例如 data.head(-10),会返回除最后 10 行之外的所有行。
这是因为负数的 n 会被解释为排除最后 n 行之后剩余的部分。
'''【练习3-20】 显示第10行到最后一行的数据(使用tail()实现)。
data.tail(-10)
'''
tail 方法用于返回 DataFrame 的最后 n 行。
传入负数参数时,它会返回从指定负数位置到最后一行的数据。
'''在 Pandas 中,使用 data.tail(n) 函数可以获取 DataFrame 或 Series 的最后 n 行。如果 n 是正数,它返回最后 n 行;如果是负数,则返回除了前 |n|(n 的绝对值)行之外的所有行。
解释 data.tail(-10)
当你使用 data.tail(-10),这意味着你想获取除了 DataFrame 开头的 10 行之外的所有行。换句话说,这个命令会排除前 10 行,并返回从第 11 行开始到 DataFrame 结尾的所有行。
【练习3-21】 显示第10行到最后一行之间的数据,并且倒叙显示。
data.tail(-10)[::-1]
data.tail(-10):通常,
data.tail(n)返回 DataFrame 或 Series 的最后n行。例如,data.tail(10)返回最后 10 行。如果
n是负数,Pandas 会返回去掉前abs(n)行后的所有行。比如data.tail(-10)会去掉前 10 行,返回剩下的所有行。[::-1]:这是 Python 切片操作的一部分。
[::-1]表示反转序列。对于 DataFrame 或 Series,这意味着行顺序会被颠倒。
综合起来,data.tail(-10)[::-1] 的作用是:
首先,去掉 DataFrame 或 Series 的前 10 行。
然后,将剩余的行顺序反转。

【练习3-22】 显示所有行,除了第1,11,111,1111行(使用布尔型列表)。
# 创建一个长度等于 data 行数的布尔列表,所有元素都为 True。
cond = [True] * data.shape[0]
# 可使用print(cond[:10])查看前10行# 将布尔列表 cond 中索引为 1、11、111 和 1111 的元素设置为 False。
cond[1] = False
cond[11] = False
cond[111] = False
cond[1111] = False# 使用布尔索引来选择 DataFrame 中的行。
data[cond]解释:
创建一个与 DataFrame
data行数相同的布尔列表,初始时所有元素为True。将该布尔列表中索引为 1、11、111 和 1111 的元素设置为
False。使用这个布尔列表作为条件,筛选出 DataFrame
data中对应位置为True的行,生成一个新的 DataFrame。
这样,新的 DataFrame data[cond] 将包含原始 DataFrame 中除去索引为 1、11、111 和 1111 的行之外的所有行。
【练习3-23】 只显示第1,11,111,111,…,1111111行(使用列表参数)。
data.iloc[[1,11,111,1111,11111,111111,1111111]]

【练习3-24】 显示2019年Japan的所有记录。
data.query('Year==2019 and Country=="Japan"')

【练习3-25】 显示2019年7月Tokyo市气温大于80°F的记录。
data.query('Year==2019 and Month==7 and City=="Tokyo" and AvgTemperature>80')

【练习3-26】 显示2019年7月和8月的Tokyo市记录。
data.query('City=="Tokyo" and Month in [7,8]')

【练习3-27】 绘制中国上海市在2013年的日均气温变化情况。
# 筛选符合条件的数据
filtered_data = data.query('Country=="China" and City=="Shanghai" and Year==2013')
# 画出平均温度的图
filtered_data['AvgTemperature'].plot()
【练习3-28】绘制Washington市在1996年1月的日均气温变化情况,要求使用直方图
# 第1步:筛选符合条件的数据
filtered_data = data.query('Country=="US" and City=="Washington" and Year==1996 and Month==1')
# 第2步:提取需要绘制的列并绘制条形图
filtered_data['AvgTemperature'].plot(kind='bar')