如何用Pandas基于双列条件从另一DataFrame填充空n×n矩阵
构建指定的人口流动矩阵方案
需求回顾
基于现有DataFrame生成n×n矩阵,以排序后的state_county_fip作为行、列名,仅填入原数据中geoid_o和geoid_d均属于目标ID列表的pop_flows值,其余位置填0。
完整实现步骤及代码
- 导入依赖并定义原始数据
import pandas as pd # 原始人口流动数据 test_mob_df = pd.DataFrame( {"geoid_o": [10002, 18039, 18039, 18182, 10006, 18111, 18005, 17001], "geoid_d": [10005, 18039, 18111, 18182, 18005, 17004, 18050, 15001], "pop_flows": [20,10,9,15,2,1,6,30]} ) # 目标区域ID列表 state_county_fip = [18182, 18111, 18005, 18039, 18050, 18001]
- 筛选符合条件的流动记录
直接判断双向ID是否同时属于目标列表,比范围查询更精准:
# 转集合提升查询效率 target_ids = set(state_county_fip) # 筛选出双向ID都在目标列表中的记录 filtered_flows = test_mob_df[ test_mob_df['geoid_o'].isin(target_ids) & test_mob_df['geoid_d'].isin(target_ids) ]
- 创建排序后的空矩阵
先对目标ID排序,再初始化全0结构:
# 对目标ID排序 sorted_ids = sorted(state_county_fip) # 生成全0的n×n矩阵,行、列均为排序后的ID flow_matrix = pd.DataFrame(0, index=sorted_ids, columns=sorted_ids)
- 填充矩阵数据
将筛选到的流动值填入对应位置:
for _, row in filtered_flows.iterrows(): origin = row['geoid_o'] dest = row['geoid_d'] flow_matrix.at[origin, dest] = row['pop_flows']
- 查看最终结果
运行print(flow_matrix)即可得到需求中的矩阵:
18001 18005 18039 18050 18111 18182 18001 0 0 0 0 0 0 18005 0 0 0 6 0 0 18039 0 0 10 0 9 0 18050 0 0 0 0 0 0 18111 0 0 0 0 0 0 18182 0 0 0 0 0 15
补充说明
- 用集合存储目标ID,
isin查询效率远高于列表,数据量大时优势明显 at方法适合单个位置赋值,比loc操作更高效- 排序后的ID保证矩阵行、列顺序统一,符合规范要求
内容的提问来源于stack exchange,提问作者AkunwexOrwa
相关产品推荐
相关产品推荐

