py数据科学学习笔记day4-空间数据统计分析与可视化(2)

接空间数据统计分析与可视化(1)

一、空间数据的读取和预处理

(1)读取和加载地理数据文件

1. 核心工具与核心逻辑
  • 主要库:GeoPandas(兼容多种主流地理数据格式,操作简洁);
  • 核心逻辑:通过 GeoPandas 的read_file()方法读取文件,自动将地理数据转换为GeoDataFrame(融合几何对象与属性数据的结构),直接支持后续分析。
2. 常见格式与读取方法
  • 重点格式:Shapefile(最常用矢量格式,存储点 / 线 / 面)

    • 代码示例:

      python 复制代码
      import geopandas as gpd
      # 传入文件完整路径(注意路径分隔符用"/"或"\")
      gdf = gpd.read_file('文件路径.shp')  # 后缀为.shp,无需额外配置
  • 其他支持格式:GeoJSON、GPKG(GeoPackage)、SHPX(Shapefile 索引文件)、KML 等

    • 读取方式统一:仅需修改read_file()的文件路径(带对应格式后缀,如'数据.geojson''数据.gpkg'),无需更换方法。

(2)数据预处理

一、数据清理和去重

目的 :去除重复、异常数据,保证数据准确性。核心操作

  1. 删除重复数据 :用 drop_duplicates() 移除完全重复的记录(或按指定列去重);
  2. 处理异常值:通过布尔索引筛选掉不合理数据(如面积≤0 的多边形);
  3. 保存结果 :用 to_file() 存储清理后的数据。

示例代码

python 复制代码
import geopandas as gpd  
gdf = gpd.read_file("数据路径.shp")  # 读数据  
gdf = gdf.drop_duplicates()  # 去重  
gdf = gdf[gdf["shape_area"] > 0]  # 删异常值  
gdf.to_file("清理后数据路径.shp")  # 保存  
二、处理缺失数据

目的 :补全或移除缺失值,避免分析偏差。核心操作

  1. 填充缺失值 :用 fillna() 填充数值(如均值、中位数)或分类值(如众数);
  2. 删除缺失值 :用 dropna(subset=列名) 移除关键属性(如名称、坐标)缺失的记录;
  3. 保存结果 :用 to_file() 存储处理后的数据。

示例代码

python 复制代码
gdf = gpd.read_file("数据路径.shp")  
mean_area = gdf["shape_area"].mean()  
gdf["shape_area"] = gdf["shape_area"].fillna(mean_area)  # 填充  
gdf = gdf.dropna(subset=["ntaname"])  # 删除关键列缺失值  
gdf.to_file("处理后数据路径.shp")  
三、坐标系转换

目的 :统一不同数据源的坐标系,确保空间分析对齐。核心操作

  1. 查看原坐标系 :通过 gdf.crs 获取当前坐标参考系统(CRS);
  2. 转换坐标系 :用 to_crs(目标EPSG码) 转换(如 WGS84 对应 EPSG:4326);
  3. 验证并保存 :检查转换后 CRS,用 to_file() 存储。

示例代码

python 复制代码
gdf = gpd.read_file("数据路径.shp")  
print("原坐标系:", gdf.crs)  
gdf = gdf.to_crs("EPSG:4326")  # 转换到WGS84  
print("新坐标系:", gdf.crs)  
gdf.to_file("转换后数据路径.shp"

二、空间数据的统计分析

1. 空间连接

空间连接是通过 GeoPandas 将两个(或多个)数据集(含地理数据 + 属性数据)按 "属性关联" 或 "空间关系" 合并,实现数据整合与属性传递,是 地理信息系统(GIS) 分析的核心操作。

(1)属性连接(用户示例类型):按共同属性列匹配
  • 适用场景:两个数据集有相同标识列(如编码、名称),无需空间关系判断。
  • 核心方法:GeoDataFrame.merge()(兼容 Pandas 的 merge 逻辑)。
  • 关键参数:

    • left_on:左数据集(地理数据 gdf)的连接列;
    • right_on:右数据集(普通数据 df)的连接列;
    • how:连接方式(left左连接、inner内连接、outer外连接,常用left保留所有地理数据)。
    • 不知道左右内连接什么意思可以看这篇文章
  • 示例代码:

    python 复制代码
    import geopandas as gpd
    import pandas as pd
    
    # 1. 读数据:地理数据(gdf)+ 普通属性数据(df)
    gdf = gpd.read_file("地块数据.shp")  # 含地理几何列(geometry)和属性列(如ntacode)
    pop_df = pd.read_csv("人口数据.csv")  # 普通表格,含连接列(如NTA Code)
    
    # 2. 数据预处理(可选):筛选目标数据(如2010年人口)
    pop_df = pop_df[pop_df["Year"] == 2010]
    
    # 3. 按属性连接:通过"ntacode"和"NTA Code"匹配
    merged_gdf = gdf.merge(pop_df, left_on="ntacode", right_on="NTA Code", how="left")
(2) 空间连接(按空间关系匹配):核心 GIS 连接方式
  • 适用场景:无共同属性列,按几何对象的空间关系关联(如 "点在多边形内""线穿过多边形")。
  • 核心方法:gpd.sjoin()(专门的空间连接函数)。
  • 关键参数:

    • left_df/right_df:待连接的两个 GeoDataFrame(均需含 geometry 列);
    • predicate:空间关系(within含于、contains包含、intersects相交等);
    • how:连接方式(同属性连接)。
  • 示例代码(点 - 多边形空间连接):

    python 复制代码
    # 假设:点数据(居民点)、多边形数据(行政区)
    points_gdf = gpd.read_file("居民点.shp")
    poly_gdf = gpd.read_file("行政区.shp")
    
    # 空间连接:将每个居民点关联到其所在的行政区(传递行政区属性)
    spatial_merged_gdf = gpd.sjoin(points_gdf, poly_gdf, predicate="within", how="left")
关键步骤(通用流程)
  1. 读取数据:地理数据(gdf)+ 待关联数据(gdf 或普通 df);
  2. 数据预处理:筛选目标数据、统一坐标系(空间连接必需);
  3. 执行连接:属性连接用merge(),空间连接用sjoin()
  4. 后续分析:基于合并后的数据做统计(如按地块统计人口)、可视化等。
核心要点
  1. 空间连接前需确保两个 GeoDataFrame 坐标系一致(用gdf.to_crs()统一);
  2. 属性连接需保证连接列格式一致(如编码均为字符串 / 数值);
  3. 连接后需检查数据完整性(如merged_gdf.isnull().sum()查看缺失关联)。

2. 空间缓冲区分

空间缓冲区分析的核心是为地理对象(点、线、面)创建 "影响范围"(如地铁站 1000 米服务圈),通过 GeoPandas 实现,关键步骤和函数如下:

一、核心流程与函数用法
(1)读取地理数据(获取分析对象)

目的:加载包含地理坐标的原始数据(如地铁站点数据)。

函数geopandas.read_file(filename)

  • 参数filename(必填):地理数据文件路径(支持 Shapefile、GeoJSON 等格式)。

  • 示例

    python 复制代码
    import geopandas as gpd
    # 读取地铁站Shapefile数据
    subway_stations = gpd.read_file('D:/数据/Subway Stations/geo_export_abaf55bb.shp')
  • 说明 :返回GeoDataFrame,包含geometry列(存储点 / 线 / 面坐标)和属性列(如站点名称)。

(2) 转换坐标系(确保距离单位有效)

目的:将数据从 "地理坐标系(经纬度,单位:度)" 转换为 "投影坐标系(单位:米 / 千米)",否则缓冲区距离会失真。

函数GeoDataFrame.to_crs(crs)

  • 参数crs(必填):目标坐标系的 EPSG 码(如"EPSG:2163"为美国等距圆锥投影,单位:米)。

  • 示例

    python 复制代码
    target_crs = 'EPSG:2163'  # 选择适合分析区域的投影坐标系
    subway_stations = subway_stations.to_crs(target_crs)  # 转换坐标系
  • 关键

    • 地理坐标系(如EPSG:4326)的 "度" 无法直接表示实际距离(1 度≈111 千米),必须转换为投影坐标系;
    • 不同地区需匹配对应投影(如中国常用EPSG:32649,UTM 分区投影,单位:米)。
(3) 创建缓冲区(核心操作)

目的:为每个地理对象生成指定距离的 "影响范围"(圆形 / 多边形)。

函数GeoSeries.buffer(distance)

  • 参数

    • distance(必填):缓冲区半径,单位与当前坐标系一致(如投影坐标系下为 "米");
    • resolution(可选):缓冲区边缘平滑度(默认 16,值越大越接近圆形)。
  • 示例

    python 复制代码
    buffer_radius = 1000  # 缓冲区半径1000米(单位由坐标系决定)
    # 为每个地铁站的点坐标创建缓冲区,结果存到新列"buffer"中
    subway_stations['buffer'] = subway_stations['geometry'].buffer(buffer_radius)
  • 说明

    • 点要素→生成圆形缓冲区;
    • 线要素→生成 "管道状" 缓冲区(沿线路两侧扩展);
    • 面要素→生成 "环状" 缓冲区(沿边界向外 / 向内扩展)。
(4)可视化结果(直观展示缓冲区)

目的:绘制原地理对象和缓冲区,验证分析结果。

核心函数

  • GeoDataFrame.plot(ax, color, markersize, alpha, label):绘制地理数据;

  • matplotlib.pyplot 辅助函数:创建画布、添加图例、显示图像。

  • 示例

    python 复制代码
    import matplotlib.pyplot as plt
    
    # 创建画布和坐标轴
    fig, ax = plt.subplots()  
    # 绘制原地铁站点(蓝色小点)
    subway_stations.plot(ax=ax, color='blue', markersize=5, label='地铁站')  
    # 绘制缓冲区(橙色半透明多边形)
    subway_stations['buffer'].plot(ax=ax, color='orange', alpha=0.5, label='1000米缓冲区')  
    ax.set_aspect('equal')  # 保持地图比例(避免拉伸变形)
    plt.legend()  # 显示图例
    plt.show()  # 展示图像
二、关键注意事项
  1. 坐标系是核心前提:缓冲区的 "距离"(如 1000 米)必须依赖投影坐标系,否则结果无实际意义;
  2. buffer()参数与对象匹配:半径单位需与坐标系一致,且根据要素类型(点 / 线 / 面)生成不同形状的缓冲区;
  3. 可视化比例ax.set_aspect('equal')确保缓冲区形状正确(避免圆形被拉伸为椭圆)。

3. 空间数据的聚合和汇总

空间数据的聚合和汇总核心是按 "分组条件" 对地理数据的属性或几何形状进行合并 / 计算,分为 "属性聚合"(统计数值)和 "几何聚合"(合并形状)两类,示例主要展示属性聚合,以下是详细用法:

一、核心目的

将分散的空间数据按某一分类标准(如行政区、类型)合并,同时计算该组的统计量(如总面积、平均人口)或合并几何形状(如将多个社区合并为一个行政区),用于宏观分析(如 "按城市汇总下属区域的面积")。

二、属性聚合

作用 :按分类字段(如boro_name,行政区名称)对数值属性(如shape_area,面积)进行汇总计算(求和、均值等)。

步骤与代码解析
  1. 读取空间数据 :获取包含分类字段和待聚合属性的GeoDataFrame

    python 复制代码
    import geopandas as gpd
    # 读取地块数据(含'boro_name'分类字段和'shape_area'面积属性)
    gdf = gpd.read_file('地块数据.shp')
  2. 按分类字段分组 :用groupby(分组字段)指定聚合的 "分组依据"(如按boro_name分组,即按行政区分组)。

  3. 选择属性并应用聚合函数 :对分组后的数值属性(如shape_area)使用聚合函数(sum求和、mean均值、count计数等)。

    python 复制代码
    # 按'boro_name'分组,对'shape_area'求和(计算每个行政区的总面积)
    gdf_area = gdf.groupby('boro_name')['shape_area'].sum().reset_index()
    • groupby('boro_name'):按行政区名称分组;
    • ['shape_area']:指定要聚合的属性(面积);
    • .sum():聚合函数(求和,计算每个组的总面积);
    • .reset_index():将分组结果转换为普通DataFrame(便于查看和后续处理)。
  4. 查看结果:打印或使用聚合后的统计数据。

    python 复制代码
    print(gdf_area.head())  # 显示前几行结果(每个行政区及其总面积)
三、几何聚合

作用:将同一组的几何对象(如多个社区多边形)合并为一个整体几何形状(如行政区多边形),同时可保留属性聚合结果。

核心函数GeoDataFrame.dissolve(by=分组字段, aggfunc=聚合函数)

  • by:指定分组字段(如boro_name);
  • aggfunc:对属性的聚合函数(如sum,可选)。

示例

python 复制代码
# 按'boro_name'合并几何形状,并计算每个行政区的总面积
gdf_dissolved = gdf.dissolve(by='boro_name', aggfunc={'shape_area': 'sum'})
# 结果:每个行政区一行,geometry列为合并后的多边形,shape_area为总面积
四、关键要点
  1. 分组字段选择:需是分类属性(如行政区名称、地块类型),确保同一组的对象有逻辑关联;

  2. 聚合函数匹配:根据需求选择函数(求和用于总量,均值用于平均水平,计数用于数量);

  3. 属性聚合 vs 几何聚合

    • 仅需统计数值:用groupby(示例方法);
    • 需合并几何形状:用dissolve(同时可包含属性聚合)。

二、空间数据可视化

空间数据可视化的核心是通过 GeoPandas 结合 Matplotlib,将地理数据(点、线、面)以地图形式展示,并通过布局优化(图例、标签等)增强可读性,最终可保存为多种格式。以下是分场景的用法总结:

1.基础地图可视化(GeoPandas 核心绘图)

目的:快速绘制地理数据的基础地图,展示几何形状分布。

核心步骤与函数

读取数据 :用gpd.read_file()加载地理数据(如 Shapefile),得到GeoDataFrame

绘制地图 :用GeoDataFrame.plot()直接绘制,默认显示几何形状。

显示图像 :用plt.show()展示地图。

示例代码

python 复制代码
import geopandas as gpd
import matplotlib.pyplot as plt

# 1. 读取数据
gdf = gpd.read_file("地块数据.shp")  # 含geometry列(几何形状)

# 2. 绘制基础地图
ax = gdf.plot()  # 返回坐标轴对象,可用于后续优化

# 3. 添加标题并显示
plt.title("基础空间数据可视化")
plt.show()

关键函数

  • gdf.plot():基础绘图函数,默认用单一颜色绘制所有几何对象;返回matplotlib.axes.Axes对象,便于后续添加布局元素。
二、地图布局与图例优化(增强可读性)

目的:通过分类着色、添加图例、坐标轴标签、指北针等,让地图更易理解(如按面积大小着色,展示区域差异)。

核心步骤与函数

创建画布与轴 :用plt.subplots(figsize=(宽, 高))定义地图尺寸,获得fig(画布)和ax(轴)对象。

分类着色绘图 :在gdf.plot()中通过column指定分类字段(如面积),cmap设置颜色映射,legend=True添加图例。

添加布局元素 : 标题:plt.title(); 坐标轴标签:plt.xlabel()(经度)、plt.ylabel()(纬度); 指北针:用ax.annotate()添加箭头标注 "N"。

示例代码

python 复制代码
import geopandas as gpd
import matplotlib.pyplot as plt

# 1. 读取数据
gdf = gpd.read_file("地块数据.shp")

# 2. 创建画布(10x8英寸)
fig, ax = plt.subplots(figsize=(10, 8))

# 3. 按"shape_area"(面积)着色,用"coolwarm"色阶,显示图例
gdf.plot(
    ax=ax,  # 指定绘制到创建的轴上
    column="shape_area",  # 按面积字段分类
    cmap="coolwarm",  # 颜色映射(冷到暖,体现大小差异)
    legend=True,  # 显示图例
    legend_kwds={"label": "区域面积"}  # 图例标签
)

# 4. 添加布局元素
plt.title("按面积着色的社区地图")  # 标题
plt.xlabel("经度")  # x轴标签
plt.ylabel("纬度")  # y轴标签

# 添加指北针(箭头从下到上,标注"N")
arrowprops = dict(arrowstyle="->", linewidth=1.5, color="black")  # 箭头样式
ax.annotate(
    "N",  # 标注文本
    xy=(0.06, 0.95),  # 箭头终点(轴坐标系:0-1,右上角为(1,1))
    xytext=(0.06, 0.89),  # 箭头起点
    arrowprops=arrowprops,
    ha="center", va="center",  # 文本对齐方式
    xycoords="axes fraction"  # 坐标基于轴比例(而非数据坐标)
)

# 5. 显示地图
plt.show()

关键参数与函数

  • column:指定用于分类着色的属性列(如面积、人口),实现 "thematic map(专题图)";
  • cmap:颜色映射方案(如"coolwarm""viridis",见 Matplotlib 官方文档);
  • legend_kwds:自定义图例(如标签、位置);
  • ax.annotate():添加文本标注(如指北针),xycoords="axes fraction"确保标注位置不随数据缩放变化。
三、地图输出与保存(持久化结果)

目的:将绘制好的地图保存为图片或文档格式(如 PNG、PDF),便于分享或报告使用。

核心步骤与函数

绘制并优化地图 :完成布局(标题、图例等)后,调用plt.savefig()保存。

指定保存参数

  • 路径与格式:文件名后缀决定格式(.png.pdf.jpg等);
  • dpi:分辨率(如 300,值越高越清晰);
  • bbox_inches="tight":避免边缘元素(如图例、标题)被裁剪。

示例代码

python 复制代码
# (承接上文布局优化后的代码)
# 保存为PNG(高分辨率)
plt.savefig(
    "社区面积地图.png",  # 路径+文件名
    dpi=300,  # 分辨率300dpi(适合打印)
    bbox_inches="tight"  # 紧凑布局,避免裁剪
)

# 保存为PDF(矢量格式,放大不失真)
plt.savefig(
    "社区面积地图.pdf",
    bbox_inches="tight"  # PDF无需指定dpi,默认矢量格式
)

关键说明

  • 保存需在plt.show()之前调用,否则画布会被清空;
  • 矢量格式(PDF、SVG)适合编辑(如用 AI 修改),位图格式(PNG、JPG)适合直接展示;
  • dpi仅对位图有效,建议 300dpi 用于印刷,150dpi 用于屏幕显示。

总结

空间数据可视化的核心流程是:

  1. 基础绘制read_file()读数据 → plot()绘地图 → show()展示;
  2. 布局优化 :用subplots()定义尺寸 → column+cmap分类着色 → 添加标题、图例、指北针;
  3. 保存输出savefig()按格式保存,通过dpibbox_inches控制质量。
相关推荐
q***48252 小时前
基于python语言的网页设计(手把手教你设计一个个人博客网站)
开发语言·python
qq_22589174662 小时前
基于Python+Django餐饮评论大数据分析与智能推荐系统 毕业论文
开发语言·后端·python·信息可视化·数据分析·django
FreakStudio2 小时前
串口协议解析实战:以 R60ABD1 雷达为例,详解 MicroPython 驱动中数据与业务逻辑的分离设计
python·单片机·pycharm·嵌入式·面向对象·硬件·电子diy
南山安3 小时前
让 LLM 与外界对话:使用 Function Calling 实现天气查询工具
人工智能·后端·python
用户12039112947263 小时前
打破信息壁垒:手把手教你实现DeepSeek大模型的天气查询功能
python·openai
鱼骨不是鱼翅4 小时前
力扣hot100----1day
python·算法·leetcode·职场和发展
2501_941236214 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
程序猿_极客4 小时前
【2025 最新】 Python 安装教程 以及 Pycharm 安装教程(超详细图文指南,附常见问题解决)
开发语言·python·pycharm·python安装以及配置
b***66614 小时前
Python 爬虫实战案例 - 获取社交平台事件热度并进行影响分析
开发语言·爬虫·python