TypeError 使用 sns.distplot() 在数据帧上使用一行

Posted

技术标签:

【中文标题】TypeError 使用 sns.distplot() 在数据帧上使用一行【英文标题】:TypeError using sns.distplot() on dataframe with one row 【发布时间】:2017-08-19 06:59:26 【问题描述】:

我正在绘制数据框的子集,而其中一个子集恰好只有一行。这是我能想到的导致问题的唯一原因。这是它的样子:

problem_dataframe = prob_df[prob_df['Date']==7]
problem_dataframe.head()

我尝试做:

sns.distplot(problem_dataframe['floatTime'])

但我得到了错误:

TypeError: len() of unsized object

谁能告诉我是什么原因造成的以及如何解决它?

【问题讨论】:

为什么要在只有一个值的情况下绘制分布? 因为它是每个月的每一天的许多子图之一,那一天恰好只有一个条目 您应该显示完整的堆栈跟踪。它包含有价值的信息,可以帮助某人(或者,谁知道,也许是您)诊断问题。 @Peaceful 我的建议是过滤掉样本少于 5 个的组 【参考方案1】:

TypeError 是通过设置 bins=1 来解决的。

但这发现了一个不同的错误,ValueError: x must be 1D or 2D,它由 Matplotlib 的 hist() 中的一个内部函数触发,称为 _normalize_input()

import pandas as pd
import seaborn as sns
df = pd.DataFrame(['Tue','Feb',7,'15:37:58',2017,15.6196]).T
df.columns = ['Day','Month','Date','Time','Year','floatTime']
sns.distplot(df.floatTime, bins=1)

输出:

ValueError                                Traceback (most recent call last)
<ipython-input-25-858df405d200> in <module>()
      6 df.columns = ['Day','Month','Date','Time','Year','floatTime']
      7 df.floatTime.values.astype(float)
----> 8 sns.distplot(df.floatTime, bins=1)

/home/andrew/anaconda3/lib/python3.6/site-packages/seaborn/distributions.py in distplot(a, bins, hist, kde, rug, fit, hist_kws, kde_kws, rug_kws, fit_kws, color, vertical, norm_hist, axlabel, label, ax)
    213         hist_color = hist_kws.pop("color", color)
    214         ax.hist(a, bins, orientation=orientation,
--> 215                 color=hist_color, **hist_kws)
    216         if hist_color != color:
    217             hist_kws["color"] = hist_color

/home/andrew/anaconda3/lib/python3.6/site-packages/matplotlib/__init__.py in inner(ax, *args, **kwargs)
   1890                     warnings.warn(msg % (label_namer, func.__name__),
   1891                                   RuntimeWarning, stacklevel=2)
-> 1892             return func(ax, *args, **kwargs)
   1893         pre_doc = inner.__doc__
   1894         if pre_doc is None:

/home/andrew/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_axes.py in hist(self, x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, **kwargs)
   6141             x = np.array([[]])
   6142         else:
-> 6143             x = _normalize_input(x, 'x')
   6144         nx = len(x)  # number of datasets
   6145 

/home/andrew/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_axes.py in _normalize_input(inp, ename)
   6080                 else:
   6081                     raise ValueError(
-> 6082                         "ename must be 1D or 2D".format(ename=ename))
   6083                 if inp.shape[1] < inp.shape[0]:
   6084                     warnings.warn(

ValueError: x must be 1D or 2D

_normalize_input() 已从 Matplotlib 中删除(它是 looks like sometime last year),所以我猜 Seaborn 指的是引擎盖下的旧版本。

你可以在this old commit看到_normalize_input()

def _normalize_input(inp, ename='input'):
        """Normalize 1 or 2d input into list of np.ndarray or
        a single 2D np.ndarray.
        Parameters
        ----------
        inp : iterable
        ename : str, optional
            Name to use in ValueError if `inp` can not be normalized
        """
        if (isinstance(x, np.ndarray) or
                not iterable(cbook.safe_first_element(inp))):
            # TODO: support masked arrays;
            inp = np.asarray(inp)
            if inp.ndim == 2:
                # 2-D input with columns as datasets; switch to rows
                inp = inp.T
            elif inp.ndim == 1:
                # new view, single row
                inp = inp.reshape(1, inp.shape[0])
            else:
                raise ValueError(
                    "ename must be 1D or 2D".format(ename=ename))
...

不过,我不知道为什么inp.ndim!=1。对输入执行相同的np.asarray().ndim 会按预期返回1

np.asarray(df.floatTime).ndim  # 1

因此,如果您想让单值输入与 sns.distplot() 一起工作,您将面临一些障碍。

建议的解决方法 检查单个元素 df.floatTime,如果是这种情况,只需使用 plt.hist() 代替(无论如何,distplot 与 KDE 一起使用):

plt.hist(df.floatTime)

【讨论】:

以上是关于TypeError 使用 sns.distplot() 在数据帧上使用一行的主要内容,如果未能解决你的问题,请参考以下文章

seaborn distplot中的y轴是啥?

每个列数据框的分布概率,在一个图中

如何规范seaborn distplot?

seaborn的一些用法

plt/sns draw histgram

kaggle总结