原作者:Damon 高校教师,中科院 GIS 博士

本文为原文章基础上,加上自己以及GPT4.0的总结整理而来

原活动链接

链接
提取码:7cbe
–来自百度网盘超级会员V5的分享

引言

在第 1 个关卡我们学习了 Python 的最基础知识,在这些知识的基础上我们可以批量的获取文件路径并且判断文件类型,算出半只脚迈入了 Python 地理数据处理的大门
,在本关我们就来学习用 Python 读取这些路径对应的数据,一只脚迈入 Python 地理数据处理的大门。

常见的地理数据格式包括:

  1. 栅格数据格式:如 GeoTIFF(地理标记图像文件)、NetCDF(网络公共数据格式)等,用于存储地球表面的栅格数据,如卫星遥感影像、数字高程模型(DEM)等。
  2. 矢量数据格式:如 Shapefile(形状文件)、GeoJSON(地理 JSON)、KML(Keyhole Markup Language)等,用于存储地球上的点、线、面等矢量要素,如地理边界、河流网络、地震震源等。
  3. 格式化文本数据:如 CSV(逗号分隔值)、TXT(纯文本文件)等,用于存储以文本形式表示的地球科学数据,如气象观测数据、水文测量数据等。
  4. 数据库格式:如 SQLite、PostgreSQL 等,用于存储和管理大量地球科学数据,如地震目录、气象站点数据等。
  5. 网络数据格式:如 WMS(Web Map Service)、WFS(Web Feature Service)等,用于通过网络进行地图和地理数据的传输和共享。
  6. 专用数据格式:如 HDF5(层次型数据格式)、GRIB(通用雷达矢量产品格式)等,用于存储特定领域的地球科学数据,如气象模型输出、海洋观测数据等。

上面每种格式都有自己的特点和适用范围。正所谓“万事开头难”,想要在使用 python 处理和分析数据,首先是要正确的读取数据。

本关卡将会带领大家读取最常见的三种地理数据:

  • 格式化文本数据:以 csv 文件为例
  • 栅格数据:以 geotiff 为例
  • 矢量数据:以 shapefile 文件为例

学完本关卡后,你要尝试处理某地区不同气象站点的气温观测数据的汇总工作,如果你顺利解决这个小问题,以后再遇到类似的数据汇总工作就手到擒来了。

1. 读取csv文件

python 中读取 csv 文件的库函数有很多,我们这里介绍使用 pandas 库来读取 csv 文件的方法。

pandas 是一个开源的 Python 数据分析库,提供了高性能、易于使用的数据结构和数据分析工具,是最常用的一个处理格式化文本的库。

pandas 中两个主要的数据结构是:

  • Series: 一维标记数组,类似于带有标签的数组或列表。
  • DataFrame: 二维的表格型数据结构,类似于电子表格或 SQL 中的表。

下面是一个 pandas 读取 csv 文件的示例:

import pandas as pd 

df = pd.read_csv('./data/GeoPy1/beijing_temp.csv')  # 读取
df.head(5)
year month day hour TEMP
0 2010 1 1 0 -11.0
1 2010 1 1 1 -12.0
2 2010 1 1 2 -11.0
3 2010 1 1 3 -14.0
4 2010 1 1 4 -12.0

可以发现,我们读取的表格中一共有 5 列,分别是 year、month、day、hour 和 TEMP,根据列名我们可以猜测这几列分别记录了时间信息和观测到的温度数据。

有时候我们拿到的csv文件前面几行是辅助信息,并不是真正的数据,这时候我们可以在读取的时候跳过,比如:

df = pd.read_csv('./data/GeoPy1/beijing_temp.csv',header=3) # 从第4行开始读取(下标从0开始)
df.head(5)
2010 1 1.1 2 -11
0 2010 1 1 3 -14.0
1 2010 1 1 4 -12.0
2 2010 1 1 5 -10.0
3 2010 1 1 6 -9.0
4 2010 1 1 7 -9.0

从上面的结果中发现上述代码的结果把第三行作为了 header(列名),这样子前面两行的数据就被忽略了。

# # 取消代码注释看看与上面的有什么不同
# df = pd.read_csv('./data/GeoPy1/beijing_temp.csv',header=None,skiprows=[0,1,2]) # 从第三行开始读取
# df.head(5)

当然,pandas 的功能肯定不只是读取啦。

pandas 提供了丰富的功能,包括:

  • 数据读取和写入:可以轻松地读取和写入多种文件格式,如 CSV、Excel、SQL 数据库等。
  • 数据清洗和转换:可以处理缺失值、重复值、异常值等,并进行数据类型转换、重塑、合并等操作。
  • 数据筛选和排序:可以根据条件对数据进行筛选和过滤,并按照指定的列进行排序。
  • 数据统计和聚合:可以进行基本统计分析、描述性统计、分组聚合等操作。
  • 数据可视化:可以使用内置的绘图工具绘制各种类型的图表,如折线图、柱状图、散点图等。

pandas 的设计目标是使数据操作变得简单、直观且高效。它广泛应用于数据清洗、数据预处理、数据分析和建模等领域。无论是处理小型数据集还是大型数据集,pandas 都提供了强大而灵活的功能来满足不同需求。大家可以在往后的使用过程中自行去学习,挖掘 pandas 的强大潜力!

2. 读取栅格数据(geotiff)

GeoTIFF(Geographic Tagged Image File Format)是一种常用的地理信息图像文件格式。它是在标准 TIFF(Tagged Image File Format)基础上扩展而来,用于存储地理空间数据和栅格图像。主要有以下特点和优势:

  1. 地理参考信息:GeoTIFF 文件可以包含地理参考信息,如坐标系统、投影信息、地理范围等。这使得 GeoTIFF 文件能够与地理空间数据进行精确对应,方便地理信息系统(GIS)和遥感应用。
  2. 栅格数据:GeoTIFF 文件可以存储栅格数据,如遥感影像、数字高程模型(DEM)、地表温度等。栅格数据以像素网格的形式表示,每个像素可以包含不同的地理属性或测量值。
  3. 多波段支持:GeoTIFF 文件支持多波段数据,可以存储多个波段的栅格数据。这对于多光谱遥感影像和其他需要多个测量通道的应用非常有用。
  4. 兼容性:GeoTIFF 文件与许多地理信息系统和遥感软件兼容,包括常用的 GIS 软件如 ArcGIS、QGIS,以及遥感软件如 ENVI、Erdas Imagine 等。这使得 GeoTIFF 成为地理空间数据交换和共享的常用格式。
  5. 数据压缩:GeoTIFF 文件支持多种压缩算法,如无损压缩(LZW、Deflate)和有损压缩(JPEG、JPEG2000),可以在保持数据质量的同时减小文件大小。

GeoTIFF 格式在地理信息系统、遥感、地球科学等领域广泛应用。它不仅可以存储和传输地理空间数据,还可以进行空间分析、图像处理、特征提取等操作,为地理信息处理和分析提供了重要的数据基础。

在 python 中可以用来读取 GeoTIFF 的库有很多,比如 gdal、rasterio 等,这里我们用 rasterio 库为例,来学习如何读取并且查看相关的元信息。

import rasterio

# 打开GeoTIFF文件
with rasterio.open('./data/GeoPy1/LC81970242014109LGN00.tif') as dataset:
    # 获取元数据信息
    metadata = dataset.meta
    print("元数据信息:")
    print(metadata)
    print("\n")

    # 读取栅格数据的波段1
    data = dataset.read(1)
    print("栅格数据-波段1:")
    print(data)
    print("\n")

    # 获取空间参考信息
    crs = dataset.crs
    print("空间参考信息:")
    print(crs)
元数据信息:
{'driver': 'GTiff', 'dtype': 'float32', 'nodata': -3.3999999521443642e+38, 'width': 757, 'height': 694, 'count': 7, 'crs': CRS.from_epsg(32631), 'transform': Affine(30.0, 0.0, 672793.029484,
       0.0, -30.0, 5770406.12239)}


栅格数据-波段1:
[[270. 250. 263. ... 190. 182. 164.]
 [400. 298. 247. ... 170. 150. 166.]
 [324. 330. 197. ... 211. 148. 162.]
 ...
 [328. 340. 348. ... 844. 620. 506.]
 [331. 350. 365. ... 977. 976. 883.]
 [329. 360. 351. ... 493. 587. 769.]]


空间参考信息:
EPSG:32631

上面的示例输出一共有三块:
(1)元数据信息:主要介绍的是关于我们所打开的遥感数据的相关信息,比如数据格式,遥感影像的大小(用长和宽表示),影像的波段数量,坐标系等;
(2)栅格数据-波段1:这里以第一个波段为1,向我们展示了遥感影像在计算机中存储的方式(每个像元用一个数字来表达,比如270就代表第一行第一列的像元,其值为270,而整个影像的数据对应的就是一个矩阵)
(3)空间参考信息:该信息是地理栅格数据和普通的数字图像之间的主要区别,因为地理数据要与现实地球对应,而有了空间参考信息我们才可以通过某种方法将第二部分的数字与真实的地理位置对应起来(在元数据信息里面包括这部分内容)。

思考 :上方代码中,with 语句的作用是什么?

在这段代码中,with 语句的作用是管理 rasterio.open 函数打开的 GeoTIFF 文件资源。with 语句提供了一种确保代码块执行完毕后资源被正确关闭的方式。这是通过上下文管理器实现的。

具体来说,with rasterio.open('./data/GeoPy1/LC81970242014109LGN00.tif') as dataset: 这行代码做了以下几件事:

  1. 使用 rasterio.open 函数打开指定的 GeoTIFF 文件(在这里是 './data/GeoPy1/LC81970242014109LGN00.tif')。

  2. 将打开的文件对象赋给变量 dataset

  3. with 语句块内,你可以使用 dataset 变量来进行各种操作,比如读取元数据、栅格数据、空间参考信息等。

  4. 一旦退出了 with 语句块,无论是因为代码正常执行完毕还是因为发生了异常,rasterio.open 打开的文件资源都会被自动关闭。这意味着你不需要手动调用关闭文件的方法,如 dataset.close(),这有助于防止文件资源泄漏和其他潜在的错误。

简而言之,with 语句在这里用于自动管理文件资源的打开和关闭,确保资源的有效利用和程序的健壮性。

✍️ 小练习:得到栅格数据的第 3、4、5 波段数据

请修改下面的代码,使其顺利运行

🐋:选中下方代码 cell,摁 Ctrl+A 全选后,再摁 Ctrl+/ 即可取消注释

with rasterio.open('./data/GeoPy1/LC81970242014109LGN00.tif') as dataset:
    data = dataset.read([3,4,5]) # 请替换_为合适的代码

3. 读取矢量数据(shapefile)

Shapefile 是一种常用的地理信息系统(GIS)数据存储格式,由 ESRI(Environmental Systems Research Institute)开发。它是一种矢量数据格式,用于存储地理空间数据和属性数据。

Shapefile 文件由多个文件组成,通常包括以下几个文件:

  • .shp 文件:存储几何数据,包括点、线、多边形等地理要素的坐标信息。
  • .shx 文件:存储几何索引,用于加快空间查询和访问。
  • .dbf 文件:存储属性数据,以表格形式记录每个地理要素的属性信息。
  • .prj 文件:存储坐标系和投影信息,描述地理数据的空间参考系统。

Shapefile 文件具有以下特点和优势:

  1. 灵活性:Shapefile 可以存储各种类型的地理要素,如点、线、多边形等,适用于不同的地理空间数据。
  2. 兼容性:Shapefile 是一种通用的 GIS 数据格式,被广泛支持和使用,包括主流的 GIS 软件和编程语言。
  3. 存储效率:Shapefile 采用二进制格式存储几何数据和索引,具有较小的存储空间占用。
  4. 属性数据支持:Shapefile 可以存储每个地理要素的属性信息,如名称、面积、人口等,方便进行属性查询和分析。
  5. 空间分析:Shapefile 支持常见的空间查询和分析操作,如缓冲区分析、空间关系判断等。

Shapefile 文件在各种 GIS 应用中被广泛使用,包括地图制作、空间分析、资源管理、环境研究等。它是一种常见且可靠的地理数据交换和共享格式。Python 中可以读取 shapefile 的库有好几个,比如 gdal、geopandas、PyShp 等,这里我们以geopandas读取 shapefile 为例,来学习如何用 python 读取矢量数据。

!pip install geopandas
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: geopandas in c:\users\chengyuanting\appdata\roaming\python\python39\site-packages (0.14.3)
Requirement already satisfied: shapely>=1.8.0 in c:\users\chengyuanting\appdata\roaming\python\python39\site-packages (from geopandas) (2.0.3)
Requirement already satisfied: pandas>=1.4.0 in c:\programdata\anaconda3\lib\site-packages (from geopandas) (1.4.2)
Requirement already satisfied: pyproj>=3.3.0 in c:\users\chengyuanting\appdata\roaming\python\python39\site-packages (from geopandas) (3.6.1)
Requirement already satisfied: fiona>=1.8.21 in c:\users\chengyuanting\appdata\roaming\python\python39\site-packages (from geopandas) (1.9.6)
Requirement already satisfied: packaging in c:\programdata\anaconda3\lib\site-packages (from geopandas) (21.3)
Requirement already satisfied: click-plugins>=1.0 in c:\programdata\anaconda3\lib\site-packages (from fiona>=1.8.21->geopandas) (1.1.1)
Requirement already satisfied: six in c:\programdata\anaconda3\lib\site-packages (from fiona>=1.8.21->geopandas) (1.16.0)
Requirement already satisfied: attrs>=19.2.0 in c:\programdata\anaconda3\lib\site-packages (from fiona>=1.8.21->geopandas) (21.4.0)
Requirement already satisfied: importlib-metadata in c:\programdata\anaconda3\lib\site-packages (from fiona>=1.8.21->geopandas) (4.11.3)
Requirement already satisfied: click~=8.0 in c:\programdata\anaconda3\lib\site-packages (from fiona>=1.8.21->geopandas) (8.0.4)
Requirement already satisfied: cligj>=0.5 in c:\programdata\anaconda3\lib\site-packages (from fiona>=1.8.21->geopandas) (0.7.2)
Requirement already satisfied: certifi in c:\programdata\anaconda3\lib\site-packages (from fiona>=1.8.21->geopandas) (2021.10.8)
Requirement already satisfied: colorama in c:\programdata\anaconda3\lib\site-packages (from click~=8.0->fiona>=1.8.21->geopandas) (0.4.4)
Requirement already satisfied: numpy>=1.18.5 in c:\users\chengyuanting\appdata\roaming\python\python39\site-packages (from pandas>=1.4.0->geopandas) (1.22.4)
Requirement already satisfied: pytz>=2020.1 in c:\programdata\anaconda3\lib\site-packages (from pandas>=1.4.0->geopandas) (2021.3)
Requirement already satisfied: python-dateutil>=2.8.1 in c:\programdata\anaconda3\lib\site-packages (from pandas>=1.4.0->geopandas) (2.8.2)
Requirement already satisfied: zipp>=0.5 in c:\programdata\anaconda3\lib\site-packages (from importlib-metadata->fiona>=1.8.21->geopandas) (3.7.0)
Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in c:\programdata\anaconda3\lib\site-packages (from packaging->geopandas) (3.0.4)
import geopandas as gpd

# 读取Shapefile文件
shp = gpd.read_file('./data/GeoPy1/Province_wgs84.shp')

# 查看数据类型
print(type(shp))
# 查看数据前五行
shp.head(5)
<class 'geopandas.geodataframe.GeoDataFrame'>

省代码 类型 geometry
0 110000 北京市 直辖市 POLYGON ((116.67527 41.04010, 116.67616 41.040...
1 120000 天津市 直辖市 POLYGON ((117.44383 40.25101, 117.45611 40.246...
2 130000 河北省 MULTIPOLYGON (((118.85390 39.10692, 118.84934 ...
3 140000 山西省 POLYGON ((114.13714 40.73445, 114.13860 40.732...
4 150000 内蒙古自治区 自治区 POLYGON ((121.49813 53.32607, 121.50116 53.321...

通常,Shapefile 文件中的数据包括几何信息和属性信息。几何信息描述了地理要素的空间位置和形状,而属性信息包含了每个地理要素的附加属性,如名称、面积、人口等。比如上面打印的信息中,geometry 列保存了该文件的几何信息,而省代码、省、类型保存的是属性信息。

属性信息的获取

有时候我们在科研和工作中拿到了 shp 文件,但是在一些统计分析的时候只需要属性信息,上面我们直接读取 shp 文件后获得的是几何信息+属性信息,那么如何获得其中的属性信息呢?当然是把几何信息给扔掉就行啦:

df = shp.drop('geometry', axis=1)  # axis=1表示对列进行处理,比如本行代码就代表扔掉'geometry'这一列
df.head()
省代码 类型
0 110000 北京市 直辖市
1 120000 天津市 直辖市
2 130000 河北省
3 140000 山西省
4 150000 内蒙古自治区 自治区
df.shape[0]
35
len(df)
35
# 取消注释,运行下面的代码查看索引结果
# geometry = shp['geometry']
# geometry

快速可视化矢量数据

我们可以使用 geopandas 包中的 plot() 函数快速地可视化读取的矢量文件:

shp.plot();  # plot函数不加任何参数的时候默认只是绘制出矢量文件的几何信息  

在这里插入图片描述

上面我们学习如何 csv、geotiff 和 shapefile 三种最常见的地理数据,并且获取了其中保存的数据和相应的元信息,有了数据我们就可以进行后续的分析工作啦,比如下面的一个小闯关题目。结合你上面学到的知识,轻松拿下它吧!

✍️ 小练习:可视化矢量的某个字段

shp.plot('类型');  # 替换_为合适的字符串

在这里插入图片描述

上面我们学习如何 csv、geotiff 和 shapefile 三种最常见的地理数据,并且获取了其中保存的数据和相应的元信息,有了数据我们就可以进行后续的分析工作了。比如下面的一个小闯关题目。结合你上面学到的知识,轻松拿下它吧!

闯关题

STEP 1: 按照题目要求完成以下任务

假设 "/home/mw/input/GeoPy17233/GeoPy1/temp"文件夹下是某地区不同站某时间的气温观测数据,现在要统计观测的总记录数,请编写一个函数批量读取每个文件,然后统计总观测记录数量作为返回值,并将结果赋值给变量 a1。

提示

  • 每一行就是一条观测
  • 只读取文件夹下的 csv 文件
  • 可以用 glob 模块中的 glob 函数获取文件夹下的所有文件(前面关卡出现过~)
  • 可以用 len() 函数来获取 pandas 中 dataframe 的行数
# 导入库
import glob 
import pandas as pd

# ...你的代码...
files = glob.glob('./data/GeoPy1/temp/*.csv')  # 替换_为合适的字符

count = 0
def count_rows(x):
    df = pd.read_csv(x)
    n = len(df)  # 使用合适的函数替换____
    return n 

for file in files:
    count += count_rows(file)  # 使用合适的函数替换____

a1 = count   ## 请给a1赋值
a1
2938

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐