请求高效实现:将三列表格数据转换为numpy矩阵
高效实现三列表格转numpy矩阵的方案
核心思路
先将字符串类型的行/列标签映射为矩阵的索引,再通过numpy的向量化索引赋值批量填充数值,避免循环遍历,保证处理效率。
方法一:结合Pandas(更易处理结构化数据)
如果输入数据是表格形式,用Pandas先做标签映射会更直观:
import numpy as np import pandas as pd # 输入数据 data_rows = [('A', 'B', 1), ('C', 'D', 2), ('E', 'F', 3), ('A', 'D', 1), ('E', 'B', 4)] df = pd.DataFrame(data_rows, columns=['D1', 'D2', 'Value']) # 提取并排序唯一的行/列标签(保证顺序稳定) row_labels = sorted(df['D1'].unique()) col_labels = sorted(df['D2'].unique()) # 创建标签到矩阵索引的映射 row_idx_map = {label: idx for idx, label in enumerate(row_labels)} col_idx_map = {label: idx for idx, label in enumerate(col_labels)} # 初始化全0数值矩阵(若需空值可替换为np.full(..., np.nan)) result_matrix = np.zeros((len(row_labels), len(col_labels)), dtype=int) # 批量获取索引并赋值 row_indices = df['D1'].map(row_idx_map).values col_indices = df['D2'].map(col_idx_map).values result_matrix[row_indices, col_indices] = df['Value'].values print(result_matrix)
输出结果:
[[1 1 0] [0 2 0] [4 0 3]]
对应行顺序:A、C、E,列顺序:B、D、F,完全匹配需求。
方法二:纯Numpy实现(无额外依赖)
如果不想引入Pandas,纯Numpy也能完成:
import numpy as np # 将输入数据转为numpy数组 data = np.array([ ['A', 'B', 1], ['C', 'D', 2], ['E', 'F', 3], ['A', 'D', 1], ['E', 'B', 4] ], dtype=object) # 拆分列数据 d1_col = data[:, 0] d2_col = data[:, 1] values = data[:, 2].astype(int) # 用np.unique自动提取唯一标签并生成索引映射(返回的索引直接对应矩阵位置) row_labels, row_indices = np.unique(d1_col, return_inverse=True) col_labels, col_indices = np.unique(d2_col, return_inverse=True) # 初始化矩阵并批量赋值 result_matrix = np.zeros((len(row_labels), len(col_labels)), dtype=int) result_matrix[row_indices, col_indices] = values print(result_matrix)
输出和方法一完全一致,np.unique会自动对标签排序,所以行/列顺序同样是A/C/E和B/D/F。
效率说明
两种方法都采用向量化操作,避免了Python层面的循环,处理大规模数据时效率远高于逐行遍历赋值。如果数据量超过十万级,优势会更明显。
内容的提问来源于stack exchange,提问作者Sudhashbahu
相关产品推荐
相关产品推荐

