如何解决Python绘图代码中的KeyError('2019-10')错误?
问题:绘图函数触发KeyError,无法找到日期键'2019-10'
测试绘图功能时所有图表都报相同错误,同事运行同款代码正常,不确定是缺库还是版本问题。错误出在filter_df = df[fechas[d]].copy()行,提示找不到'2019-10'这个键。
出错代码
def sub_plot_weekday(df): fechas = [] for i in range(len(df.index)): date = str(df.index[i])[0:7] if date not in fechas: fechas.append(date) #print(fechas) n_subplots = len(fechas) n_col = 2 n_rows = math.ceil(n_subplots/n_col) fig = plt.figure(figsize = (20, 12)) for d in range(len(fechas)): #Guardamos en una var el df filtrado x fecha filter_df = df[fechas[d]].copy() #Guardamos en una lista el nombre de cada día para cada "Fecha" y la ponemos en una columna #print(filter_df) dates = filter_df.index name_m = dates[0].strftime("%B") list_weekdays = [dates[i].date().strftime("%A") for i in range(len(dates))] filter_df['weekday'] = list_weekdays # Creamos un df agrupando por día de semana contando eventos grouped_by_weekday = pd.DataFrame(filter_df[['EVENT', 'weekday']][filter_df['EVENT'] != 0].groupby('weekday').count()) days_index = grouped_by_weekday.index.tolist() days_values = grouped_by_weekday.EVENT.tolist() order_day, order_val = reorder_lists(days_index, days_values) #Añadimos subplot plt.subplot(n_rows, n_col, d+1) plt.title('Number of Operations per Weekday (' + name_m + ' ' +fechas[d][:4] + ')',fontsize= 17) plt.bar(order_day, order_val, color = 'purple') #(0.5,0.1,0.5,0.6) #plt.xticks(order_day, rotation=45) for i, val in enumerate(order_val): plt.text(i, val, int(val), horizontalalignment='center', verticalalignment='bottom', fontdict={'fontweight':500, 'size':12}) plt.ylim(0,26) plt.xticks(order_day, rotation=0) fig.tight_layout(pad=2.0) plt.show() sub_plot_weekday(dt1)
错误回溯信息
KeyError Traceback (most recent call last) File ~\AppData\Local\anaconda3\envs\myenv\lib\site-packages\pandas\core\indexes\base.py:3790, in Index.get_loc(self, key) 3789 try: -> 3790 return self._engine.get_loc(casted_key) 3791 except KeyError as err: File index.pyx:152, in pandas._libs.index.IndexEngine.get_loc() File index.pyx:181, in pandas._libs.index.IndexEngine.get_loc() File pandas\_libs\hashtable_class_helper.pxi:7080, in pandas._libs.hashtable.PyObjectHashTable.get_item() File pandas\_libs\hashtable_class_helper.pxi:7088, in pandas._libs.hashtable.PyObjectHashTable.get_item() KeyError: '2019-10' The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) Cell In[11], line 1 ----> 1 sub_plot_weekday(dt1) Cell In[10], line 25, in sub_plot_weekday(df) 21 #Recoremos cada "fecha" recogida 23 for d in range(len(fechas)): 24 #Guardamos en una var el df filtrado x fecha ---> 25 filter_df = df[fechas[d]].copy() 26 #Guardamos en una lista el nombre de cada día para cada "Fecha" y la ponemos en una columna 27 #print(filter_df) 28 dates = filter_df.index File ~\AppData\Local\anaconda3\envs\myenv\lib\site-packages\pandas\core\frame.py:3896, in DataFrame.__getitem__(self, key) 3894 if self.columns.nlevels > 1: 3895 return self._getitem_multilevel(key) -> 3896 indexer = self.columns.get_loc(key) 3897 if is_integer(indexer): 3898 indexer = [indexer] File ~\AppData\Local\anaconda3\envs\myenv\lib\site-packages\pandas\core\indexes\base.py:3797, in Index.get_loc(self, key) 3792 if isinstance(casted_key, slice) or ( 3793 isinstance(casted_key, abc.Iterable) 3794 and any(isinstance(x, slice) for x in casted_key) 3795 ): 3796 raise InvalidIndexError(key) -> 3797 raise KeyError(key) from err 3798 except TypeError: 3799 # If we have a listlike key, _check_indexing_error will raise 3800 # InvalidIndexError. Otherwise we fall through and re-raise 3801 # the TypeError. 3802 self._check_indexing_error(key) KeyError: '2019-10' <Figure size 2000x1200 with 0 Axes>
问题分析与修复
核心问题是搞混了行索引和列的用法:你从行索引里提取了日期字符串fechas,但却用df[fechas[d]]去按列名取数据,而你的数据里根本没有叫'2019-10'的列,自然触发KeyError。同事的代码能跑,是因为他的dt1数据结构和你的不一样——他的列名是日期格式,而你的日期存在行索引里。
修复方案:
- 替换错误的过滤代码,改成按行索引筛选对应年月的数据,推荐两种写法:
- 简单字符串匹配(如果索引是字符串格式):
filter_df = df.loc[df.index.str.startswith(fechas[d])].copy() - 规范datetime索引筛选(先把索引转为datetime类型,更可靠):
# 先确保索引是datetime类型(放在函数开头) df.index = pd.to_datetime(df.index) # 筛选对应年月 year, month = int(fechas[d][:4]), int(fechas[d][5:]) filter_df = df[(df.index.year == year) & (df.index.month == month)].copy()
- 简单字符串匹配(如果索引是字符串格式):
- 另外,提取
fechas的循环代码可以简化,不用手动遍历:# 如果索引是字符串 fechas = df.index.str[:7].unique().tolist() # 如果是datetime索引,更规范 fechas = df.index.to_period('M').astype(str).unique().tolist()
内容的提问来源于stack exchange,提问作者Luis Enrique Orozco Villanueva
相关产品推荐
相关产品推荐

