FutureWarning:元素比较失败; 返回标量,但将来会执行元素比较

Art*_*uro 60 python numpy matplotlib python-3.x pandas

0.19.1在Python 3上使用Pandas .我在这些代码行上收到警告.我试图得到一个包含所有行数,其中字符串列表Peter出现在列Unnamed: 5.

df = pd.read_excel(xls_path)
myRows = df[df['Unnamed: 5'] == 'Peter'].index.tolist()
Run Code Online (Sandbox Code Playgroud)

警告:

"\Python36\lib\site-packages\pandas\core\ops.py:792: FutureWarning: elementwise 
comparison failed; returning scalar, but in the future will perform 
elementwise comparison 
result = getattr(x, name)(y)"
Run Code Online (Sandbox Code Playgroud)

什么是FutureWarning,我应该忽略它,因为它似乎有效.

Eri*_*ski 86

这个FutureWarning不是来自Pandas,它来自numpy,而且bug也会影响matplotlib和其他,这里是如何重现更接近麻烦来源的警告:

import numpy as np
print(np.__version__)   # Numpy version '1.12.0'
'x' in np.arange(5)       #Future warning thrown here

FutureWarning: elementwise comparison failed; returning scalar instead, but in the 
future will perform elementwise comparison
False
Run Code Online (Sandbox Code Playgroud)

使用double equals运算符重现此错误的另一种方法:

import numpy as np
np.arange(5) == np.arange(5).astype(str)    #FutureWarning thrown here
Run Code Online (Sandbox Code Playgroud)

Matplotlib的一个例子受到这个FutureWarning在其箭头图实现下的影响:https://matplotlib.org/examples/pylab_examples/quiver_demo.html

这里发生了什么?

Numpy和本地python之间存在分歧,当你将字符串与numpy的数字类型进行比较时会发生什么.注意左操作数是python的草皮,一个原始字符串,中间操作是python的草皮,但右操作数是numpy的草皮.你应该返回一个Python风格的Scalar还是一个布尔的Numpy风格的ndarray?Numpy说bool的ndarray,Pythonic开发者不同意.经典的对峙.

如果项目存在于数组中,它应该是元素比较还是标量?

如果您的代码或库使用in==运算符将python字符串与numpy ndarrays进行比较,则它们不兼容,因此当您尝试它时,它会返回一个标量,但仅限于此.警告表明将来这种行为可能会发生变化,因此如果python/numpy决定采用Numpy风格,那么你的代码就会在地毯上呕吐.

提交的错误报告:

Numpy和Python处于对峙状态,目前该操作返回标量,但未来它可能会发生变化.

https://github.com/numpy/numpy/issues/6784

https://github.com/pandas-dev/pandas/issues/7830

两种解决方案:

锁定你的python版本和numpy并忽略警告,或者照看你的左右操作数来自普通的草皮.

全局禁止警告:

import warnings
import numpy as np
warnings.simplefilter(action='ignore', category=FutureWarning)
print('x' in np.arange(5))   #returns False, without Warning
Run Code Online (Sandbox Code Playgroud)

逐行取消警告.

import warnings
import numpy as np

with warnings.catch_warnings():
    warnings.simplefilter(action='ignore', category=FutureWarning)
    print('x' in np.arange(2))   #returns False, warning is suppressed

print('x' in np.arange(10))   #returns False, Throws FutureWarning
Run Code Online (Sandbox Code Playgroud)

只需按名称抑制警告,然后在旁边添加一个响亮的注释,提及当前版本的python和numpy,说这段代码很脆弱,需要这些版本并在此处添加链接.在路上踢罐头.

  • 这个stackoverflow帖子是Python的"牛仔风管 - 磁带编程"的一个例子:代码快速,不回归测试,犯错误,破坏事物,学习,然后修复它,然后重复".在其他更快,更敏感的语言中,比如C++和Java,这个问题永远不会成为一个问题,因为类型在编译时被固定并保护,而不是被允许采取任何十亿形式,并在大气中漂浮完全混乱.祈祷我不会进一步改变合同:https://www.youtube.com/watch?v = WpE_xMRiCLE (3认同)
  • 这是有关此问题的质量信息的惊人水平。 (3认同)
  • 实际上,每当您尝试将 numpy.ndarray 与空列表进行比较时,也会引发此未来警告。例如,执行 `np.array([1, 2]) == []` 也会引发警告。 (2认同)
  • 我会发现看一个这样做的例子会很有帮助:`或者照看你的左右操作数来自一个共同的草皮` (2认同)

yhd*_*ung 10

我对相同警告消息的体验是由 TypeError 引起的。

类型错误:无效的类型比较

因此,您可能需要检查 Unnamed: 5

for x in df['Unnamed: 5']:
  print(type(x))  # are they 'str' ?
Run Code Online (Sandbox Code Playgroud)

这是我如何复制警告消息:

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3, 2), columns=['num1', 'num2'])
df['num3'] = 3
df.loc[df['num3'] == '3', 'num3'] = 4  # TypeError and the Warning
df.loc[df['num3'] == 3, 'num3'] = 4  # No Error
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。


Tob*_*tty 9

无法击败 Eric Leschinski 非常详细的答案,但这里有一个快速解决我认为尚未提及的原始问题的方法 - 将字符串放在列表中并使用.isin而不是==

例如:

import pandas as pd
import numpy as np

df = pd.DataFrame({"Name": ["Peter", "Joe"], "Number": [1, 2]})

# Raises warning using == to compare different types:
df.loc[df["Number"] == "2", "Number"]

# No warning using .isin:
df.loc[df["Number"].isin(["2"]), "Number"]
Run Code Online (Sandbox Code Playgroud)


Dat*_*man 6

当我尝试将index_col读取文件设置为Panda的数据帧时,出现相同的错误:

df = pd.read_csv('my_file.tsv', sep='\t', header=0, index_col=['0'])  ## or same with the following
df = pd.read_csv('my_file.tsv', sep='\t', header=0, index_col=[0])
Run Code Online (Sandbox Code Playgroud)

我以前从未遇到过这样的错误。我仍然试图找出背后的原因(使用@Eric Leschinski的解释和其他解释)。

无论如何,在我找出原因之前,以下方法可以立即解决该问题:

df = pd.read_csv('my_file.tsv', sep='\t', header=0)  ## not setting the index_col
df.set_index(['0'], inplace=True)
Run Code Online (Sandbox Code Playgroud)

一旦找出这种行为的原因,我将立即更新。