Python实战:基于IPF(迭代比例拟合)算法填补空间迁移数据缺失值

在最近的数据清洗工作中,我遇到了一批存在严重缺失值的长序列空间流动数据。尤其是在构建跨度较长的地级市级别数据集时,某些特定年份或特定节点的数据存在大面积空白。 如果直接剔除这些缺失行,会导致样本量骤降;如果使用简单的均值填补,又会完全破坏空间流动数据的拓扑结构和比例关系。经过查阅文献,我决定采用**迭代比例拟合(Iterative Proportional Fitting, 简称 IPF)**方法来进行数据插补。 今天记录一下在使用 Python 实现 IPF 算法时踩过的一些坑,特别是关于输出偏差和零值处理的问题。 1. 什么是 IPF? IPF 最初是统计学中用于调整二维或多维列联表(Contingency Table)边缘分布的方法。简单来说,当我们已知一个矩阵的内部结构(比如历史基准年份的流动比例),同时又知道当前年份的总流出量(行和)与总流入量(列和)时,IPF 可以通过不断交替调整行比例和列比例,逼近真实的内部流动矩阵。 2. Python 核心实现逻辑 在 Python 中,通常不需要手写死循环,利用 numpy 和 pandas 的矩阵运算可以极大地提升效率。以下是一个简化的核心逻辑: import numpy as np import pandas as pd def apply_ipf(seed_matrix, target_row_margins, target_col_margins, tolerance=1e-5, max_iter=1000): """ seed_matrix: 历史基准矩阵 (2D numpy array) target_row_margins: 目标行和 (1D numpy array) target_col_margins: 目标列和 (1D numpy array) """ matrix = seed_matrix.copy().astype(float) for iteration in range(max_iter): # 1. 调整行比例 current_row_margins = matrix.sum(axis=1) # 避免除以零 current_row_margins[current_row_margins == 0] = 1 row_multipliers = target_row_margins / current_row_margins matrix = matrix * row_multipliers[:, np.newaxis] # 2. 调整列比例 current_col_margins = matrix.sum(axis=0) current_col_margins[current_col_margins == 0] = 1 col_multipliers = target_col_margins / current_col_margins matrix = matrix * col_multipliers # 3. 检查收敛性 row_diff = np.abs(matrix.sum(axis=1) - target_row_margins).max() col_diff = np.abs(matrix.sum(axis=0) - target_col_margins).max() if row_diff < tolerance and col_diff < tolerance: print(f"IPF converged in {iteration} iterations.") return matrix print("Warning: IPF did not converge reach max iterations.") return matrix 3. 遇到的坑与解决方案 在将上述基础逻辑应用到真实的省市级数据时,我遇到了两个主要问题: ...

March 9, 2025

极速配置 HTTPS:Caddy 服务器上手指南

相比于 Nginx 繁琐的配置和手动申请 SSL 证书,Caddy 真的是新一代的 Web 服务器神器。 它原生支持自动申请和续期 Let’s Encrypt 证书,只需一行命令即可启动静态文件服务。非常适合个人开发者。

November 2, 2023

Python 爬虫实战:如何绕过基础的反爬机制

今天记录一下在做数据挖掘时遇到的一些常见反爬策略以及应对方法。 主要是通过设置随机的 User-Agent,以及使用代理 IP 池来解决访问频率限制的问题。 后续会更新更多关于 Selenium 的使用技巧。

October 25, 2023