How to suppress pandas warnings (tested on pandas 2 and 3)
Use warnings.filterwarnings("ignore", category=...) with the exact pandas class, ideally inside warnings.catch_warnings(). Measured traps: module="pandas" matches nothing, -W ignore::pandas.errors.X is rejected, and on pandas 3 Pandas4Warning is a DeprecationWarning, so ignoring FutureWarning misses it.
All blocks import this helper, which triggers four common pandas warnings:
# noisy.py
import pandas as pd
def noisy():
df = pd.DataFrame({"a": range(3)})
for i in range(101):
df[f"c{i}"] = i # fragmented frame
pd.Series([1, None, 3], dtype=object).fillna(0) # downcasting
pd.concat([pd.DataFrame({"x": [1.0]}), pd.DataFrame({"x": [None]})])
sub = df[df["a"] > 0]
sub["a"] = 0 # chained assignment
1. Which warnings you actually get
import warnings, collections
import pandas as pd
from noisy import noisy
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
noisy()
print(pd.__version__, collections.Counter(type(w.message).__name__ for w in caught))
print([n for n in dir(pd.errors) if n.endswith("Warning")])
Output with pandas 2.3.3:
2.3.3 Counter({'PerformanceWarning': 2, 'FutureWarning': 2, 'SettingWithCopyWarning': 1})
['AttributeConflictWarning', 'CSSWarning', 'CategoricalConversionWarning', 'DtypeWarning', 'IncompatibilityWarning', 'ParserWarning', 'PerformanceWarning', 'SettingWithCopyWarning']
Output with pandas 3.1.0:
3.1.0 Counter({'PerformanceWarning': 2})
['AttributeConflictWarning', 'CSSWarning', 'CategoricalConversionWarning', 'DtypeWarning', 'IncompatibilityWarning', 'Pandas4Warning', 'Pandas5Warning', 'PandasChangeWarning', 'PandasDeprecationWarning', 'PandasFutureWarning', 'PandasPendingDeprecationWarning', 'ParserWarning', 'PerformanceWarning', '_CurrentDeprecationWarning']
The same code gives five warnings on pandas 2.3.3 and two on 3.1.0. pandas 3 removed SettingWithCopyWarning (copy-on-write makes sub an independent copy), and the fillna/concat behaviour that used to raise FutureWarnings is now simply the default. Before silencing anything, check whether the warning is telling you about a result that will change: see fillna downcasting, concat empty entries and groupby FutureWarnings.
2. Silence by category (and why module="pandas" does not work)
import warnings, collections
import pandas as pd
from noisy import noisy
def count():
with warnings.catch_warnings(record=True) as caught:
noisy()
return dict(collections.Counter(type(w.message).__name__ for w in caught))
warnings.simplefilter("always")
warnings.filterwarnings("ignore", category=pd.errors.PerformanceWarning)
print("ignore PerformanceWarning:", count())
warnings.filterwarnings("ignore", category=FutureWarning)
print("+ ignore FutureWarning: ", count())
warnings.filterwarnings("ignore", category=Warning, module="pandas")
print("+ module='pandas': ", count())
Output with pandas 2.3.3:
ignore PerformanceWarning: {'FutureWarning': 2, 'SettingWithCopyWarning': 1}
+ ignore FutureWarning: {'SettingWithCopyWarning': 1}
+ module='pandas': {'SettingWithCopyWarning': 1}
Output with pandas 3.1.0:
ignore PerformanceWarning: {}
+ ignore FutureWarning: {}
+ module='pandas': {}
Filter on the class: pd.errors.PerformanceWarning, FutureWarning, and so on. Adding module="pandas" did nothing for the remaining SettingWithCopyWarning, because pandas reports warnings against your line (the /w/noisy.py:9: prefix in the -W output below), and module= matches that file, not the library that raised it.
3. Know the class hierarchy
import warnings
import pandas as pd
from noisy import noisy
for name in ["SettingWithCopyWarning", "ChainedAssignmentError",
"Pandas4Warning", "PandasChangeWarning"]:
cls = getattr(pd.errors, name, None)
print(name, "->", [c.__name__ for c in cls.__mro__[1:-2]] if cls else "not in this pandas")
warnings.simplefilter("always")
warnings.filterwarnings("ignore", category=pd.errors.PerformanceWarning)
warnings.filterwarnings("ignore", category=FutureWarning)
if hasattr(pd.errors, "SettingWithCopyWarning"):
warnings.filterwarnings("ignore", category=pd.errors.SettingWithCopyWarning)
with warnings.catch_warnings(record=True) as caught:
noisy()
print(len(caught), "warnings left")
Output with pandas 2.3.3:
SettingWithCopyWarning -> ['Warning', 'Exception']
ChainedAssignmentError -> ['Warning', 'Exception']
Pandas4Warning -> not in this pandas
PandasChangeWarning -> not in this pandas
0 warnings left
Output with pandas 3.1.0:
SettingWithCopyWarning -> not in this pandas
ChainedAssignmentError -> ['Warning', 'Exception']
Pandas4Warning -> ['PandasDeprecationWarning', 'PandasChangeWarning', 'DeprecationWarning', 'Warning', 'Exception']
PandasChangeWarning -> ['Warning', 'Exception']
0 warnings left
On pandas 2, SettingWithCopyWarning derives straight from Warning, so ignoring FutureWarning never touches it; filter it by name. On pandas 3 it no longer exists (guard with hasattr as above or your filter line raises AttributeError), and Pandas4Warning is a DeprecationWarning, not a FutureWarning, so ignore::FutureWarning does not hide it. The hasattr version silenced everything on both versions (0 left).
4. Silence one block only, and the chained_assignment option
import warnings
import pandas as pd
from noisy import noisy
with warnings.catch_warnings():
warnings.simplefilter("ignore")
noisy() # silent only inside the with block
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
noisy()
print(len(caught), "warnings after the block")
try:
pd.set_option("mode.chained_assignment", None)
print("chained_assignment option:", pd.get_option("mode.chained_assignment"))
except Exception as e:
print(type(e).__name__, e)
Output with pandas 2.3.3:
5 warnings after the block
chained_assignment option: None
Output with pandas 3.1.0:
/w/b3.py:12: Pandas4Warning: The 'mode.chained_assignment' option is deprecated. It has had no effect since pandas 3.0, which removed the SettingWithCopyWarning it controlled. Chained assignment now emits a ChainedAssignmentError warning instead; use warnings.filterwarnings with category=ChainedAssignmentError to silence or escalate it. This option will be removed in pandas 4.0.
pd.set_option("mode.chained_assignment", None)
/w/b3.py:13: Pandas4Warning: The 'mode.chained_assignment' option is deprecated. It has had no effect since pandas 3.0, which removed the SettingWithCopyWarning it controlled. Chained assignment now emits a ChainedAssignmentError warning instead; use warnings.filterwarnings with category=ChainedAssignmentError to silence or escalate it. This option will be removed in pandas 4.0.
print("chained_assignment option:", pd.get_option("mode.chained_assignment"))
2 warnings after the block
chained_assignment option: None
warnings.catch_warnings() restores the previous filters when the block ends, so the second run shows the warnings again; prefer it to a global filter at the top of the file. pd.set_option("mode.chained_assignment", None) was the old way to hide SettingWithCopyWarning. On pandas 3.1.0 it does nothing and itself emits a Pandas4Warning; the message says to filter ChainedAssignmentError instead.
5. From the command line: -W needs a message, not pandas.errors
python -W "ignore::FutureWarning" -W "ignore::pandas.errors.PerformanceWarning" -c "from noisy import noisy; noisy(); print('done')"
Output with pandas 2.3.3:
Invalid -W option ignored: invalid module name: 'pandas.errors'
/w/noisy.py:5: PerformanceWarning: DataFrame is highly fragmented. This is usually the result of calling `frame.insert` many times, which has poor performance. Consider joining all columns at once using pd.concat(axis=1) instead. To get a de-fragmented frame, use `newframe = frame.copy()`
df[f"c{i}"] = i # fragmented frame
/w/noisy.py:5: PerformanceWarning: DataFrame is highly fragmented. This is usually the result of calling `frame.insert` many times, which has poor performance. Consider joining all columns at once using pd.concat(axis=1) instead. To get a de-fragmented frame, use `newframe = frame.copy()`
df[f"c{i}"] = i # fragmented frame
/w/noisy.py:9: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
sub["a"] = 0 # chained assignment
done
Output with pandas 3.1.0:
Invalid -W option ignored: invalid module name: 'pandas.errors'
/w/noisy.py:5: PerformanceWarning: DataFrame is highly fragmented. This is usually the result of calling `frame.insert` many times, which has poor performance. Consider joining all columns at once using pd.concat(axis=1) instead. To get a de-fragmented frame, use `newframe = frame.copy()`
df[f"c{i}"] = i # fragmented frame
done
Python parses -W (and PYTHONWARNINGS) before pandas is imported, so it rejects the pandas class with Invalid -W option ignored and the PerformanceWarnings still print. Match the message text instead:
python -W "ignore:DataFrame is highly fragmented" -W "ignore::FutureWarning" -c "from noisy import noisy; noisy(); print('done')"
Output with pandas 2.3.3:
/w/noisy.py:9: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
sub["a"] = 0 # chained assignment
done
Output with pandas 3.1.0:
done
Related: all pandas 3 breaking changes · SettingWithCopyWarning · DataFrame is highly fragmented · to_datetime errors='ignore' deprecated.
Frequently asked questions
How do I turn off all pandas warnings?
warnings.simplefilter('ignore') inside a with warnings.catch_warnings(): block, or filterwarnings('ignore', category=...) per class. A global ignore also hides warnings about results that will change.
How do I suppress SettingWithCopyWarning?
On pandas 2, filterwarnings('ignore', category=pd.errors.SettingWithCopyWarning). pandas 3 removed the warning; the mode.chained_assignment option now only emits a Pandas4Warning.
Why does python -W ignore::pandas.errors.PerformanceWarning not work?
-W is parsed before pandas is imported, so Python reports Invalid -W option ignored. Use a message filter such as -W 'ignore:DataFrame is highly fragmented'.
Written with AI assistance. Measured on 2026-10-23 in the python:3-alpine Docker image (Python 3.14.7) with pandas 2.3.3 and pandas 3.1.0. Every block and command was run as shown; outputs pasted unedited. PlainTables is our extension; Python and pandas are free.