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

結論から: 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つです。
Pandas4Warningが表示される。drop、rename、reset_index、set_index、sort_values、dropna、drop_duplicatesなどのinplace=Trueが対象です。修正は機械的で、df.drop(..., inplace=True)をdf = df.drop(...)に書き換えます。自分のコードではなく、使っているライブラリから警告が出ることも多いです。- 大きなローカルファイルの
pd.read_csvがかなり速くなる。 手元のテストでは 72 MB のファイルが pandas 3.0.1 の 0.23 秒から 3.1 では 0.02 秒になりました。ただし、よく使う引数のいくつかはこの高速化を無効にします。一覧は後述します。 - 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 読み込みの高速化、エラーを出さずに結果を変えてしまう挙動の確認、という順番で作業を進めます。
- pandas 3.1 アップグレード手順:inplace 非推奨の Pandas4Warning 対処と read_csv 高速化
- OpenCode 2.0 へのアップグレード方法:v1 の設定・プラグイン・セッションを移行する手順
- パワポでビフォーアフターを見せる方法|工数・コスト削減グラフ
- Python 3.15 アップグレード手順:uv でインストール、遅延インポート (lazy import) の使い方、pandas・PyTorch の対応状況
- Claude Code Mods 入門:最初の Mod の作り方・テスト・導入手順と、コミュニティ実例 15 選
- Laya の使い方:pandas でテキスト分類(Jev のオープンソース代替を4言語で実測)
- Claude Code が AGENTS.md を読むように:設定方法、4つの読み込みモード、Codex・OpenCode・Cursor との共用
- GPT Image 2.5の使い方:FlareとSunburstの違い・API料金
- DeepSeek Harness の使い方:インストール、初期設定、最初のエージェント実行まで
- Runcell Science:Claude Scienceのオープンソース代替となるAI研究ワークスペース
- Macをスリープさせない方法:Codex・Claude Codeを止めずに動かす
- OpenClaw vs ZeroClaw vs Pi Agent vs Nanobot: 2026年に選ぶべきAIエージェントスタックは?
- Claude CodeでJupyterノートブックを分析する方法|Data Science向けの実践ポイントと限界
- Claude Code Routinesとは?AIエージェントの定期実行と自動化を理解する
- Claude Code DesktopでBypass permissionsを有効にする方法
- GoogleのA2Aプロトコルで2つのPythonエージェントを構築する方法 - ステップバイステップチュートリアル
- 2025年のPythonで人気のあるトップ10のデータ可視化ライブラリ
ステップ1:pandas 3.1 をインストールする
要件(検証済み)
pandas 3.1.0 は CPython 3.11 から 3.15 までの wheel を提供しており(requires_python >= 3.11)、PyPI と conda-forge の両方にあります。必要な NumPy の下限は Python のバージョンによって変わります。
| Python | NumPy の最小バージョン |
|---|---|
| 3.11 – 3.13 | 2.0.2 |
| 3.14 – 3.15 | 2.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.pyinplace 以外も含めて、すべての 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.Pandas4WarningPandas4Warning は 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 などのプロジェクトが含まれます。
これらは自分のコードからは直せません。おすすめ順に選択肢を挙げます。
- ライブラリを更新する。 多くのプロジェクトは数日以内に修正版を出しています。
- この警告クラスだけを抑制する。 ライブラリが追いつくまでの間、すべての警告ではなくこのクラスだけを止めます。
import warnings
import pandas as pd
warnings.filterwarnings("ignore", category=pd.errors.Pandas4Warning)pandas<3.1に固定する。 メンテナンスされていないライブラリを動かす環境だけで行います。pandas 3.0 に永遠に固定しないでください。inplaceキーワードは 4.0 で削除されるので、この警告は猶予期間の通知です。
3.1 で出会うかもしれないその他の非推奨(注記のないものは検証済み)
| 警告が出るようになったコード | 置き換え |
|---|---|
s.dt.dayofweek, .dayofyear, .daysinmonth | s.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.values | ser.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.10assign と同じように、後ろの引数は同じ呼び出しの中で先に作った列を参照できます。
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 の比較
| 作業 | Polars | pandas 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 s | 1x |
pandas 3.1.0, mode.max_threads = 1(逐次) | 0.089 s | 2.6x |
| pandas 3.1.0, 2 スレッド | 0.049 s | 4.8x |
| pandas 3.1.0, 4 スレッド | 0.025 s | 9.3x |
| pandas 3.1.0, デフォルト(6 スレッド) | 0.018 s | 13x |
pandas 3.1.0, engine="pyarrow" | 0.030 s | 7.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 s | yes |
pd.read_csv("big.csv", usecols=["a", "c"]) | 0.079 s | no |
pd.read_csv("big.csv", index_col=0) | 0.091 s | no |
pd.read_csv("big.csv", nrows=1_000_000) | 0.032 s | no(逐次、ファイルの 3 分の 1) |
pd.read_csv("big.csv", converters={"b": int}) | 0.255 s | no(通常の読み込みより遅いが、3.0 で同じ呼び出しをするよりは速い) |
pd.read_csv(open("big.csv", "rb")) | 0.091 s | no(パスではなくファイルハンドル) |
pd.read_csv(io.StringIO(text)) | 0.131 s | no |
pd.read_csv("big.csv.gz") | 0.163 s | no(圧縮) |
pd.concat(pd.read_csv("big.csv", chunksize=500_000)) | 0.099 s | no |
pd.read_csv("big.csv", dtype={...}) | 0.034 s | yes(明示的な dtype は問題ない) |
pd.read_csv("big.csv", na_values=["z"]) | 0.025 s | yes |
実務上の結論は 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 goneC エンジンが、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 アップグレード手順 を参照してください。
関連ガイド
- Pandas read_csv() チュートリアル:pd.read_csv() の決定版ガイド
- Pandas で列を削除する方法
- Pandas で条件によって行を絞り込む方法
- Pandas で列名を変更する方法
- Polars と pandas の比較
- Python 3.15 アップグレード手順
- Python パッケージのアップグレード方法