基于日期及日期范围为DataFrame新增列报错求助
问题:基于日期为DataFrame新增假期列失败
我是Python初学者,尝试根据日期及日期范围为DataFrame新增一列,但多次尝试都失败了。
原始代码
df_accident["bank_holidays_2010"] = df_accident["date"].map( {'Easter': [d.strftime('%d/%m/%Y') for d in pd.date_range('02/04/2010', periods=4)], 'Mayday': [d.strftime('%d/%m/%Y') for d in pd.date_range('03/05/2010', periods=1)], 'Spring Bank Holiday': [d.strftime('%d/%m/%Y') for d in pd.date_range('31/05/2010', periods=1)], 'Summer Bank Holiday': [d.strftime('%d/%m/%Y') for d in pd.date_range('30/08/2010', periods=1)], 'Christmas and New Year': [d.strftime('%d/%m/%Y') for d in pd.date_range('25/12/2010', periods=9)] } )
报错信息
None of [Index(['Easter', 'Mayday', 'Spring Bank Holiday', 'Summer Bank Holiday',\n 'Christmas and New Year'],\n dtype='object')] are in the [columns]"
尝试过的写法
写法一:
hols = {'Easter': [d.strftime('%d/%m/%Y') for d in pd.date_range('02/04/2010', periods=4)], 'Mayday': [d.strftime('%d/%m/%Y') for d in pd.date_range('03/05/2010', periods=1)], 'Spring Bank Holiday': [d.strftime('%d/%m/%Y') for d in pd.date_range('31/05/2010', periods=1)], 'Summer Bank Holiday': [d.strftime('%d/%m/%Y') for d in pd.date_range('30/08/2010', periods=1)], 'Christmas and New Year': [d.strftime('%d/%m/%Y') for d in pd.date_range('25/12/2010', periods=9)] }
写法二:
bank_holidays_2010 = {'Easter': ('02/04/2010', '03/04/2010', '05/04/2010', '06/04/2010'), 'Mayday': ('03/05/2010'), 'Spring Bank Holiday': ('31/05/2010'), 'Summer Bank Holiday': ('30/08/2010'), 'Christmas and New Year': ('25/12/2010', '26/12/2010', '27/12/2010', '28/12/2010', '29/12/2010', '30/12/2010', '31/12/2010', '01/01/2011', '02/01/2011') }
两种写法均出现相同错误,期望实现的效果是新增列后,能统计各假期对应的日期计数:
df_accident['bank_holidays_2010'].value_counts() Easter 466921 Mayday 301039 Spring Bank Holiday 132195 Christmas and New Year 92931
解决方案
错误原因
map方法需要的是日期到假期名的映射字典,但当前字典是假期名到日期列表的映射,方向完全相反。pandas会把字典的键当作DataFrame的列名去查找,找不到就会抛出报错。
具体实现步骤
1. 构建日期到假期的映射字典
遍历原假期字典,将每个日期映射到对应的假期名,确保日期格式和DataFrame中date列的格式一致:
import pandas as pd # 定义假期及对应日期范围 bank_holidays = { 'Easter': pd.date_range('02/04/2010', periods=4), 'Mayday': pd.date_range('03/05/2010', periods=1), 'Spring Bank Holiday': pd.date_range('31/05/2010', periods=1), 'Summer Bank Holiday': pd.date_range('30/08/2010', periods=1), 'Christmas and New Year': pd.date_range('25/12/2010', periods=9) } # 反转字典,生成日期到假期的映射 date_to_holiday = {} for holiday_name, date_range in bank_holidays.items(): # 转换日期格式为字符串,匹配df_accident['date']的格式 for date_str in date_range.strftime('%d/%m/%Y'): date_to_holiday[date_str] = holiday_name
2. 映射生成新列
使用反转后的字典调用map方法,为DataFrame新增假期列:
df_accident["bank_holidays_2010"] = df_accident["date"].map(date_to_holiday)
3. 处理非假期日期(可选)
如果date列存在不属于任何假期的日期,map会返回NaN,可以用fillna填充为指定值:
df_accident["bank_holidays_2010"] = df_accident["date"].map(date_to_holiday).fillna('Non-Holiday')
完成上述步骤后,运行df_accident['bank_holidays_2010'].value_counts()即可得到预期的统计结果。
内容的提问来源于stack exchange,提问作者kmedri
相关产品推荐
相关产品推荐

