Kaggle TypeError: slice indices must be integers or None or have an __index__ method

Kaggle TypeError: slice indices must be integers or None or have an __index__ method

我正在尝试以这种方式在 Kaggle 笔记本上绘制 seaborn 直方图:

 sns.distplot(myseries, bins=50, kde=True)

但是我得到这个错误:

TypeError: slice indices must be integers or None or have an __index__ method

这是 Kaggle 笔记本: https://www.kaggle.com/asindico/slice-indices-must-be-integers-or-none/

这是系列头:

0     5850000
1     6000000
2     5700000
3    13100000
4    16331452
Name: price_doc, dtype: int64

此错误似乎是一个已知问题。

https://github.com/mwaskom/seaborn/issues/1092

可能的解决方案 -> 将您的 statsmodels 包更新到 0.8.0

pip install -U statsmodels

正如@ryankdwyer 指出的那样,它是底层 statsmodels 实现中的 issue,在 0.8.0 版本中不再存在。

由于 kaggle 不允许您从任何 kernel/script 访问互联网,因此无法升级软件包。你基本上有以下两种选择:

  1. 使用sns.distplot(myseries, bins=50, kde=False)。这当然不会打印 kde。
  2. 使用版本 0.8.0 中的 code 手动修补 statsmodels 实现。诚然,这有点 hacky,但您会得到 kde 图。

这是一个例子(还有一个proof on kaggle):

import numpy as np

def _revrt(X,m=None):
    """
    Inverse of forrt. Equivalent to Munro (1976) REVRT routine.
    """
    if m is None:
        m = len(X)
    i = int(m // 2+1)
    y = X[:i] + np.r_[0,X[i:],0]*1j
    return np.fft.irfft(y)*m

from statsmodels.nonparametric import kdetools

# replace the implementation with new method.
kdetools.revrt = _revrt

# import seaborn AFTER replacing the method. 
import seaborn as sns

# draw the distplot with the kde function
sns.distplot(myseries, bins=50, kde=True)

为什么有效?好吧,它与 Python 加载模块的方式有关。来自 Python docs:

5.3.1. The module cache

The first place checked during import search is sys.modules. This mapping serves as a cache of all modules that have been previously imported, including the intermediate paths. So if foo.bar.baz was previously imported, sys.modules will contain entries for foo, foo.bar, and foo.bar.baz. Each key will have as its value the corresponding module object.

因此,from statsmodels.nonparametric import kdetools 在此模块缓存中。下次 seaborn 获取它时,缓存的版本将由 Python 模块加载器返回。由于这个缓存版本是我们适配的模块,所以用的是我们的revrt函数补丁。顺便说一句,这种做法在编写单元测试时非常得心应手,被称为mocking

从@ryankdwyer 的 seaborn 问题来看,这听起来像是 kde 中的错误。尝试使用 kde=False 关闭它。

 sns.distplot(myseries, bins=50, kde=False)