李翔-大数据技术

Big data technology!

第3章 数据检查-Pandas

3.1 项目背景

2020年7月9日,世界气象组织发布《未来五年全球气温预测评估》.数据显示2020—2024年,预计全球气温每年都有可能比工业化前的平均气温(1850—1900年期间气温年平均值)升高至少1℃,北极的升温幅度可能是全球平均水平的两倍以上。据美国陆军工程兵团估计,美国阿拉斯加州沿海小镇基瓦利纳将逐渐被海水淹没,并将于2025年被海水彻底淹没。全球变暖正给人类社会和经济生活带来日益显著的影响。

作为一名数据分析师,你的第一个任务是获取与全球气温有关的数据,对其进行处理、初步分析和简单可视化,并回答以下问题。

(1)近年来全球气温的变化趋势是什么?

(2)是否存在全球气温升高的情况?

(3)不同地区的升温幅度是否有差异?

(4)能否用通俗易懂的方式向公众展示你的工作成果?


3.2 技能图谱


image-20240724172131448


3.2.1 Pandas概述

NumPy

  • 是什么:NumPy 是一个用于科学计算的 Python 库,它提供了支持多维数组和矩阵运算的功能,还包含大量的数学函数。

  • 作用:主要用于快速处理大量的数字数据,特别是涉及到向量和矩阵运算时。

  • 特点

    • 高效的多维数组对象:提供强大的 N 维数组(ndarray),支持大量的数组运算。

    • 丰富的数学函数库:可以进行如加减乘除、线性代数、统计分析等各种复杂计算。

    • 内存紧凑:与 Python 自带的列表相比,NumPy 数组占用更少的内存,运行更快。


Pandas

  • 是什么:Pandas 是一个数据分析和数据处理的 Python 库,专为处理表格数据而设计,类似于 Excel 中的电子表格。

  • 作用:用于对数据进行清理、变换、分析和可视化,是数据科学和机器学习工作流程中的核心工具之一。

  • 特点

    • 强大的数据结构:包括 DataFrame(二维表格)和 Series(一维序列),便于数据操作。

    • 灵活的数据操作:可以方便地对数据进行切片、过滤、聚合、合并等操作。

    • 数据清洗功能:提供了处理缺失数据和重复数据的方法。

    • 与其他库的集成:能够与 NumPyMatplotlib 等库无缝集成,实现更复杂的分析和可视化。

总结:

  • NumPy 负责数值计算,

  • Pandas 负责数据的管理和分析。


3.2.2 Pandas数据结构

DataFrame 和 Series 总结

Pandas 数据结构:DataFrame(二维带标签表格),Series(一维带标签数据结构)

image-20240731103535993

Pandas DataFrame 结构图解释

  1. 总体结构

    • DataFrame:一个二维的数据结构,其中每一列可以包含不同类型的数据(数值、字符串、布尔等)。它类似于一个电子表格或 SQL 表格,非常适用于处理各种数据类型。

  2. 轴标签(Axis Labels)

    • 位置:图中顶部的橙色区域。

    • 作用:用于标识每一列的名称,这些名称在数据操作中用作列的引用。

    • 位置:图中左侧的蓝色条形区域。

    • 作用:用于标识每一行的唯一索引。默认情况下是从 0 开始的整数序列,但也可以设置为其他值,如时间序列或唯一标识符。

    • 索引(Index)

    • 列名(Columns)

  3. 数据区域

    • 位置:图中的浅灰色网格区域。

    • 作用:存储实际的数据值,每个数据值都通过其行索引和列名称进行定位和访问。

  4. 数据选择

    • 解释:当从 DataFrame 中选择单列数据时,结果是一个 Series 对象。 Series 是一维带标签的数据结构,它类似于数组,可以存储任意数据类型,且保留了来自 DataFrame 的行索引。每个 Series 对象不仅具有单一的数据类型,还可以由用户指定或自动生成索引。

    • 作用:允许对单列数据进行操作和分析,而不影响原始 DataFrame。

    • Series

  5. 轴方向(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)


未标题-1

总结对比

  • 结构

    • DataFrame 是一个二维的、带有标签的表格数据结构,类似于 Excel 表格,包含行和列索引,每列可以包含不同的数据类型。

    • Series 是一种一维的、带标签的数据结构,类似于数组或列表,只有一个索引轴,每个数据项都有一个与之对应的标签(索引)。

  • 数据类型

    • DataFrame 中的每一列必须包含相同类型的数据(例如,整型、浮点型或字符串等),但是不同的列之间可以有不同的数据类型。。

    • Series 中通常所有数据类型相同。

  • 应用

    • DataFrame 适用于处理复杂的表格数据。

    • Series 适用于处理简单的一维数据。

通过理解 DataFrame 和 Series 的特点和应用场景,可以更好地选择合适的数据结构进行数据处理和分析,从而提高数据分析的效率和效果。


一、DataFrame 与 Series 的联系

  1. 组成关系

    • DataFrame 是由多个 Series 组成的。每一列可以看作是一个 Series。

    • Series 是 DataFrame 的基本组成单元。一个 DataFrame 可以看作是由多个具有相同索引的 Series 组成的二维数据结构。

  2. 数据结构

    • Series 是一维的,包含数据和一个索引。

    • DataFrame 是二维的,包含行和列,每列是一个 Series,并且所有列共享同一个索引。

  3. 操作

    • 对 DataFrame 的列进行操作时,可以单独将一列作为一个 Series 进行操作。

    • 可以将多个 Series 合并成一个 DataFrame。

image-20240731102851083


3.3 数据获取

本书用到的数据均从 Kaggle和鲸社区免费下载。

【数据下载:】https://wwtf.lanzoul.com/iY8VB2b6170d

本教程涉及的数据及其结构的描述:

  • 文件名称city_temperature.csv

  • 数据覆盖期间:1995年至2020年

  • 记录总数:2,906,327 条

数据列说明

  1. Region(洲):地理区域划分,如亚洲、欧洲等。

  2. Country(国家):国家名称,如中国、美国等。

  3. State(地区):国家内部的州或省份,适用于部分国家。

  4. City(城市):具体的城市名称。

  5. Month(月):记录数据的月份。

  6. Day(日):记录数据的日期。

  7. Year(年):记录数据的年份。

  8. AvgTemperature(日均气温):当天的平均气温,单位为华氏度(°F)。转换为摄氏度的公式为:摄氏度 = (华氏度 - 32) / 1.8

数据特点

  • 数据单位:气温数据使用华氏度表示,这与中国常用的摄氏度不同。

  • 数据完整性:文件中存在一些字段值缺失的情况,需要在数据预处理阶段进行处理。

数据应用场景

  • 气候分析:可以用于分析不同城市和地区的气候变化模式。

  • 环境研究:有助于研究全球变暖对各地区气温的影响。

  • 教育用途:可作为教学数据,帮助学生了解数据分析的基本方法和技巧。

数据处理建议

  • 缺失值处理:检查和处理缺失数据,如填补或删除缺失记录。

  • 数据类型转换:将气温从华氏度转换为摄氏度,以符合国内的常规使用习惯。

  • 时间序列分析:利用年、月、日字段创建时间序列,进行时间序列相关的分析。


表3-1 city_temperature.csv中的前5行

国家州或省份城市日均气温
RegionCountryStateCityMonthDayYearAvgTemperature (°F)
AfricaAlgeria
Algiers11199564.2
AfricaAlgeria
Algiers12199549.4
AfricaAlgeria
Algiers13199548.8
AfricaAlgeria
Algiers14199546.4
AfricaAlgeria
Algiers15199547.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 结构和属性的精练总结:

  1. 数据规模data.shape 提供了 DataFrame 的总行数和列数。

  2. 行数检查data.shape[0] 返回 DataFrame 的总行数。

  3. 列数检查data.shape[1] 返回 DataFrame 的列数。

  4. 列标签data.columns 列出所有列名称。

  5. 数据类型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: object


3.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']]

image-20240731105443146


【例 3-9】显示第223条记录(即索引为222的行)

data[222:223]

# 解释
# data[222:223] 返回一个DataFrame,包含第223条记录(索引为222的行)。
# 由于Pandas的切片是左闭右开的,所以 data[222:223] 只包含起始索引222的那一行,而不包含结束索引223。

image-20240731105559853


【例 3-10】显示行索引为100-150的记录

data[100:151]

image-20240731105816820


【例 3-11】显示所有的Region为Asia的记录

data[data['Region']=='Asia']
  1. 条件生成:比较 data['Region']'Asia',生成布尔序列。

  2. 数据过滤:用布尔序列筛选 'Region''Asia' 的行。

  3. 结果返回:返回新 DataFrame,仅含 'Asia' 行。

image-20240731110027662


【例 3-12】查询所有的Country为China,并且City为Guangzhou的记录

data[(data['Country']=='China') & (data['City']=='Guangzhou')]
  1. 条件设置:设置 'Country' 等于 'China''City' 等于 'Guangzhou' 的条件。

  2. 逻辑组合:使用 & 操作符组合两个条件。

  3. 结果过滤:返回满足这两条件的行组成的新 DataFrame。

image-20240731110456606


3.6.2 采用.iloc或.loc方式

【知识点】

img

image-20241014151559488

lociloc 是 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 列


lociloc的区别

image-20241014151608923


lociloc总结

loc

  • 基于标签(Label-based): 使用行标签和列标签进行访问。

  • 适用于行标签和列标签: 可以使用行标签(行名)和列标签(列名)来选择数据。

  • 包含结束点: 切片选择时包含结束点,遵循左闭右闭的原则。


iloc

  • 基于位置(Integer-location based): 使用行索引和列索引进行访问。

  • 适用于整数位置索引: 可以使用整数索引来选择数据,索引从0开始。

  • 不包含结束点: 切片选择时不包含结束点,遵循左闭右开的原则。


主要区别

  • 索引类型: loc使用标签索引,iloc使用整数位置索引。

  • 结束点: loc的切片选择包含结束点,iloc的切片选择不包含结束点。

  • 适用范围:

    • loc适用于标签索引,适合处理带有自定义行标签的DataFrame;

    • iloc适用于整数位置索引,适合处理需要按位置选择数据的场景。

注意:

如果在创建 DataFrame 时没有指定索引(index),Pandas 会自动使用整数索引(从 0 开始)作为行标签。在这种情况下,行标签和整数位置是相同的,因此可以使用 lociloc 进行索引,两者的效果相同。


【例 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]

image-20240731112306530


按位置(整数索引)

data.iloc[221]

image-20240731112238699


在 Pandas 中,data.iloc[221:222]data.iloc[221] 区别:

  1. data.iloc[221:222]:

    • 这是一个切片操作,选择从索引 221 到 221(不包括 222)的行。

    • 结果是一个 DataFrame,即使只包含一行数据。

  2. data.iloc[221]:

    • 这是一个单点索引操作,直接选择索引为 221 的行。

    • 结果是一个 Series 对象,代表了该行的数据。

总结来说,前者返回一个包含指定行的 DataFrame,而后者返回一个具体行数据的 Series


【例 3-15】显示第222条记录(与【例3-14】比较)

基于标签进行选择。如果数据框(帧)的标签是默认的整数索引,这两种方法的效果是相同的

data.loc[221]

image-20240731114330385

data.loc[221:222]

image-20240731114344162

在 Pandas 中,data.loc[221]data.loc[221:222] 有如下区别:

  1. data.loc[221]:

    • 这是一个单点索引操作,直接选择索引值为 221 的行。

    • 结果是一个 Series 对象,包含该行的所有列数据。

  2. data.loc[221:222]:

    • 这是一个切片操作,选择从索引 221 到 222(包括 222)的行。

    • 结果是一个 DataFrame 对象,即使只包含一行数据。


【例 3-16】显示索引为100到150的记录中的Country、City、AvgTemperature列

data.iloc[100:150,[0,2,7]]

image-20241014163824818

等同于.loc

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

image-20241014163723236


【例 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"]]

image-20240731114900522


【例 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"

注意

  • 简洁性:使用字符串表达式进行查询,语法简单,代码更具可读性。

  • 直接使用列名:在表达式中直接使用列名,不需要加引号或使用方括号。

  • 逻辑运算符:支持使用 andornot 等逻辑运算符,或者使用 &|~

  • 字符串处理:字符串值需要用双引号(")括起来。

  • 带空格的列名:对于带有空格或特殊字符的列名,使用反引号(``)括起来。

  • **动态变量**:可以通过@` 符号在表达式中引用 Python 变量。


【例 3-20】显示2020年所有的记录。

data.query('Year == 2020')

等同于:

data.loc[data['Year']==2020]
data[data['Year']==2020]
data.loc[data.iloc[:,6]==2020]

image-20240731120700406


【例 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')]

image-20240731120634415


【例 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)
]

image-20240731120824488


【例 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)
]

image-20240731120907284


【例 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"))
]

image-20240731120950857

# 只显示满足条件的'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'(散点图)等。

  • xy:用于 DataFrame,指定 x 和 y 轴的数据列。

  • title:设置图表的标题。

  • xlabelylabel:设置 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()

image-20240804125131388


柱型图

# 导入必要的库
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()

image-20240804125416482


直方图

显示广州每年的平均气温分布情况

# 导入必要的库
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()

image-20240804130818274

从直方图可以看出广州的年度平均气温的分布情况,主要说明以下几点:

  1. 温度集中范围:大多数年份的平均气温集中在 72°F 到 74°F 之间,表明广州的年平均气温相对稳定,主要分布在这个范围。

  2. 温度分布趋势:在 68°F 到 70°F 区间和 71°F 到 72°F 区间分别有少数年份,显示了一些波动,但整体趋势还是集中在较高的平均气温范围。

  3. 偏态:该直方图表现出一种右偏分布(较低温度的年份较少),意味着广州整体上具有较温暖的气候,极少数年份可能会出现较低的平均温度。

总的来说,这个直方图展示了广州年平均气温的集中趋势,表明温暖的气候占据主导。


实验


【练习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()

image-20240731121407648


【练习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]]

image-20240731121953871


【练习3-11】 显示2001年1月1日的所有中国城市的行数据。

# 从 DataFrame data 中筛选出所有符合条件的行
data.query('Country=="China" and Year==2001 and Month==1 and Day==1')

image-20240731122030433


【练习3-12】 显示2001年1月1日的所有中国城市的行数据,只显示City和AvgTemperature列。

data.query('Country=="China" and Year==2001 and Month==1 and Day==1')[['City','AvgTemperature']]

image-20240731122127913


【练习3-13】 显示所有AvgTemperature大于95的中国城市数据。

data.query('Country=="China" and AvgTemperature>95')

image-20240731122207312


【练习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]

image-20240731122458107

第二种方法

data.iloc[0:151:50, 4:7]


iloc 方法

iloc 是 Pandas 中用于基于整数位置(即索引)来选择数据的方法。它允许你按照行和列的位置索引进行数据选择。

语法和参数

data.iloc[行选择, 列选择]
  • 行选择:指定要选择的行的索引范围。

  • 列选择:指定要选择的列的索引范围。

示例代码

data.iloc[0:151:50, 4:7]

详细解释

  1. 行选择 0:151:50

    • 0:151:表示行索引范围从 0 到 150(不包括 151)。

    • 50:表示步长为 50,即每隔 50 行选取一行。

    • 综合起来,0:151:50 表示从索引 0 开始,每隔 50 行选取一行,直到索引 150。

  2. 列选择 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 表示步长,即每隔多少个元素选择一个。
'''

image-20240731122926165


【练习3-16】 显示所有偶数行

data.iloc[::2]


【练习3-17】 显示所有奇数行,并且倒序显示。

data.iloc[-2::-2]

'''
解释
start=-2: -2 表示从倒数第二行开始,到结束。
stop 省略: 省略 stop 表示一直切片到 DataFrame 的开头。
step=-2:  -2 表示以步长为 2 进行反向切片,即每隔 2 行向上选择一行。
'''

image-20240731124116630


【练习3-18】 显示第0行到倒数第10行之间的数据(不包括倒数第10行)。

data[:-10]

image-20240731124156071


【练习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]
  1. data.tail(-10):

    • 通常,data.tail(n) 返回 DataFrame 或 Series 的最后 n 行。例如,data.tail(10) 返回最后 10 行。

    • 如果 n 是负数,Pandas 会返回去掉前 abs(n) 行后的所有行。比如 data.tail(-10) 会去掉前 10 行,返回剩下的所有行。

  2. [::-1]:

    • 这是 Python 切片操作的一部分。[::-1] 表示反转序列。对于 DataFrame 或 Series,这意味着行顺序会被颠倒。

综合起来,data.tail(-10)[::-1] 的作用是:

  • 首先,去掉 DataFrame 或 Series 的前 10 行。

  • 然后,将剩余的行顺序反转。

image-20240731124758554


【练习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]

解释:

  1. 创建一个与 DataFrame data 行数相同的布尔列表,初始时所有元素为 True

  2. 将该布尔列表中索引为 1、11、111 和 1111 的元素设置为 False

  3. 使用这个布尔列表作为条件,筛选出 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]]

image-20240731124906804

【练习3-24】 显示2019年Japan的所有记录。

data.query('Year==2019 and Country=="Japan"')

image-20240731124931954

【练习3-25】 显示2019年7月Tokyo市气温大于80°F的记录。

data.query('Year==2019 and Month==7 and City=="Tokyo" and AvgTemperature>80')

image-20240731124954779

【练习3-26】 显示2019年7月和8月的Tokyo市记录。

data.query('City=="Tokyo" and Month in [7,8]')

image-20240731125017816


【练习3-27】 绘制中国上海市在2013年的日均气温变化情况。

# 筛选符合条件的数据
filtered_data = data.query('Country=="China" and City=="Shanghai" and Year==2013')

# 画出平均温度的图
filtered_data['AvgTemperature'].plot()

image-20240731125047973

【练习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')



发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-BlogPHP 1.7.3

版权:李翔
备案/许可证编号为:新ICP备2024006115号-1