如何从含日期列表的单元格填充DataFrame日期列
Pandas根据缺勤列填充日期列的解决方案
问题背景
现有仅包含Name和Absences两列的数据集,Absences以逗号分隔存储缺勤日期。已手动创建对应日期的列(初始值全为0),需要将Absences中出现的日期对应的单元格填充为1,最终得到目标格式的DataFrame。
方案一:基于已有日期列的行级填充
如果已经创建了全0的日期列,可以通过拆分缺勤日期列表,逐行判断填充:
import pandas as pd # 初始化数据(含已创建的日期列) data = { 'Name': ['Student1', 'Student2', 'Student3', 'Student4'], 'Absences': ['9/1,9/3,9/4,9/5', '9/1,9/2,9/6', '9/1,9/2,9/3', '9/2'], '9/1': [0,0,0,0], '9/2': [0,0,0,0], '9/3': [0,0,0,0], '9/4': [0,0,0,0], '9/5': [0,0,0,0], '9/6': [0,0,0,0] } df = pd.DataFrame(data) # 将Absences拆分为列表 df['_abs_list'] = df['Absences'].str.split(',') # 获取所有日期列 date_cols = [col for col in df.columns if '/' in col] # 逐行遍历填充 for idx, row in df.iterrows(): for date in row['_abs_list']: df.loc[idx, date] = 1 # 删除临时辅助列 df.drop('_abs_list', axis=1, inplace=True)
方案二:从原始数据直接生成目标DataFrame(更高效)
如果还未创建日期列,推荐用Pandas的向量化操作直接生成,避免循环,效率更高:
import pandas as pd # 原始仅两列的数据 data = { 'Name': ['Student1', 'Student2', 'Student3', 'Student4'], 'Absences': ['9/1,9/3,9/4,9/5', '9/1,9/2,9/6', '9/1,9/2,9/3', '9/2'] } df = pd.DataFrame(data) # 拆分缺勤日期并展开为行 expanded = df['Absences'].str.split(',', expand=True).stack().reset_index(level=1, drop=True).to_frame('date') # 生成日期的哑变量(自动创建日期列,缺勤为1,否则0) dummies = pd.get_dummies(expanded['date'], prefix='', prefix_sep='') # 按学生分组求和(合并同一学生的多个缺勤日期) dummies = dummies.groupby(level=0).sum() # 合并回原始数据,并补全所有需要的日期列(缺失的日期填充0) all_dates = ['9/1', '9/2', '9/3', '9/4', '9/5', '9/6'] result_df = df.join(dummies).reindex(columns=['Name', 'Absences'] + all_dates, fill_value=0)
方案三:使用apply自定义函数实现
对应你尝试的apply思路,需注意设置axis=1按行处理,并正确返回修改后的行:
import pandas as pd data = { 'Name': ['Student1', 'Student2', 'Student3', 'Student4'], 'Absences': ['9/1,9/3,9/4,9/5', '9/1,9/2,9/6', '9/1,9/2,9/3', '9/2'] } df = pd.DataFrame(data) # 先创建所有日期列并初始化为0 date_cols = ['9/1', '9/2', '9/3', '9/4', '9/5', '9/6'] for date in date_cols: df[date] = 0 # 自定义填充函数 def mark_absences(row): abs_dates = row['Absences'].split(',') for date in abs_dates: row[date] = 1 return row # 按行应用函数 df = df.apply(mark_absences, axis=1)
以上三种方案都能得到你需要的目标结果,其中方案二的向量化操作在数据量较大时性能更优。
内容的提问来源于stack exchange,提问作者Matthew Rozanoff
相关产品推荐
相关产品推荐

