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.