我正在尝试制作我的第一张Matplotlib小提琴图,并且我正在使用此SO帖子中的确切代码,但遇到KeyError错误。我不知道那是什么意思。有什么想法吗?
Process pandas dataframe into violinplot
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
x = np.random.poisson(lam =3, size=100)
y = np.random.choice(["S{}".format(i+1) for i in range(6)], size=len(x))
df = pd.DataFrame({"Scenario":y, "LMP":x})
fig, axes = plt.subplots()
axes.violinplot(dataset = [df[df.Scenario == 'S1']["LMP"],
df[df.Scenario == 'S2']["LMP"],
df[df.Scenario == 'S3']["LMP"],
df[df.Scenario == 'S4']["LMP"],
df[df.Scenario == 'S5']["LMP"],
df[df.Scenario == 'S6']["LMP"] ] )
错误:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-6-cd0789171d00> in <module>
15 df[df.Scenario == 'S4']["LMP"],
16 df[df.Scenario == 'S5']["LMP"],
---> 17 df[df.Scenario == 'S6']["LMP"] ] )
18
19 # axes.set_title('Day Ahead Market')
c:\Anaconda\lib\site-packages\matplotlib\__init__.py in inner(ax, data, *args, **kwargs)
1808 "the Matplotlib list!)" % (label_namer, func.__name__),
1809 RuntimeWarning, stacklevel=2)
-> 1810 return func(ax, *args, **kwargs)
1811
1812 inner.__doc__ = _add_data_doc(inner.__doc__,
c:\Anaconda\lib\site-packages\matplotlib\axes\_axes.py in violinplot(self, dataset, positions, vert, widths, showmeans, showextrema, showmedians, points, bw_method)
7915 return kde.evaluate(coords)
7916
-> 7917 vpstats = cbook.violin_stats(dataset, _kde_method, points=points)
7918 return self.violin(vpstats, positions=positions, vert=vert,
7919 widths=widths, showmeans=showmeans,
c:\Anaconda\lib\site-packages\matplotlib\cbook\__init__.py in violin_stats(X, method, points)
1460 # Evaluate the kernel density estimate
1461 coords = np.linspace(min_val, max_val, points)
-> 1462 stats['vals'] = method(x, coords)
1463 stats['coords'] = coords
1464
c:\Anaconda\lib\site-packages\matplotlib\axes\_axes.py in _kde_method(X, coords)
7910 def _kde_method(X, coords):
7911 # fallback gracefully if the vector contains only one value
-> 7912 if np.all(X[0] == X):
7913 return (X[0] == coords).astype(float)
7914 kde = mlab.GaussianKDE(X, bw_method)
c:\Anaconda\lib\site-packages\pandas\core\series.py in __getitem__(self, key)
765 key = com._apply_if_callable(key, self)
766 try:
--> 767 result = self.index.get_value(self, key)
768
769 if not is_scalar(result):
c:\Anaconda\lib\site-packages\pandas\core\indexes\base.py in get_value(self, series, key)
3116 try:
3117 return self._engine.get_value(s, k,
-> 3118 tz=getattr(series.dtype, 'tz', None))
3119 except KeyError as e1:
3120 if len(self) > 0 and self.inferred_type in ['integer', 'boolean']:
pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
KeyError: 0
答案 0 :(得分:1)
每当在容器中查找项目失败时,都会引发KeyError
。这些查询中使用的值是 keys ,并且错误表示0
不是该数据帧的有效密钥。
DataFrame
对象不是传统的NumPy数组。它们包含一个 index ,它基于或多或少的任意信息(包括数字数据,还包括日期,字符串等)提供对数据的快速查找。这与标准ndarray
相对,后者仅允许将线性索引(即位置)作为有效键。因此,当您执行类似df[0]
的操作时,这是尝试在框架索引中找到值0
,而不是检索数组中的第一项。
但是,如果您进行df[df.Scenario == 'S1']['LMP'].index
,则应该看到:
Int64Index([8, 20, 25, 27, 28, 35, 52, 57, 62, 68, 72, 74, 77, 80, 81, 83, 97], dtype='int64')
请注意,找不到0
,因此找不到KeyError
。 matplotlib
设计用于NumPy ndarray
对象,而不是熊猫DataFrame
对象。它对这种花哨的索引一无所知,因此这些类型的错误很常见。
您可以选择几种方法来解决此问题。首先,将要绘制的数据转换为数组。您可以对每个此类数组使用df[df.Scenario == 'S1']['LMP'].values
进行此操作。
另一种方法是使用像seaborn
这样的程序包,该程序包专门用于处理Pandas框架。一般来说,我强烈推荐Seaborn,这是一个非常漂亮且设计精心的套件。例如,它具有自己的violinplot
版本,它支持DataFrame
和大量选项。