基于Python实现带ID筛选的关系网络图构建技术问询
家庭关系网络图构建与ID筛选解决方案
数据说明
我有一张包含百万行数据的表格,字段如下:
serial_num:序列号FAMILY_ID:逗号分隔的家庭ID集合ID2:关系起点IDID1:关系终点IDRELATIONSHIP:关系类型
示例数据:
| serial_num | FAMILY_ID | ID2 | ID1 | RELATIONSHIP |
|---|---|---|---|---|
| A11 | x1,x2,x3,X4 | x1 | x2 | CHILD |
| A11 | x1,x2,x3,X4 | x1 | x3 | SPOUSE |
| A11 | x1,x2,x3,X4 | x1 | x4 | CHILD |
| A12 | x5,x6,x7,X8 | x5 | x6 | CHILD |
| A12 | x5,x6,x7,X8 | x5 | x7 | CHILD |
| A12 | x5,x6,x7,X8 | x5 | x8 | SPOUSE |
| A11 | x1,x2,x3,X4 | x1 | x1 | MOVIL |
| A12 | x5,x6,x7,X8 | x5 | x5 | MOVIL |
需求列表
- 构建带有
RELATIONSHIP类型标注的连线关系网络图 - 实现ID筛选功能:根据用户输入的ID,筛选对应
FAMILY_ID的所有数据后生成网络图
解决方案
1. 百万级数据预处理
先通过pandas清洗数据,过滤无效关系(如ID1与ID2相同的MOVIL类型,可根据业务调整),并建立ID与家庭的映射索引:
import pandas as pd # 分批读取百万行数据,避免内存溢出 chunk_iter = pd.read_csv('your_data.csv', chunksize=10000) processed_df = pd.concat([chunk[chunk['ID1'] != chunk['ID2']] for chunk in chunk_iter]) # 建立ID到FAMILY_ID的映射,加速筛选 id_to_family = {} for _, row in processed_df.iterrows(): family_ids = row['FAMILY_ID'].split(',') for _id in family_ids: id_to_family[_id.strip()] = row['FAMILY_ID']
2. 关系网络图构建
静态可视化(NetworkX + Matplotlib)
适合快速生成静态关系图:
import networkx as nx import matplotlib.pyplot as plt def build_static_network(df): G = nx.DiGraph() # 有向图体现关系方向(如CHILD是x1→x2) # 批量添加节点和带标签的边 edges = [(row['ID2'], row['ID1'], row['RELATIONSHIP']) for _, row in df.iterrows()] G.add_edges_from(edges, label=[e[2] for e in edges]) # 布局与绘图 pos = nx.spring_layout(G, k=0.2, iterations=30) nx.draw(G, pos, with_labels=True, node_size=2500, node_color='#87CEEB', font_weight='bold') nx.draw_networkx_edge_labels(G, pos, edge_labels=nx.get_edge_attributes(G, 'label'), font_size=9) plt.title('Family Relationship Network') plt.show() # 基于全量数据生成图 build_static_network(processed_df)
交互式可视化(PyVis)
适合查看复杂网络,支持缩放、拖拽:
from pyvis.network import Network def build_interactive_network(df): net = Network(directed=True, height='800px', width='100%') # 添加节点与带关系标签的边 for _, row in df.iterrows(): net.add_node(row['ID2'], label=row['ID2'], size=20) net.add_node(row['ID1'], label=row['ID1'], size=20) net.add_edge(row['ID2'], row['ID1'], label=row['RELATIONSHIP'], width=2) # 生成可交互网页 net.show('family_relationship_network.html') # 生成交互式图 build_interactive_network(processed_df)
3. ID筛选功能实现
根据输入ID定位对应家庭,筛选数据后生成网络图:
def filter_and_build_network(input_id): target_family = id_to_family.get(input_id.strip()) if not target_family: print(f"ID {input_id} 不存在") return # 筛选该家庭的所有关系数据 filtered_df = processed_df[processed_df['FAMILY_ID'] == target_family] print(f"筛选到 {len(filtered_df)} 条关联数据") # 生成静态图或交互式图 build_static_network(filtered_df) # build_interactive_network(filtered_df) # 示例:输入x1,筛选对应家庭数据并生成图 filter_and_build_network('x1')
性能优化建议
- 百万行数据优先用
Dask代替pandas做分布式处理,避免内存不足 - 节点过多时,可通过采样、合并重复节点简化图形
- 预先将ID到家庭的映射存储为本地文件,重复使用时直接加载,减少计算耗时
内容的提问来源于stack exchange,提问作者user17396020
相关产品推荐
相关产品推荐

