未来警告:使用非元组序列进行多维索引已被弃用,请使用 `arr[tuple(seq)]`。

30

我在 S/O 上搜索了,但找不到答案。

当我尝试使用 seaborn 绘制分布图时,出现了未来警告。我想知道这里可能出了什么问题。

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
% matplotlib inline
from sklearn import datasets

iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['class'] = iris.target
df['species'] = df['class'].map({idx:s for idx, s in enumerate(iris.target_names)})


fig, ((ax1,ax2),(ax3,ax4))= plt.subplots(2,2, figsize =(13,9))
sns.distplot(a = df.iloc[:,0], ax=ax1)
sns.distplot(a = df.iloc[:,1], ax=ax2)
sns.distplot(a = df.iloc[:,2], ax=ax3)
sns.distplot(a = df.iloc[:,3], ax=ax4)
plt.show()

这是警告:

C:\ProgramData\Anaconda3\lib\site-packages\scipy\stats\stats.py:1713:
FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; 
use `arr[tuple(seq)]` instead of `arr[seq]`. 
In the future this will be interpreted as an array index, `arr[np.array(seq)]`,
which will result either in an error or a different result.
return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval

需要帮助吗?您可以运行上述代码,然后会收到警告。

Pandas: 0.23.4, seaborn: 0.9.0, matplotlib:2.2.3, scipy:1.1.0, numpy:1.15.0'


运行代码时我没有收到警告。也许你想分享一下你正在使用哪些版本的pandas、matplotlib、scipy、numpy和seaborn?我认为更新它们可能会防止出现这种情况。 - ImportanceOfBeingErnest
@ImportanceOfBeingErnest Pandas : 0.23.4、seaborn : 0.9.0、matplotlib : 2.2.3、scipy : 1.1.0、numpy : 1.15.0' - user_6396
1
好的,这是因为使用了numpy 1.15(在numpy 1.14.6中不会出现此问题)。稍后我可能会更深入地查看哪个软件包引起了这个问题。 - ImportanceOfBeingErnest
1
因此,一个[mcve]是sns.kdeplot(data = [1,3,4])。我想这是 seaborn 中的问题。 - ImportanceOfBeingErnest
1
不,旧版的seaborn不能解决这个问题。为了消除警告,您可以安装旧版的numpy(例如1.14.6);但是目前这个警告并没有什么危害。我们希望在numpy删除列表索引支持之前,scipy会发布一个新版本。我相信这将很快发生。 - ImportanceOfBeingErnest
显示剩余2条评论
5个回答

22

如果您使用的是python>=3.7,则需要升级您的scipy>=1.2


1
我同意这个解决方案。在SciPy 1.2中,它按预期工作。之前版本中的警告可能是由于代码不完整造成的。 - Jumy Elerossë
1
除了SciPy之外,这也适用于skimage。 - mdoc-2011

13

希望能提供更详细的回溯信息。 我猜测 seaborn.distplot 在计算某些内容时使用了 scipy.stats。错误发生在

def _compute_qth_percentile(sorted, per, interpolation_method, axis):
    ....
    indexer = [slice(None)] * sorted.ndim
    ...
    indexer[axis] = slice(i, i + 2)
    ...
    return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval

因此,在这最后一行中,使用列表indexer来切片sorted

In [81]: x = np.arange(12).reshape(3,4)
In [83]: indexer = [slice(None), slice(None,2)]
In [84]: x[indexer]
/usr/local/bin/ipython3:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  #!/usr/bin/python3
Out[84]: 
array([[0, 1],
       [4, 5],
       [8, 9]])
In [85]: x[tuple(indexer)]
Out[85]: 
array([[0, 1],
       [4, 5],
       [8, 9]])

使用切片列表是可行的,但计划在未来停用。涉及多个维度的索引应为元组。在此上下文中使用列表是一种较旧的风格,正在逐步淘汰。

所以,scipy 的开发人员需要修复这个问题。这不是最终用户应该处理的事情。但现在,不必担心 futurewarning。它不会影响计算或绘图。有一种方法可以抑制未来的警告,但我没有记在脑子里。

FutureWarning: 使用非元组序列进行多维索引已过时,请使用 `arr[tuple(seq)]` 替代 `arr[seq]`


谢谢提供信息 :) 我一直在想是我自己的问题导致了错误。因此,我想知道是什么导致了这个错误,以及如何修复它。 - user_6396
这是一个很好的解释,虽然没有提供解决方案。请参考@NetworkMeister的解决方案 - 只需升级scipy即可。该错误已在之前的版本中修复。 - mr_mo
1
我觉得这有点令人困惑。他们是否提供了一些解释,说明在哪些情况下结果会不同?因为它说“这将导致错误或不同的结果。”。错误可能还好,因为它会提醒用户存在问题,但是默默产生不同的结果让我更担心。 - Jason
@Jason:请注意,np.array([[1,2]]) 是一个二维数组。而 tuple([[1,2]]) 是一个元组,其中第一个组件是一个一维列表。目前,当一个>1d列表被传递到np.array的索引中时,采用后者的方法。但在未来,将采用第一种方法:即用np.array(...)包装。 - VimNing

6

我运行了seaborn.regplot,并按照NetworkMeister建议,升级了scipy 1.2,从而消除了警告。

pip install --upgrade scipy --user

如果在其他seaborn图表中仍然收到警告,您可以事先运行以下操作。这对于Jupyter笔记本非常有用,因为即使您的图表很棒,警告也会使报告看起来不太好。

import warnings
warnings.filterwarnings("ignore")

2
我遇到了同样的警告。我更新了scipy、pandas和numpy。但我仍然得到这个警告。当我使用带有kde的seaborn.pairplot时,就会出现这个警告,它底层使用seaborn.kdeplot
如果你想消除这个警告,可以使用warnings库。例如:
import warnings

with warnings.catch_warnings():

    your_code_block

1
仍然收到警告。 - rahul-ahuja

0

工作示例:

import numpy as np
import warnings

x  = np.random.normal(size=100)

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    
    sns.distplot(x, hist=False, rug=True, color="r");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接