There are a number of answers on this website detailing how one can ignore specific warnings in python (either by category or by providing a regex to match a warning message).
这个网站上有很多答案,详细说明了如何忽略python中的特定警告(按类别或通过提供正则表达式来匹配警告消息)。
However, none of these seem to work when I try try to suppress PerformanceWarning
s coming from PyTables.
但是,当我尝试抑制来自PyTables的PerformanceWarnings时,这些似乎都不起作用。
Here's an MWE:
以下是MWE:
import pandas as pd
import warnings
from tables import NaturalNameWarning, PerformanceWarning
data = {
'a' : 1,
'b' : 'two'
}
df = pd.DataFrame.from_dict(data, orient = 'index') # mixed types will trigger PerformanceWarning
dest = pd.HDFStore('warnings.h5', 'w')
#dest.put('data', df) # mixed type will produce a PerformanceWarning
#dest.put('data 1', df) # space in 'data 1' will trigger NaturalNameWarning in addition to the PerformanceWarning
warnings.filterwarnings('ignore', category = NaturalNameWarning) # NaturalNameWarnings ignored
warnings.filterwarnings('ignore', category = PerformanceWarning) # no effect
warnings.filterwarnings('ignore', message='.*PyTables will pickle') # no effect
#warnings.filterwarnings('ignore') # kills all warnings, not what I want
dest.put('data 2', df) # PerformanceWarning
dest.close()
Using a context manager doesn't help either:
使用上下文管理器也没有帮助:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=PerformanceWarning) # no effect
warnings.filterwarnings('ignore', message='.*PyTables') # no effect
dest.put('data 6', df)
Nor does using warnings.simplefilter()
instead of warnings.filterwarnings()
.
也不使用warnings.simplefilter()代替warnings.filterwarnings()。
Perhaps relevant, here is the PerformanceWarning:
也许与此相关,以下是性能警告:
test.py:21: PerformanceWarning:
your performance may suffer as PyTables will pickle object types that it cannot
map directly to c-types [inferred_type->mixed-integer,key->block0_values] [items->Int64Index([0], dtype='int64')]
dest.put('data 2', df) # PerformanceWarning
Contrast this with the NaturalNameWarning
, which doesn't come from the offending line in test.py
, but from tables/path.py
:
与此形成对比的是NaturalNameWarning,它不是来自test.py中的违规行,而是来自tables/path.py:
/home/user/.local/lib/python3.8/site-packages/tables/path.py:137: NaturalNameWarning: object name is not a valid Python identifier: 'data 2'; it does not match the pattern ``^[a-zA-Z_][a-zA-Z0-9_]*$``; you will not be able to use natural naming to access this object; using ``getattr()`` will still work, though
check_attribute_name(name)
This is with tables 3.7.0/python 3.8.10. Any ideas?
这与表3.7.0/python 3.8.10有关。有什么想法吗?
更多回答
Does it work in ipython terminal? Does it work in plain Python terminal?
它在ipython终端中工作吗?它在普通Python终端中工作吗?
Good question. I just tried and it turns out the PerformanceWarning
shows even when running outside of JupyterLab (copy the above MWE to a file test.py
and do python3 test.py
; you will see PerformanceWarning
s). So this probably doesn't have anything to do with JupyterLab. I will edit the question accordingly.
好问题。我刚试过,结果发现即使在JupyterLab之外运行时,性能警告也会显示(将上面的MWE复制到文件test.py并执行python3 test.py;您将看到性能警告)。所以这可能与JupyterLab无关。我将相应地编辑这个问题。
@Corralien thanks. Any idea why the warning trace doesn't indicate that the warning is coming from pandas?
@Corralien谢谢。知道为什么警告痕迹没有表明警告来自熊猫吗?
Yes. Pandas uses an utility function find_stack_level()
to modify the level where the warning is raised.
对Pandas使用实用函数find_stack_level()来修改引发警告的级别。
This may be confusing but the PerformanceWarning
is not emitted by the tables
package but by pandas
:
这可能令人困惑,但PerformanceWarning不是由tables包发出的,而是由panda发出的:
Try:
尝试:
from pandas.errors import PerformanceWarning
Example:
示例:
import pandas as pd
import warnings
from tables import NaturalNameWarning
from pandas.errors import PerformanceWarning
data = {
'a' : 1,
'b' : 'two'
}
df = pd.DataFrame.from_dict(data, orient = 'index')
dest = pd.HDFStore('warnings.h5', 'w')
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=PerformanceWarning)
dest.put('data', df) # mixed type will produce a PerformanceWarning
dest.put('data 1', df) # space in 'data 1' will trigger NaturalNameWarning
dest.close()
Only the NaturalNameWarning
should remain in the above example.
以上示例中只应保留NaturalNameWarning。
更多回答
Cool, this solved it. Why didn't the regex filter catch this? (warnings.filterwarnings('ignore', message='.*PerformanceWarning')
?
酷,这解决了它。为什么正则表达式过滤器没有捕捉到这个?(warnings.filterwarnings('ignore',message='.*PerformanceWarning')?
Because you can't filter the warning name (only the message). The correct regex is r'[\r\n]+.*performance'
我是一名优秀的程序员,十分优秀!