如何从学生选课DataFrame生成含二维One-Hot编码的三维Numpy数组
将学生选课DataFrame转换为三维One-Hot编码Numpy数组
问题说明
现有记录学生每学期选课情况的pandas DataFrame,需将其转换为形状为**(唯一学生数量, 唯一学期数量, 唯一课程数量)**的三维Numpy数组。其中每个学生对应的二维子数组是「学期×课程」的One-Hot编码矩阵:选过的课程对应位置为1,未选则为0。
输入数据示例
import pandas as pd data = [['1011', 10, 'Spring-2022','MATH-101'], ['1011', 11, 'Summer-2022','BIO-101'], ['1011', 12, 'Fall-2022','STAT-102'], ['1011', 12, 'Fall-2022','CHEM-101'], ['1022', 10, 'Spring-2022','ART-101'], ['1022', 10, 'Spring-2022','HIST-102'], ['1022', 12, 'Fall-2022','MATH-101'], ] df = pd.DataFrame(data, columns=['StudentID', 'TermID', 'Termname','CourseID']) print(df)
输出的DataFrame内容:
StudentID TermID Termname CourseID 0 1011 10 Spring-2022 MATH-101 1 1011 11 Summer-2022 BIO-101 2 1011 12 Fall-2022 STAT-102 3 1011 12 Fall-2022 CHEM-101 4 1022 10 Spring-2022 ART-101 5 1022 10 Spring-2022 HIST-102 6 1022 12 Fall-2022 MATH-101
期望输出
本示例需生成形状为(2,3,6)的三维Numpy数组(对应2个学生、3个学期、6门课程),具体如下:
import numpy as np arr = np.zeros((2,3,6)) arr[0,0,0] = 1 # 学生1011,学期10,课程MATH-101 arr[0,1,1] = 1 # 学生1011,学期11,课程BIO-101 arr[0,2,2] = 1 # 学生1011,学期12,课程STAT-102 arr[0,2,3] = 1 # 学生1011,学期12,课程CHEM-101 arr[1,0,4] = 1 # 学生1022,学期10,课程ART-101 arr[1,0,5] = 1 # 学生1022,学期10,课程HIST-102 arr[1,2,0] = 1 # 学生1022,学期12,课程MATH-101 print(arr)
输出结果:
[[[1. 0. 0. 0. 0. 0.] [0. 1. 0. 0. 0. 0.] [0. 0. 1. 1. 0. 0.]] [[0. 0. 0. 0. 1. 1.] [0. 0. 0. 0. 0. 0.] [1. 0. 0. 0. 0. 0.]]]
实现方案
通过以下步骤完成转换:
- 对
StudentID、TermID、CourseID建立原始值到数组索引的映射; - 初始化对应形状的全零三维数组;
- 遍历DataFrame,根据映射将对应位置设为1。
完整代码
import pandas as pd import numpy as np # 初始化输入DataFrame data = [['1011', 10, 'Spring-2022','MATH-101'], ['1011', 11, 'Summer-2022','BIO-101'], ['1011', 12, 'Fall-2022','STAT-102'], ['1011', 12, 'Fall-2022','CHEM-101'], ['1022', 10, 'Spring-2022','ART-101'], ['1022', 10, 'Spring-2022','HIST-102'], ['1022', 12, 'Fall-2022','MATH-101'], ] df = pd.DataFrame(data, columns=['StudentID', 'TermID', 'Termname','CourseID']) # 提取各维度唯一值并创建索引映射 student_ids = df['StudentID'].unique() term_ids = df['TermID'].unique() course_ids = df['CourseID'].unique() student_map = {sid: idx for idx, sid in enumerate(student_ids)} term_map = {tid: idx for idx, tid in enumerate(term_ids)} course_map = {cid: idx for idx, cid in enumerate(course_ids)} # 初始化三维数组 shape = (len(student_ids), len(term_ids), len(course_ids)) result_arr = np.zeros(shape, dtype=np.float64) # 填充One-Hot编码 for _, row in df.iterrows(): s_idx = student_map[row['StudentID']] t_idx = term_map[row['TermID']] c_idx = course_map[row['CourseID']] result_arr[s_idx, t_idx, c_idx] = 1 print(result_arr)
代码说明
- 提取三个维度的唯一值,确保覆盖所有学生、学期和课程;
- 用字典建立原始ID到连续数组索引的映射,避免索引断层;
- 遍历DataFrame每一行,根据映射定位三维数组的对应位置并设为1;
- 最终输出符合要求的One-Hot编码三维数组。
内容的提问来源于stack exchange,提问作者seeker
相关产品推荐
相关产品推荐

