使用Matplotlib绘制DataFrame与数组时遇InvalidIndexError求助
问题分析:Matplotlib绘图时的InvalidIndexError错误
问题场景
- X_train是形状为(1343, 1)的pandas DataFrame
- y_pred_baseline是长度为1343的numpy数组
- 执行的绘图代码:
plt.plot(X_train, y_pred_baseline, color = "orange", label = "Baseline Model")
报错信息
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) File /opt/conda/lib/python3.9/site-packages/pandas/core/indexes/base.py:3629, in Index.get_loc(self, key, method, tolerance) 3628 try: -> 3629 return self._engine.get_loc(casted_key) 3630 except KeyError as err: File /opt/conda/lib/python3.9/site-packages/pandas/_libs/index.pyx:136, in pandas._libs.index.IndexEngine.get_loc() File /opt/conda/lib/python3.9/site-packages/pandas/_libs/index.pyx:142, in pandas._libs.index.IndexEngine.get_loc() TypeError: '(slice(None, None, None), None)' is an invalid key During handling of the above exception, another exception occurred: InvalidIndexError Traceback (most recent call last) Cell In [148], line 1 ----> 1 plt.plot(X_train, y_pred_baseline, color = "orange", label = "Baseline Model") 2 plt.scatter(X_train, y_train) 3 plt.xlabel("Area [sq meters]") File /opt/conda/lib/python3.9/site-packages/matplotlib/pyplot.py:3019, in plot(scalex, scaley, data, *args, **kwargs) 3017 @_copy_docstring_and_deprecators(Axes.plot) 3018 def plot(*args, scalex=True, scaley=True, data=None, **kwargs): -> 3019 return gca().plot( 3020 *args, scalex=scalex, scaley=scaley, 3021 **({"data": data} if data is not None else {}), **kwargs) File /opt/conda/lib/python3.9/site-packages/matplotlib/axes/_axes.py:1605, in Axes.plot(self, scalex, scaley, data, *args, **kwargs) 1363 """ 1364 Plot y versus x as lines and/or markers. 1365 (...) 1602 (``'green'``) or hex strings (``'#008000'``). 1603 """ 1604 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D) -> 1605 lines = [*self._get_lines(*args, data=data, **kwargs)] 1606 for line in lines: 1607 self.add_line(line) File /opt/conda/lib/python3.9/site-packages/matplotlib/axes/_base.py:315, in _process_plot_var_args.__call__(self, data, *args, **kwargs) 313 this += args[0], 314 args = args[1:] -> 315 yield from self._plot_args(this, kwargs) File /opt/conda/lib/python3.9/site-packages/matplotlib/axes/_base.py:490, in _process_plot_var_args._plot_args(self, tup, kwargs, return_kwargs) 487 kw[prop_name] = val 489 if len(xy) == 2: -> 490 x = _check_1d(xy[0]) 491 y = _check_1d(xy[1]) 492 else: File /opt/conda/lib/python3.9/site-packages/matplotlib/cbook/__init__.py:1362, in _check_1d(x) 1356 with warnings.catch_warnings(record=True) as w: 1357 warnings.filterwarnings( 1358 "always", 1359 category=Warning, 1360 message='Support for multi-dimensional indexing') -> 1362 ndim = x[:, None].ndim 1363 # we have definitely hit a pandas index or series object 1364 # cast to a numpy array. 1365 if len(w) > 0: File /opt/conda/lib/python3.9/site-packages/pandas/core/frame.py:3505, in DataFrame.__getitem__(self, key) 3503 if self.columns.nlevels > 1: 3504 return self._getitem_multilevel(key) -> 3505 indexer = self.columns.get_loc(key) 3506 if is_integer(indexer): 3507 indexer = [indexer] File /opt/conda/lib/python3.9/site-packages/pandas/core/indexes/base.py:3636, in Index.get_loc(self, key, method, tolerance) 3631 raise KeyError(key) from err 3632 except TypeError: 3633 # If we have a listlike key, _check_indexing_error will raise 3634 # InvalidIndexError. Otherwise we fall through and re-raise 3635 # the TypeError. -> 3636 self._check_indexing_error(key) 3637 raise 3639 # GH#42269 File /opt/conda/lib/python3.9/site-packages/pandas/core/indexes/base.py:5651, in Index._check_indexing_error(self, key) 5647 def _check_indexing_error(self, key): 5648 if not is_scalar(key): 5649 # if key is not a scalar, directly raise an error (the code below 5650 # would convert to numpy arrays and raise later any way) - GH29926 -> 5651 raise InvalidIndexError(key) InvalidIndexError: (slice(None, None, None), None)
问题原因
Matplotlib的plot函数会调用_check_1d方法验证数据维度,该方法尝试用x[:, None]这种numpy风格的二维索引访问输入数据。但X_train是单列DataFrame,属于二维表格结构,pandas不支持这种索引方式,因此抛出InvalidIndexError。
Matplotlib要求x轴输入为一维序列(比如pandas Series或numpy数组),而非二维的DataFrame。
解决方法
方法1:提取DataFrame的单列转为Series
通过索引提取单列,得到一维的Series对象:
# 方式a:通过位置索引提取 plt.plot(X_train.iloc[:, 0], y_pred_baseline, color = "orange", label = "Baseline Model") # 方式b:通过列名提取(若知道列名,比如列名为'Area') plt.plot(X_train['Area'], y_pred_baseline, color = "orange", label = "Baseline Model")
方法2:将DataFrame转为numpy数组
直接将DataFrame转换为一维numpy数组:
plt.plot(X_train.to_numpy(), y_pred_baseline, color = "orange", label = "Baseline Model") # 或者使用values属性(to_numpy()是更推荐的方式) plt.plot(X_train.values, y_pred_baseline, color = "orange", label = "Baseline Model")
内容的提问来源于stack exchange,提问作者Kazien
相关产品推荐
相关产品推荐

