You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按邮政编码聚类:将100英里范围内的地点分组

问题

我有一个约700条记录的数据集,每条记录对应唯一ID和邮政编码(Zip Code),数据结构如下:

ID     ZipCode     Sales
1      15110       10,000
2      15115       15,000
3      98000       2,000
4      98001       10,000
5      70570       10,000

同时我有NBER提供的邮政编码距离数据集(仅包含100英里范围内的邮编对),结构如下:

zip1    miles_to_zip2    zip2
1534    50               1001
1534    44               1002
1534    48               1003

这个距离数据集有1300万行,但我只需要用到我那700个邮编的相关数据。我想用Python、R或Power BI实现最简方案,给每条记录加上cluster列,将100英里范围内的地点归为同一聚类(例如ID1和ID2归为cluster1,ID3和ID4归为cluster2,ID5归为cluster3)。

最简解决方案:Python实现

这是最直接的方案,利用pandas筛选数据,networkx处理图的连通分量(聚类本质是找相互连通的邮编组):

1. 筛选目标邮编的距离数据

分块读取大距离数据集,只保留和我们700个邮编相关的行,避免内存过载:

import pandas as pd

# 读取自有数据集
my_data = pd.read_csv("your_data_file.csv")
target_zips = my_data["ZipCode"].unique().tolist()

# 分块读取并筛选距离数据
filtered_distance = pd.DataFrame()
for chunk in pd.read_csv("nber_distance_file.csv", chunksize=100000):
    # 保留zip1或zip2属于目标邮编的行
    mask = chunk["zip1"].isin(target_zips) | chunk["zip2"].isin(target_zips)
    filtered_distance = pd.concat([filtered_distance, chunk[mask]])

# 去重,避免重复的双向邮编对(如(zipA, zipB)和(zipB, zipA))
filtered_distance = filtered_distance.drop_duplicates(subset=["zip1", "zip2"])

2. 识别聚类(连通分量)

把邮编转化为图节点,100英里内的邮编对作为边,连通的节点即为同一聚类:

import networkx as nx

# 创建无向图
G = nx.Graph()
G.add_nodes_from(target_zips)
# 添加边
for _, row in filtered_distance.iterrows():
    G.add_edge(row["zip1"], row["zip2"])

# 生成邮编到聚类的映射
cluster_mapping = {}
current_cluster = 1
for component in nx.connected_components(G):
    for zip_code in component:
        cluster_mapping[zip_code] = f"cluster{current_cluster}"
    current_cluster += 1

# 合并聚类信息到原数据集
my_data["cluster"] = my_data["ZipCode"].map(cluster_mapping)

3. 输出结果

my_data.to_csv("clustered_result.csv", index=False)
R实现方案

用dplyr筛选数据,igraph处理连通分量:

1. 筛选距离数据

library(dplyr)

my_data <- read.csv("your_data_file.csv")
target_zips <- unique(my_data$ZipCode)

# 读取并筛选距离数据
filtered_distance <- read.csv("nber_distance_file.csv") %>%
  filter(zip1 %in% target_zips | zip2 %in% target_zips) %>%
  distinct(zip1, zip2, .keep_all = TRUE)

2. 生成聚类

library(igraph)

# 构建图对象
g <- graph_from_data_frame(filtered_distance[, c("zip1", "zip2")], directed = FALSE)
# 获取连通分量
cluster_info <- components(g)
# 构建映射表
cluster_mapping <- data.frame(
  ZipCode = names(cluster_info$membership),
  cluster = paste0("cluster", cluster_info$membership)
)

# 合并到原数据
clustered_data <- left_join(my_data, cluster_mapping, by = "ZipCode")
Power BI实现方案

如果习惯可视化工具,推荐直接在Power BI中嵌入Python脚本(复用上面的Python代码),步骤如下:

  1. 导入自有数据集和NBER距离数据集到Power BI;
  2. 进入转换数据界面,新建空白查询,点击运行Python脚本,粘贴前面的Python代码(注意修改文件路径为Power BI中的表名,如my_data = dataset对应导入的自有数据表);
  3. 运行后即可得到带cluster列的数据集,加载到报表中使用。

内容的提问来源于stack exchange,提问作者Jurassic_Question

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 15:35:13