Skip to content

pandas 3.1 アップグレード手順:inplace 非推奨の Pandas4Warning 対処、df.select() と pd.col() の使い方、read_csv 高速化の条件

更新日

pandas 3.1.0(2026年10月22日リリース)では drop、rename、sort_values など 11 メソッドの inplace=True が非推奨になり、pd.col() 式を使う DataFrame.select() と filter(cond=) が追加され、大きな CSV が並列で読み込まれます。macOS で実測:72 MB の CSV が 0.23 秒から 0.02 秒に。Pandas4Warning が出るメソッドの一覧、並列リーダーを無効にしてしまう read_csv の引数、Python 3.14 での NumPy 2.3.3 の落とし穴を解説します。

結論から: pandas 3.1.0 は 2026年10月22日にリリースされ、11月4日にはバグ修正版の 3.1.1 が出ました。3.1.1 に直接アップグレードしてください。

pip install --upgrade "pandas>=3.1"
# or, in a uv project
uv add "pandas>=3.1"

アップグレード後に起きることは3つです。

  1. Pandas4Warning が表示される。 drop、rename、reset_index、set_index、sort_values、dropna、drop_duplicates などの inplace=True が対象です。修正は機械的で、df.drop(..., inplace=True) を df = df.drop(...) に書き換えます。自分のコードではなく、使っているライブラリから警告が出ることも多いです。
  2. 大きなローカルファイルの pd.read_csv がかなり速くなる。 手元のテストでは 72 MB のファイルが pandas 3.0.1 の 0.23 秒から 3.1 では 0.02 秒になりました。ただし、よく使う引数のいくつかはこの高速化を無効にします。一覧は後述します。
  3. Polars 風の API が使える。 df.select("a", pd.col("b") * 2) と df.filter(pd.col("a") > 1) です。

まだ pandas 2.x を使っているなら、3.x への移行(Copy-on-Write、デフォルトの string dtype)のほうが大きな変更です。その場合は pandas 3.0 の移行ガイド (opens in a new tab) から始めてください。このガイドでは 3.0 → 3.1 の変更点と、実際にはまった落とし穴を扱います。

検証環境: 以下で「検証済み」とある内容は、2026年11月1日に Apple M4 Max(16 コア、macOS)上で、新規に作った uv 仮想環境の CPython 3.14.2、pandas 3.1.0、NumPy 2.5.4、PyArrow 26.0.0 を使って実行したものです。比較用の数値は、同じマシンの pandas 3.0.1、NumPy 2.4.2、PyArrow なしの環境で取りました。Windows、Linux、conda、Docker での挙動は公式ドキュメントに基づく情報で、ここでは検証していません。2026年11月4日には、検証済みの内容をすべて pandas 3.1.1 で再実行し、同じ結果を得ました。

3.1 で実際に気づく変更点

変更影響対応
inplace が非推奨(11 メソッド、PDEP-8)呼び出すたびに Pandas4Warning が出る。pandas 4.0 で削除される戻り値を再代入する:df = df.drop(...)
read_csv の並列化(ローカルの非圧縮ファイル、5 MB 以上)シングルスレッドで 2〜3 倍速く、さらにデフォルトで最大 6 スレッドを使う何もしなくてよい。ただし usecols、index_col、nrows、ファイルハンドルを渡すと無効になる(後述)
DataFrame.select()(3.0 から使える pd.col() 式を受け付ける)列の選択と計算を 1 回の呼び出しで行える。Polars 風任意。メソッドチェーンで便利
filter(cond=...) がブールマスクを受け付けるdf.filter(pd.col("a") > 1) で行を絞り込める注意:ブール値のリストを位置引数で渡すと、今までどおり ラベル の選択になる
NumPy 2.0.2 以上が必須(Python 3.14 では 2.3.3 以上)NumPy 1.x の環境には 3.1 をインストールできない先に NumPy を上げるか、pandas<3.1 に固定する
数値入力のデフォルトがマイクロ秒にpd.to_timedelta([1], unit="s") が timedelta64[s] ではなく timedelta64[us] になる3.0 の丸めバグの修正。特定の解像度が必要なら .as_unit() を使う
read_csv の dtype="category" が数値カテゴリを推論する郵便番号や ID の先頭のゼロが消えるその列は先に str で読み込む

変更点の全一覧は 公式の What's new in 3.1.0 (opens in a new tab) にあります。以下では、インストール、警告の修正、新 API の使い方、CSV 読み込みの高速化、エラーを出さずに結果を変えてしまう挙動の確認、という順番で作業を進めます。

トレンド記事

ステップ1:pandas 3.1 をインストールする

要件(検証済み)

pandas 3.1.0 は CPython 3.11 から 3.15 までの wheel を提供しており(requires_python >= 3.11)、PyPI と conda-forge の両方にあります。必要な NumPy の下限は Python のバージョンによって変わります。

PythonNumPy の最小バージョン
3.11 – 3.132.0.2
3.14 – 3.152.3.3

whatsnew のページには 2.0.2 しか書かれていません。Python 3.14 では wheel のメタデータが 2.3.3 を要求し、リゾルバーはそれを強制します。NumPy 1.x を固定していると、インストール自体が失敗します。

  × No solution found when resolving dependencies:
  ╰─▶ Because pandas==3.1.1 depends on numpy>=2.3.3 and you require
      pandas==3.1.1, we can conclude that you require numpy>=2.3.3.
      And because you require numpy<2, we can conclude that your requirements
      are unsatisfiable.

依存パッケージがまだ numpy<2 を固定しているなら、アップグレードを止めているのは pandas ではなくそのパッケージです。そのパッケージを更新するか、対応が出るまで pandas<3.1 のままにします。

アップグレード(uv で検証済み)

3.1.0 ではなく 3.1.1 を入れてください。3.1.1 では、read_csv と to_csv が pytest の tmpdir のようなパスオブジェクトを開いたファイルハンドルとして扱い、エラーになったり不完全なファイルを書き出したりするリグレッションが修正されています(What's new in 3.1.1 (opens in a new tab))。

# pip
pip install --upgrade "pandas>=3.1,<3.2"
 
# uv project
uv add "pandas>=3.1,<3.2"
 
# uv, throwaway environment to test first
uv venv p31 --python 3.14
uv pip install --python p31/bin/python "pandas==3.1.1" pyarrow
p31/bin/python -c "import pandas as pd; print(pd.__version__)"

conda-forge には 3.1.1 があります(2026年11月4日に確認。conda install -c conda-forge "pandas>=3.1")。ここでは未検証です。

PyArrow がまだ入っていなければ、あわせてインストールしてください。pandas 3 は PyArrow があればデフォルトの string dtype にそれを使い、engine="pyarrow" の CSV リーダーにも必要です。

ステップ2:inplace の Pandas4Warning を修正する

アップグレード後、次のようなコードは

df.drop(columns=["rain"], inplace=True)

こう表示します。

Pandas4Warning: The inplace keyword in DataFrame.drop is deprecated and will be removed in a future version (PDEP-8).
See https://pandas.pydata.org/docs/dev/whatsnew/v3.1.0.html#deprecation-inplace for more details.

対象になるメソッド(検証済み)

非推奨になったのは、inplace=True を指定しても値をその場で変更していなかったメソッドです。dropna、sort_values など行を並べ替えるメソッドでは内部的に常に再代入でした。drop、rename、set_index がかつて避けていたコピーも、pandas 3.0 で入った Copy-on-Write のもとではもともと発生しません。

メソッド3.1 での inplace修正
drop, rename, rename_axis非推奨df = df.drop(...)
reset_index, set_index非推奨df = df.reset_index()
sort_values, sort_index非推奨df = df.sort_values("col")
dropna, drop_duplicates非推奨df = df.dropna()
eval, query非推奨df = df.query("a > 1")
fillna, replace, where, mask, clip, interpolate維持(値をその場で更新できるため)変更不要

手元のテストでは、非推奨の 11 メソッドすべてが inplace=True で警告を出しました。fillna と replace はドキュメントどおり警告を出しませんでした。

書き換えは、呼び出し 1 つにつき 1 行の変更です。

# before
df.rename(columns={"temp": "temp_c"}, inplace=True)
df.sort_values("temp_c", inplace=True)
df.reset_index(drop=True, inplace=True)
 
# after (same cost, chains cleanly)
df = (
    df.rename(columns={"temp": "temp_c"})
      .sort_values("temp_c")
      .reset_index(drop=True)
)

コードベース内のすべての呼び出しを見つける(検証済み)

1 回だけ警告をエラーに変えて実行すると、トレースバックが該当行をそのまま指してくれます。ただし python -W は pandas.errors.Pandas4Warning のようなサードパーティのクラスを受け付けません。Invalid -W option ignored: invalid module name: 'pandas.errors' と表示したうえで、スクリプトをそのまま実行してしまいます。代わりにメッセージで照合します。

python -W "error:The inplace keyword:DeprecationWarning" your_script.py

inplace 以外も含めて、すべての Pandas4Warning をエラーにするには次のようにします。

python -c "import runpy, warnings, pandas as pd; warnings.simplefilter('error', pd.errors.Pandas4Warning); runpy.run_path('your_script.py', run_name='__main__')"

どちらも最初の inplace の行でトレースバックを出して終了します。メッセージで絞るフィルターは、関係のない非推奨警告には影響しません。

テストスイートの場合、pytest は pandas を import できる状態になってから -W フィルターを適用するので、クラス名がそのまま使えます。

pytest -W error::pandas.errors.Pandas4Warning

Pandas4Warning は PandasDeprecationWarning のサブクラスなので、どちらでフィルターしても効きます。grep でもほとんどの箇所は見つかります。

grep -rn "inplace=True" --include="*.py" --include="*.ipynb" .

警告が自分のコードではなくライブラリから出る場合

リリース直後の数週間はこれが一番よくあるケースです。2026年10月22日から11月1日の間に、GitHub では Pandas4Warning に言及する issue と pull request が約 300 件、「pandas 3.1」に言及するものが約 3,500 件増えました。yfinance(8 ファイルに 29 箇所の inplace 呼び出し、yfinance #3009 (opens in a new tab)。11月3日の yfinance 1.8.0 で修正済み)、FLAML、marimo、cuDF、darts、category_encoders などのプロジェクトが含まれます。

これらは自分のコードからは直せません。おすすめ順に選択肢を挙げます。

  1. ライブラリを更新する。 多くのプロジェクトは数日以内に修正版を出しています。
  2. この警告クラスだけを抑制する。 ライブラリが追いつくまでの間、すべての警告ではなくこのクラスだけを止めます。
import warnings
import pandas as pd
 
warnings.filterwarnings("ignore", category=pd.errors.Pandas4Warning)
  1. pandas<3.1 に固定する。 メンテナンスされていないライブラリを動かす環境だけで行います。pandas 3.0 に永遠に固定しないでください。inplace キーワードは 4.0 で削除されるので、この警告は猶予期間の通知です。

3.1 で出会うかもしれないその他の非推奨(注記のないものは検証済み)

警告が出るようになったコード置き換え
s.dt.dayofweek, .dayofyear, .daysinmonths.dt.day_of_week, .day_of_year, .days_in_month
文字列列に対する df.select_dtypes(include="object")(3.0 から警告が出ていた。3.1 で exclude="object" も対象に)"str" を明示する。pandas 3 では "object" は「テキスト」を意味しない
float 列に対する s.fillna("missing")先に共通の dtype にキャストする。将来のバージョンではエラーになる
タイムゾーン付きの列に対する ser.valuesser.array、ser.to_numpy()、または以前の UTC 配列を保つなら ser.dt.tz_convert(None).to_numpy()
pd.infer_freq(idx) が "D" を返すオフセットオブジェクトを返すようになる。.freqstr を使うか future.infer_freq_returns_offset を設定する
read_parquet(engine="fastparquet")(ドキュメントより)fastparquet は廃止。デフォルトの PyArrow エンジンを使う
pd.set_eng_float_format()(ドキュメントより)pd.set_option("display.precision", n)

ステップ3:df.select()、pd.col()、filter(cond=) を使う

3.1 で目に見える新 API は DataFrame.select() と filter(cond=) です。pd.col() 自体は pandas 3.0 で assign() と .loc 用に入ったもので、3.1 ではこの 2 つの新メソッドに渡す引数として自然に使えるようになりました。Polars を使ったことがあれば、見慣れた形でしょう。

select は列の選択と計算を 1 回で行う(検証済み)

import pandas as pd
 
df = pd.DataFrame({
    "city": ["Tokyo", "Seoul", "Osaka"],
    "temp": [18.2, 15.1, 19.5],
    "rain": [12, 30, 8],
})
 
df.select("city", "temp")                         # same as df[["city", "temp"]]
df.select("city", temp_f=pd.col("temp") * 1.8 + 32)   # keyword names the new column
    city  temp_f
0  Tokyo   64.76
1  Seoul   59.18
2  Osaka   67.10

assign と同じように、後ろの引数は同じ呼び出しの中で先に作った列を参照できます。

df.select(temp_c=pd.col("temp"), temp_f=pd.col("temp_c") * 1.8 + 32)

pd.col("temp") は pandas.api.typing.Expression です。Series に対して使う演算子やアクセサーをサポートしており、.str や .round() も使えます。

df.select(pd.col("city").str.upper(), pd.col("temp").round(0))

はまった点が 3 つあります(検証済み)。

  • .alias() はありません。 計算した列に名前を付けるにはキーワード形式(temp_f=...)を使います。pd.col("temp").alias("x") は式を作る時点ではエラーになりませんが、df.select(...) を実行すると AttributeError: 'Series' object has no attribute 'alias' で失敗します。
  • pd.col("temp").mean() のようにスカラーに縮約される式は、キーワード引数(mean_temp=pd.col("temp").mean())で渡す必要があります。その場合は全行にブロードキャストされます。位置引数で渡すと TypeError になります。
  • 存在しない列は KeyError になります。df[["nope"]] と同じです。

filter(cond=) はブールマスクで行を残す(検証済み)

DataFrame.filter はこれまで ラベル の選択専用でした(items=、like=、regex=)。3.1 ではマスクも受け付けます。

df.filter(cond=df["temp"] > 17)          # a boolean Series
df.filter(pd.col("temp") > 17)           # an expression, positional is fine
df.filter(lambda d: d["rain"] < 20)      # a callable

チェーンすると Polars のように読めますが、中身は pandas の DataFrame のままです。

(
    df.filter(pd.col("rain") < 20)
      .select("city", "temp")
      .sort_values("temp")
)

マスク内の欠損値はデフォルトで False として扱われます。残したい場合は na=True、エラーにしたい場合は na="raise" を渡します。

落とし穴: ブール値だけのリストを位置引数で渡すと、今までどおり ラベル の経路に入ります。手元のテストでは df.filter([True, False, True]) が 列ゼロ の DataFrame を返し、cond= を使うようにという UserWarning が出ました。マスクがリストや配列のときは必ず cond= を書いてください。

Polars と pandas 3.1 の比較

作業Polarspandas 3.1
列を選ぶdf.select("a", "b")df.select("a", "b")
列を計算するdf.select(pl.col("a") * 2)df.select(pd.col("a") * 2)
名前を付ける(pl.col("a") * 2).alias("a2")df.select(a2=pd.col("a") * 2)
行を絞るdf.filter(pl.col("a") > 1)df.filter(pd.col("a") > 1)
集約するdf.select(pl.col("a").mean()) → 1 行df.select(m=pd.col("a").mean()) → 全行にブロードキャスト

pandas が Polars になるわけではありません。select の裏に遅延評価もクエリオプティマイザーもありません。チェーンを読みやすくし、DataFrame 名の繰り返しを避けるための構文です。エンジンの乗り換えを検討しているなら、Polars と pandas の比較 がその判断を扱っています。

ステップ4:速くなった read_csv を使い、何が無効にするかを知る

ベンチマーク(検証済み)

ファイルは 1 つ:3,000,000 行 × 3 列(float、int、string)、72.5 MB、非圧縮、ローカル SSD 上。3 回実行した最良値です。

リーダー時間pandas 3.0.1 比
pandas 3.0.1, engine="c"0.233 s1x
pandas 3.1.0, mode.max_threads = 1(逐次)0.089 s2.6x
pandas 3.1.0, 2 スレッド0.049 s4.8x
pandas 3.1.0, 4 スレッド0.025 s9.3x
pandas 3.1.0, デフォルト(6 スレッド)0.018 s13x
pandas 3.1.0, engine="pyarrow"0.030 s7.8x

逐次の行はリリースノートの「2〜3 倍速い」と一致します。並列の行はその上に積み上がります。ファイルによって結果は変わります(文字列列が多いとパースは遅くなります)が、ポイントは結果の形です。デフォルトの engine="c" リーダーは、普通のローカルファイルに対しては PyArrow より速くなりました。

条件(ドキュメントより。上の計測で確認)

並列の経路は、次のすべてが満たされたときに自動で使われます。

  • filepath_or_buffer が ローカルの非圧縮ファイルのパス である
  • デフォルトの C エンジン を使っている
  • データ行の合計が 5 MB 以上 である
  • mode.max_threads が 1 より大きい(デフォルト:CPU 数、上限 6。プロセスが 1 CPU に制限されている場合は 1)
  • ファイル全体を一度に必要とするオプションがない:iterator、chunksize、nrows、usecols、index_col、parse_dates、リストまたは callable の skiprows、複数行ヘッダー、UTF-8 以外のエンコーディング

これ以外はすべて逐次リーダーにフォールバックします。結果は常に逐次読み込みと同一です。

手元のテストでの結果(検証済み)

呼び出し時間並列?
pd.read_csv("big.csv")0.018 syes
pd.read_csv("big.csv", usecols=["a", "c"])0.079 sno
pd.read_csv("big.csv", index_col=0)0.091 sno
pd.read_csv("big.csv", nrows=1_000_000)0.032 sno(逐次、ファイルの 3 分の 1)
pd.read_csv("big.csv", converters={"b": int})0.255 sno(通常の読み込みより遅いが、3.0 で同じ呼び出しをするよりは速い)
pd.read_csv(open("big.csv", "rb"))0.091 sno(パスではなくファイルハンドル)
pd.read_csv(io.StringIO(text))0.131 sno
pd.read_csv("big.csv.gz")0.163 sno(圧縮)
pd.concat(pd.read_csv("big.csv", chunksize=500_000))0.099 sno
pd.read_csv("big.csv", dtype={...})0.034 syes(明示的な dtype は問題ない)
pd.read_csv("big.csv", na_values=["z"])0.025 syes

実務上の結論は 2 つです。

  • usecols は読み込みを速くするどころか遅くすることがある。 長年「不要な列は usecols で飛ばせ」と言われてきました。3.1 では、5 MB 以上のローカルファイルを全列並列で読んでから列を落とすほうが、手元のテストでは usecols より 4 倍速かったです。昔の習慣を続ける前に計測してください。
  • ハンドルではなくパスを渡す。 pd.read_csv("file.csv") は並列になりますが、pd.read_csv(open("file.csv")) はなりません。パスではなく開いたファイルオブジェクトを pandas に渡すラッパーは、この高速化を失います。

すでに並列化されたアプリケーションの中では抑える

pandas を Dask、Ray、multiprocessing のプール、あるいは全コアを使っている Web ワーカーの中で動かす場合は、スレッド数に上限を付けて競合を避けます。

import pandas as pd
 
with pd.option_context("mode.max_threads", 1):
    df = pd.read_csv("large.csv")
 
# or globally
pd.set_option("mode.max_threads", 2)

Docker と Kubernetes では、上限は cgroup の CPU クォータに従います(ドキュメントより、ここでは未検証)。1 CPU に制限されたコンテナでは、何もしなくても逐次で読み込まれます。

ステップ5:エラーを出さない挙動の変更を確認する

結果を静かに変えてしまう可能性が最も高い変更です。それぞれ 3.0.1 と 3.1.0 で再現しました(検証済み)。

数値からの Timedelta と datetime がデフォルトでマイクロ秒になる

3.0 では pd.to_timedelta([1], unit="s") が timedelta64[s] を生成し、演算もその解像度を維持していました。割り算の結果は秒単位に丸められていました。

td = pd.to_timedelta([1], unit="s")
print(td / 3)
# pandas 3.0.1 → TimedeltaIndex(['0 days'], dtype='timedelta64[s]', freq=None)
# pandas 3.1.x → TimedeltaIndex(['0 days 00:00:00.333333'], dtype='timedelta64[us]', freq=None)

3.1 では、変換に使った unit に関係なくデフォルトでマイクロ秒になり、この問題が直りました。dtype を比較していたり [s] の解像度に依存していたコードは、.as_unit("s") を明示してください。数値入力の Timestamp と to_datetime も同じように変わりました。

関連:Timedelta.total_seconds() がナノ秒を含むようになりました。pd.Timedelta(nanoseconds=1500).total_seconds() は 1e-06 ではなく 1.5e-06 を返します。

read_csv の dtype="category" が数値カテゴリを推論する

from io import StringIO
data = "zip\n00501\n00501\n10001"
 
pd.read_csv(StringIO(data), dtype="category")["zip"].cat.categories.tolist()
# pandas 3.0.1 → ['00501', '10001']
# pandas 3.1.0 → [501, 10001]        leading zeros gone

C エンジンが、PyArrow エンジンがすでにしていたことをするようになりました。郵便番号、口座番号、ゼロ埋めされた識別子は、列を str で読み込んでから変換します。

df = pd.read_csv("file.csv", dtype={"zip": "str"})
df["zip"] = df["zip"].astype("category")

以前は静かに通っていたが、今はエラーになるもの

  • pd.Timestamp(datetime(2020, 12, 31), hour=5) は手元のテストで ValueError になりました。3.0 では hour を黙って無視していました。すべての要素をキーワードで渡してください。
  • pd.to_timedelta("3:25:00 PM") はエラーになります。3.0 では 3 時間としてパースし、PM を捨てていました。
  • DataFrame と category 型の Series の算術演算と順序比較を、デフォルトの axis="columns" 方向で行う場合(例:df + cat_series)、カテゴリに対して演算する代わりに TypeError を投げるようになりました。等値比較は変わりません(ドキュメントより、手元でも再現)。
  • Index.values と Index.array は読み取り専用の配列を返します。これらを通してインデックスを変更していたコードは、ルックアップを壊すのではなく明示的に失敗します(ドキュメントより)。

PyArrow ベースの文字列に対する正規表現(検証済み)

PyArrow が入っている環境では、pandas 3.0 の .str.replace、.str.count などで \w、\d、\s、\b が ASCII にしかマッチしませんでした。3.1 では Python の re や pandas 2.x と同じく Unicode にマッチします。PyArrow 26.0.1 で pd.Series(["héllo wörld", "naïve 東京"]).str.count(r"\w") を実行すると、pandas 3.0.6 では [8, 4]、3.1.1 では [10, 7] が返りました。英語以外のテキストを処理していて 3.0 に移ってからカウントが減ったなら、これが修正です。3.1.1 では、PyArrow の文字列で \s が \x0b と \x1c にマッチしない問題も直っています。

今アップグレードすべきか

状況おすすめ
新規プロジェクト、Python 3.11 以上する。3.1 から始めて、inplace を使わずに書く
3.0 で動いているスクリプトとノートブックする。1 回 -W "error:The inplace keyword:DeprecationWarning"(または pytest -W error::pandas.errors.Pandas4Warning)で実行して該当行を直し、速くなった CSV 読み込みはそのまま活かす
dtype="category" でゼロ埋め ID を読み込むライブラリやパイプラインアップグレードするが、先に dtype={"id": "str"} を追加する
FLAML、darts などに依存しているそれらが 3.1 対応版を出してからアップグレードする(yfinance は 1.8.0 で対応済み)。それまでは Pandas4Warning をフィルターする
まだ pandas 2.x先に 2 → 3 の移行(Copy-on-Write、string dtype)をする。3.1 はその上の小さな変更
まだ NumPy 1.x不可。先に NumPy を上げる

Jupyter で pandas 3.1 を使う

ノートブック自体で変わることはありません。注意点は 2 つです。

  • -W error はコマンドラインのフラグで、動いているカーネルには効きません。修正作業中は最初のセルに warnings.simplefilter("error", pd.errors.Pandas4Warning) を書き、終わったら消します。
  • 並列 CSV リーダーにフリースレッド版 Python は不要です。通常のインタープリターで動きます。

大きなファイルが一瞬で読み込めるようになると、遅いのはそれを眺める作業のほうです。PyGWalker (opens in a new tab) 0.5.0.1 は手元のテストで pandas 3.1 上で動きました(pyg.to_html(df) で 50,000 行のフレームを 0.23 秒で描画)。groupby のコードを書く前に、読み込んだ直後の DataFrame をドラッグ&ドロップで一通り眺めるのは、次のステップとして妥当です。

トラブルシューティング

ResolutionImpossible / "requires numpy>=2.3.3" — Python 3.14 か 3.15 で古い NumPy を固定しています。NumPy を上げるか、固定を緩めてください。Python 3.11〜3.13 では下限は 2.0.2 です。

site-packages から何百行も Pandas4Warning が出る — 自分のコードではなく依存パッケージです。更新してください。まだ修正がなければ warnings.filterwarnings("ignore", category=pd.errors.Pandas4Warning) を入れ、トレースバックを付けて issue を立てます。

read_csv が速くならない — ステップ 4 の一覧を確認してください。よくある原因は usecols、index_col、圧縮ファイル、パスではなくファイルオブジェクトです。pd.get_option("mode.max_threads") が 1 になっていないことも確認します(デフォルトは None で、「自動」を意味します)。

df.filter([...]) が列を返さない — ブール値のリストを位置引数で渡しています。df.filter(cond=[...]) を使ってください。

AttributeError: 'Series' object has no attribute 'alias' — pd.col の式には使える alias がありません。select のキーワード形式で列に名前を付けます。

郵便番号の先頭のゼロが消えた — dtype="category" が整数を推論するようになりました。先に str で読み込みます。

Timedelta の dtype が [s] から [us] に変わった — 3.1 では想定どおりです。下流のシステムが秒を必要とするなら .as_unit("s") を使います。

よくある質問

Pandas4Warning とは何ですか?どう直せばいいですか?

pandas 3.1 が、4.0 で変わる挙動に対して出す非推奨警告です。最も多いのは drop、rename、reset_index、set_index、sort_values、dropna、drop_duplicates の inplace=True です。代わりに戻り値を再代入します:df = df.drop(columns=["a"])。python -W "error:The inplace keyword:DeprecationWarning" your_script.py(テストスイートなら pytest -W error::pandas.errors.Pandas4Warning)を実行すると、残っている最初の呼び出しでトレースバック付きで止まります。直したら再実行してください。

pandas 3.1 で inplace=True は削除されましたか?

いいえ。3.1 でも動作し、警告が表示されます。削除は pandas 4.0 の予定で、対象は実際にはその場でデータを変更していなかったメソッドだけです。fillna、replace、where、mask、clip、interpolate ではキーワードが維持されます。

read_csv が速くなったのはなぜですか?自分の環境で速くならないのはなぜですか?

C エンジンが 2〜3 倍速くなり、大きなローカルファイルはデフォルトで並列に読み込まれます。変化がないなら、おそらく usecols、index_col、nrows、chunksize、圧縮ファイル、開いたファイルオブジェクトのどれかを渡しています。ステップ 4 の表を確認してください。

df.select() は Polars の select と同じですか?

構文は意図的に似せてありますが、pandas は即時評価で、クエリオプティマイザーはありません。性能のためではなく、チェーンを読みやすくするために使ってください。

pandas 3.1 は Python 3.15 で動きますか?

動きます。wheel は CPython 3.11 から 3.15 まで公開されています。3.14 と 3.15 では NumPy 2.3.3 以上が必要です。Python 側のアップグレードについては Python 3.15 アップグレード手順 を参照してください。

関連ガイド