如何从多列时序状态数据框构建有向邻接矩阵(R/Python)
多列时序数据有向邻接矩阵构建方案
核心规则说明
- 输入为多列结构数据框,单列对应时序维度上的一组状态集合,测试样例为3行8列结构,全量唯一状态值包含
1、2、3、5、22、23共6个 - 邻接矩阵构建逻辑:逐一遍历所有相邻列对,前一列中的每个元素,均建立指向后一列所有行对应元素的有向边,累计统计每条有向边的出现次数
- 输出为N×N维度邻接矩阵,N等于数据集内所有唯一状态值的总数量
- 方案适配数百列规模的实际数据处理,同时提供Python、R两种实现代码
Python实现
依赖pandas、numpy两个常用数据处理库,直接替换代码中测试数据部分为你的实际数据即可运行:
import pandas as pd import numpy as np # 替换为实际数据 test_data = [ [1, 2, 3, 5, 22, 23, 1, 2], [2, 3, 5, 22, 23, 1, 2, 3], [3, 5, 22, 23, 1, 2, 3, 5] ] df = pd.DataFrame(test_data) # 提取全量唯一状态,建立值到矩阵索引的映射 all_states = sorted(pd.unique(df.values.ravel())) state_idx = {val:i for i, val in enumerate(all_states)} N = len(all_states) # 初始化零矩阵 adj_mat = np.zeros((N, N), dtype=np.int32) # 遍历相邻列对累计边计数 for col in range(df.shape[1]-1): front_vals = df.iloc[:, col].values next_vals = df.iloc[:, col+1].values for f in front_vals: for t in next_vals: adj_mat[state_idx[f], state_idx[t]] += 1 # 转换为带状态标签的矩阵输出 adj_result = pd.DataFrame(adj_mat, index=all_states, columns=all_states) print(adj_result)
R语言实现
基于R基础语法实现,无需额外安装第三方包:
# 替换为实际数据 test_data <- matrix(c( 1, 2, 3, 5, 22, 23, 1, 2, 2, 3, 5, 22, 23, 1, 2, 3, 3, 5, 22, 23, 1, 2, 3, 5 ), nrow = 3, byrow = TRUE) df <- as.data.frame(test_data) # 提取全量唯一状态 all_states <- sort(unique(unlist(df))) N <- length(all_states) # 初始化零矩阵 adj_mat <- matrix( 0, nrow = N, ncol = N, dimnames = list(all_states, all_states) ) # 遍历相邻列对累计边计数 for (col in 1:(ncol(df)-1)) { front_vals <- df[[col]] next_vals <- df[[col+1]] for (f in front_vals) { for (t in next_vals) { adj_mat[as.character(f), as.character(t)] <- adj_mat[as.character(f), as.character(t)] + 1 } } } print(adj_mat)
说明:上述代码在数百列规模下运行无性能压力,如果后续需要处理千列以上更大规模数据,可以将内层双层循环替换为向量化的交叉表统计逻辑,进一步提升运行速度。
内容的提问来源于stack exchange,提问作者James Simon
相关产品推荐
相关产品推荐

