pandasをインストールする
ターミナルでpip installコマンドを使ってpandasをインストールします。pandas 3はPython 3.11以降が必要です。古いPythonでは、そのバージョンがサポートする最新のpandas 2.xがインストールされます。
pip install pandas
あるいは、conda経由でインストールすることもできます。
conda install pandas
インストール後、他パッケージとの互換性確認のためにも、バージョンを表示して動作確認しておくとよいでしょう。
import pandas as pd
print(pd.__version__) # Prints the pandas version
これでpandasが正しく導入されたことが確認でき、他パッケージとの互換性も検証できます。
pandas 3.0と3.1の変更点
2026年1月リリースのpandas 3.0では、コピー、文字列、代入の挙動が変わり、pandas 3.1(2026年10月)では多くのinplace=Trueの使い方が非推奨になりました。古いチュートリアルのコードの多くはそのまま動きますが、特につまずきやすい変更点は次の4つです。
- Copy-on-Writeがデフォルト。 任意の部分集合やメソッド結果はコピーとして振る舞い、変更しても元のDataFrameは変わりません。
SettingWithCopyWarningは消え、防御的な.copy()呼び出しも不要です。 - 連鎖代入は機能しません。
df["Age"][0] = 35は一時的なコピーを更新するだけでdfは変わらず、ChainedAssignmentErrorで警告されます。代わりに1回の.loc[]呼び出しを使います。 - 文字列に専用のデータ型。 テキスト列は
objectではなくstrとして推論され、PyArrowがインストールされていればそれを基盤にします。 inplace=Trueが非推奨。sort_values()、reset_index()、dropna()、drop_duplicates()、rename()などで非推奨になりました。代わりに結果を再代入します(例:df = df.dropna())。

以下は小さなDataFrameでの連鎖代入の変更例です。
import pandas as pd
patients = pd.DataFrame({"name": ["Ana", "Ben", "Chloe"], "age": [34, 51, 28]})
patients["age"][0] = 35 # chained assignment: patients is not changed
patients.loc[0, "age"] = 35 # a single .loc[] call: patients is updated
print(patients.dtypes)
name str
age int64
dtype: object
本チュートリアルのすべての例はpandas 3のルールに従っています。変更点の全リストは、公式リリースノートpandas 3.0とpandas 3.1をご覧ください。古いコードを保守している場合は、Copy-on-Writeに置き換えられた挙動を解説するSettingWithCopyWarningガイドが参考になります。
pandasでのデータのインポート
まず、以下のようにpandasをインポートします。pandasの一般的なエイリアスはpdです。
import pandas as pd
CSVファイルのインポート
カンマ区切り値ファイルはread_csv()にパスを渡して読み込みます(詳細はread_csv()でのインポートチュートリアルを参照)。
df = pd.read_csv("diabetes.csv")
この読み込みはdiabetes.csvをpandasのDataFramedfにロードします。本チュートリアルではPima Indians Diabetesデータセットを使用します。768人の患者、Glucose、BMI、Ageなど8つの健康指標、そして糖尿病診断を示すOutcome(1が診断あり)列を含みます。
テキストファイルのインポート
テキストファイルの読み込みはCSVと同様ですが、sep引数で区切り文字を指定する点が異なります。区切り文字は各行で値(列)を分ける文字です。よく使われるのはカンマ(sep=",")、タブ(sep="\t")、コロン(sep=":")、空白(sep=r"\s+")です。r"\s+"は1つ以上の空白文字にマッチする正規表現で、r接頭辞により生文字列として扱われ、Pythonが\sを無効なエスケープとして扱いません。
df = pd.read_csv("diabetes.txt", sep=r"\s+")
Excelファイルのインポート(単一シート)
read_excel()でファイルパスを渡して読み込みます。pandasでExcelを扱うには追加エンジンが必要です。.xlsxはopenpyxl、レガシーな.xlsはxlrdをインストールしてください。
df = pd.read_excel('diabetes.xlsx')
headerでヘッダー行(列名となる行)を指定できます。デフォルトは0(最初の行)。列名をnamesにリストで渡すこともできます。ファイルに行インデックスが含まれる場合はindex_col(デフォルトNone)を使います。
注: pandasのDataFrameやSeriesでは、インデックスは行や列の位置を指す識別子です。要するに、インデックスはDataFrameの行や列にラベルを付け、インデックスを使って特定の行・列にアクセスできます(後ほど登場)。行インデックスは範囲(例:0〜303)、時系列(日付やタイムスタンプ)、一意ID(例:employeesテーブルのemployee_ID)など様々です。列のインデックス(列名)は通常は文字列です。
Excelファイルのインポート(複数シート)
複数シートの読み込みもほぼ同様で、追加のsheet_name引数を指定します。シート名の文字列か、位置の整数を渡せます(Pythonは0始まりなので、先頭シートはsheet_name = 0)。
# Pythonは0始まりなので2番目のシートを抽出
df = pd.read_excel('diabetes_multi.xlsx', sheet_name=1)
JSONファイルのインポート
read_csv()と同様に、JSONはread_json()で読み込みます(詳細はJSONとHTMLのインポートを参照)。以下はディスク上のJSONを読み込んでDataFramedfを作成します。
df = pd.read_json("diabetes.json")
pandasでのデータ読み込みをさらに学ぶには、Pythonでさまざまなファイルタイプをインポートするためのチートシートをご覧ください。
SQLデータベースからのインポート
リレーショナルデータベースからデータを読み込むには、pd.read_sql()とDB接続を使います。
import sqlite3
# SQLiteデータベースに接続
conn = sqlite3.connect("my_database.db")
# テーブルからデータを読み込む
df = pd.read_sql("SELECT * FROM my_table", conn)
PostgreSQLやMySQLなど他のDBでは、sqlite3接続の代わりにSQLAlchemyエンジンを渡します。大きなテーブルはchunksizeでバッチ読み込みにします。
API(JSON形式)からのインポート
Web APIからデータを取得する場合、pd.read_json()で直接読み込めます。
df = pd.read_json("https://api.example.com/data.json")
APIレスポンスが入れ子のJSONなら、pd.json_normalize()でフラット化し、入れ子のキーをドット区切りの列に展開します。
records = [
{"id": 1, "vitals": {"glucose": 148, "bmi": 33.6}},
{"id": 2, "vitals": {"glucose": 85, "bmi": 26.6}},
]
pd.json_normalize(records)
id vitals.glucose vitals.bmi
0 1 148 33.6
1 2 85 26.6
pandasでのデータのエクスポート
pandasは多様な形式へのエクスポートも可能です。pandasで変換したデータをローカルへ保存する場面で使用します。以下にDataFrameの主な出力方法を示します。
DataFrameをCSVに出力
pandas DataFrame(ここではdf)は.to_csv()でCSVに保存します。ファイルパスを渡し、行インデックスが不要ならindex=Falseを指定します(デフォルトのindex=Trueだと、無名列として追加されます)。その他の引数はCSVに保存するチュートリアルを参照してください。
df.to_csv("diabetes_out.csv", index=False)
DataFrameをJSONに出力
.to_json()でDataFrameをJSONファイルにエクスポートします。
df.to_json("diabetes_out.json")
注: JSONはDataFrameのような表をキーと値の組で保存するため、列名が繰り返し現れます。
DataFrameをテキストに出力
CSV出力と同様に.to_csv()を使いますが、拡張子を.txtにし、sepで区切り文字を指定します。
df.to_csv('diabetes_out.txt', header=df.columns, index=None, sep=' ')
DataFrameをExcelに出力
.to_excel()で.xlsxとして保存します(openpyxlが必要)。レガシーな.xlsには出力できなくなりました。
df.to_excel("diabetes_out.xlsx", index=False)
pandasでのDataFrameの確認と理解
表データをDataFrameとして読み込んだら、まず中身をざっと確認します。データセットの一部や要約統計で概要を掴めます。
データの閲覧:.head()と.tail()
先頭・末尾の数行は、それぞれ.head()・.tail()で閲覧できます。n引数で行数を指定します(デフォルトは5)。
df.head()

DataFrameの先頭5行
df.tail(n = 10)

DataFrameの末尾10行
データの把握:.describe()
.describe()は数値列の要約統計(件数、平均、標準偏差、範囲、四分位数など)を表示します。
df.describe()

.describe()で要約統計を取得
これにより、数値データのスケール、歪度、範囲を素早く把握できます。
percentiles引数で四分位点を変更できます。例えば、DataFramedfの数値列について、30%、50%、70%点を表示します。
df.describe(percentiles=[0.3, 0.5, 0.7])

特定パーセンタイルでの要約統計
include引数で、出力するデータ型を限定できます。例えば、integer型の列のみを要約します。
df.describe(include=[int])

整数列のみの要約統計
同様に、exclude引数で特定の型を除外することもできます。
df.describe(exclude=[int])
BMI DiabetesPedigreeFunction
count 768.000000 768.000000
mean 31.992578 0.471876
std 7.884160 0.331329
min 0.000000 0.078000
25% 27.300000 0.243750
50% 32.000000 0.372500
75% 36.600000 0.626250
max 67.100000 2.420000
これらの統計は、.Tで転置すると見やすくなることがよくあります。
df.describe().T

.Tで要約統計を転置
DataFrameの記述に関する詳細は、以下のチートシートを参照してください。
.info()でデータを把握する
.info()は、DataFrameのデータ型、欠損数、データサイズを素早く確認する方法です。ここではshow_countsをTrueにして各列の非欠損数を表示し、memory_usageをTrueにして合計メモリ使用量も表示しています。verboseをTrueにすると.info()の完全な要約が出力されます。
df.info(show_counts=True, memory_usage=True, verbose=True)
<class 'pandas.DataFrame'>
RangeIndex: 768 entries, 0 to 767
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Pregnancies 768 non-null int64
1 Glucose 768 non-null int64
2 BloodPressure 768 non-null int64
3 SkinThickness 768 non-null int64
4 Insulin 768 non-null int64
5 BMI 768 non-null float64
6 DiabetesPedigreeFunction 768 non-null float64
7 Age 768 non-null int64
8 Outcome 768 non-null int64
dtypes: float64(2), int64(7)
memory usage: 54.1 KB
.shapeで行数・列数を確認
DataFrameの行数・列数は.shape属性で取得できます。戻り値は(行, 列)のタプルで、インデックス指定で行数・列数だけ取り出せます。
df.shape # 行数・列数
df.shape[0] # 行数のみ
df.shape[1] # 列数のみ
(768,9)
768
9
全ての列と列名を取得
DataFrameオブジェクトの.columns属性は、列名をIndexとして返します。pandasのインデックスは、行や列のアドレス/ラベルを指します。
df.columns
Index(['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI',
'DiabetesPedigreeFunction', 'Age', 'Outcome'],
dtype='str')
list()でリストに変換できます。
list(df.columns)
['Pregnancies',
'Glucose',
'BloodPressure',
'SkinThickness',
'Insulin',
'BMI',
'DiabetesPedigreeFunction',
'Age',
'Outcome']
.isnull()で欠損値を確認
サンプルDataFrameには欠損がありません。ここでは例として欠損を少し加えます。.copy()で元のDataFrameのコピーを作り、以降の例に備えて元のdfを保ちます。.loc(後述)で、Pregnancies列のラベル2〜5の行を欠損に設定します。欠損値はNaN(float)で保存されるため、列の型はint64からfloat64に変わります。
df2 = df.copy()
df2.loc[2:5,'Pregnancies'] = None
df2.head(7)

2〜5行がNaNになっているのがわかります
各要素が欠損かどうかは.isnull()で確認できます。
df2.isnull().head(7)
どの程度欠損があるかを知るには、.isnull()と.sum()を組み合わせて列ごとの欠損数を数えます。
df2.isnull().sum()
Pregnancies 4
Glucose 0
BloodPressure 0
SkinThickness 0
Insulin 0
BMI 0
DiabetesPedigreeFunction 0
Age 0
Outcome 0
dtype: int64
さらに合計の欠損数は二重に合計すれば取得できます。
df2.isnull().sum().sum()
4
pandasでの並べ替え、スライス、抽出
pandasは、DataFrame内のデータを並べ替え、部分集合化、フィルタ、抽出する複数の方法を提供します。ここでは最も一般的な方法を見ていきます。
並べ替え
特定の列で並べ替えるには.sort_values()を使います。これは新しいソート済みDataFrameを返し、dfはそのままなので、保持したい場合は結果を変数に代入します。
df.sort_values(by="Age", ascending=False) # Ageで降順
複数列での並べ替えも可能です。
df.sort_values(by=["Age", "Glucose"], ascending=[False, True])
インデックスのリセット
並べ替えやフィルタをしても元の行ラベルは保持されるため、インデックスが順序どおりでなくなることがあります。.reset_index()で0始まりの新しいインデックスにします(オプションはリセットのチュートリアル参照)。
df_sorted = df.sort_values(by="Age", ascending=False).reset_index(drop=True) # drop=Trueで旧インデックスを破棄
df_sorted[["Age", "Glucose", "Outcome"]].head(3)
Age Glucose Outcome
0 81 134 0
1 72 119 0
2 70 145 1
[ ]で1列を抽出
角括弧[ ]に列名を渡すと1列を抽出できます。出力はpandasのSeriesです。Seriesは1次元配列で、整数、浮動小数、文字列、ブール、Pythonオブジェクトなど任意の型を保持できます。DataFrameは複数のSeriesから構成されています。
df['Outcome']
0 1
1 0
2 1
3 0
4 1
..
763 0
764 0
765 0
766 1
767 0
Name: Outcome, Length: 768, dtype: int64
[[ ]]で複数列を抽出
列名のリストを角括弧内に渡して、2列以上を取得できます。ここでは外側の角括弧がDataFrameの部分集合、内側の角括弧がリスト生成を表します。
df[['Pregnancies', 'Outcome']]
Pregnancies Outcome
0 6 1
1 1 0
2 8 1
3 1 0
4 0 1
.. ... ...
763 10 0
764 2 0
765 5 0
766 1 1
767 1 0
[768 rows x 2 columns]
[ ]で1行を抽出
Trueが1つだけのブールSeriesを渡すと単一行を取得できます。以下はindex = 1の2行目を返します。.indexは行ラベルを返し、比較でブールの1次元配列に変換されます。
df[df.index==1]

pandasで1行を抽出
[ ]で複数行を抽出
同様に、==の代わりに.isin()を使えば2行以上を返せます。
df[df.index.isin(range(2,10))]

pandasで特定の行を抽出
.loc[]と.iloc[]で行を取得
行や列、セルをラベルまたは条件で取得するには.loc[]、位置で取得するには.iloc[]("location"と"integer location")を使います。違いの詳細はloc vs ilocガイドで解説しています。ここでは、先ほど作成したdf2のインデックスを変更して、ラベルと位置が一致しない状況を作ります。
![.loc[]はラベル、.iloc[]は位置で選択](https://media.datacamp.com/cms/pandas-02.png?w=802)
df2.index = range(1,769)
以下の例はDataFrameではなくpandasのSeriesを返します。.loc[1]では、1はラベルなのでラベル1(再インデックス後の先頭行)を返します。.iloc[1]では、1は0始まりの位置なので2行目を返し、そのラベルは2です。
df2.loc[1]
Pregnancies 6.000
Glucose 148.000
BloodPressure 72.000
SkinThickness 35.000
Insulin 0.000
BMI 33.600
DiabetesPedigreeFunction 0.627
Age 50.000
Outcome 1.000
Name: 1, dtype: float64
df2.iloc[1]
Pregnancies 1.000
Glucose 85.000
BloodPressure 66.000
SkinThickness 29.000
Insulin 0.000
BMI 26.600
DiabetesPedigreeFunction 0.351
Age 31.000
Outcome 0.000
Name: 2, dtype: float64
範囲を指定して複数行を取得することもできます。両者は範囲の終端の扱いが異なります。.loc[100:110]はラベル110を含み11行を返しますが、.iloc[100:110]は位置110の手前で止まり10行を返します。
df2.loc[100:110]

.loc[]で行を抽出
df2.iloc[100:110]
![.loc[]で行を抽出](https://media.datacamp.com/legacy/v1668597143/image28_07af2245c8.png?w=724)
.iloc[]で行を抽出
範囲の代わりにリストを使って抽出することもできます。
df2.loc[[100, 200, 300]]
![.loc[]でリスト指定して行を抽出](https://media.datacamp.com/legacy/v1668597142/image31_c5acf2a9bd.png?w=723)
.loc[]でリスト指定して行を抽出
df2.iloc[[100, 200, 300]]
![.iloc[]で位置100, 200, 300の行を選択](https://media.datacamp.com/legacy/v1668597142/image25_36fb2e17e1.png?w=802)
.iloc[]でリスト指定して行を抽出
行と同時に列を指定して抽出することも可能です。ここで.iloc[]は列のラベルではなく「位置」を要求する点が.loc[]と異なります。
df2.loc[100:110, ['Pregnancies', 'Glucose', 'BloodPressure']]
Pregnancies Glucose BloodPressure
100 1.0 122 90
101 1.0 163 72
102 1.0 151 60
103 0.0 125 96
104 1.0 81 72
105 2.0 85 65
106 1.0 126 56
107 1.0 96 122
108 4.0 144 58
109 3.0 83 58
110 0.0 95 85
df2.iloc[100:110, :3]
Pregnancies Glucose BloodPressure
101 1.0 163 72
102 1.0 151 60
103 0.0 125 96
104 1.0 81 72
105 2.0 85 65
106 1.0 126 56
107 1.0 96 122
108 4.0 144 58
109 3.0 83 58
110 0.0 95 85
より高速な操作には、開始インデックス以降を範囲指定する方法もあります。
df2.loc[760:, ['Pregnancies', 'Glucose', 'BloodPressure']]
Pregnancies Glucose BloodPressure
760 6.0 190 92
761 2.0 88 58
762 9.0 170 74
763 9.0 89 62
764 10.0 101 76
765 2.0 122 70
766 5.0 121 72
767 1.0 126 60
768 1.0 93 70
df2.iloc[760:, :3]
Pregnancies Glucose BloodPressure
761 2.0 88 58
762 9.0 170 74
763 9.0 89 62
764 10.0 101 76
765 2.0 122 70
766 5.0 121 72
767 1.0 126 60
768 1.0 93 70
.loc[]と代入演算子=の組み合わせで値を更新できます。更新対象と同じDataFrameから条件を作ってください。dfから作った条件は新しいdf2のインデックスと揃わず、pandasはエラーを出します。
df2.loc[df2["Age"] == 81, "Age"] = 80
条件で行をフィルタ
pandasでは行・列の値に基づく条件でフィルタできます。例えば、以下は血圧がちょうど122の行を選択します。角括弧[ ]で行を抽出するのは前節と同じですが、ここでは列BloodPressureが122に等しいという条件df.BloodPressure == 122を渡しています。
df[df.BloodPressure == 122]

条件で行を抽出
次の例はOutcomeが1の行をすべて取得します。df.Outcomeで列を選び、df.Outcome == 1でTrue/FalseのSeriesを作り、そのTrueの位置の行だけを[]で取り出します。
df[df.Outcome == 1]

条件で行を抽出
>演算子で比較もできます。以下はBloodPressureが100より大きいレコードについて、Pregnancies、Glucose、BloodPressureを取得します。
df.loc[df['BloodPressure'] > 100, ['Pregnancies', 'Glucose', 'BloodPressure']]
Pregnancies Glucose BloodPressure
43 9 171 110
84 5 137 108
106 1 96 122
177 0 129 110
207 5 162 104
362 5 103 108
369 1 133 102
440 0 189 104
549 4 189 110
658 11 127 106
662 8 167 106
672 10 68 106
691 13 158 114
pandasでのデータクレンジング
データクレンジングはデータサイエンスで最も一般的な作業の1つです。pandasは機械学習や深層学習の前処理に限らず、あらゆる用途に向けてデータを前処理できます。ここでは先ほどの欠損が4つあるdf2を使って、いくつかのクレンジング手法を示します。まず、DataFrame内の欠損数は次のように確認できます。
df2.isnull().sum()
Pregnancies 4
Glucose 0
BloodPressure 0
SkinThickness 0
Insulin 0
BMI 0
DiabetesPedigreeFunction 0
Age 0
Outcome 0
dtype: int64
手法1:欠損値を削除する
データ量が十分で、少しの欠損を落としても下流の分析に影響しない場合は削除が有効です。.dropna()を使います。ここでは.dropna()の結果をDataFramedf3に保存します。
df3 = df2.copy()
df3 = df3.dropna()
df3.shape
(764, 9) # df2より4行少ない
axis引数で削除対象を行か列か指定できます。デフォルトはNaNを含む行の削除です。axis = 1で1つ以上NaNを含む列を削除します。本チュートリアルの他の例と同様に、pandas 3.1で.dropna()のinplace=Trueは非推奨のため、結果を再代入しています。
df3 = df2.dropna(axis=1)
list(df3.columns)
['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI', 'DiabetesPedigreeFunction', 'Age', 'Outcome']
デフォルトの.dropna()は、1つでも欠損があれば行を削除します。howを'all'にすると、すべての値が欠損の行のみ削除します。df2には完全に空の行がないため、何も削除されません。
df3 = df2.dropna(how="all")
df3.shape
(768, 9)
手法2:欠損値を置換する
削除の代わりに、要約統計や固定値で補完する方法もあります。例えば、1週間の気温測定で1日分が欠けている場合、その週の平均で埋めれば行は保持され、情報の損失も小さくて済みます。以下はPregnanciesの欠損を列平均で埋めています。
df3 = df2.copy()
# Pregnanciesの平均を取得
mean_value = df3["Pregnancies"].mean()
# その列の欠損のみを補完
df3["Pregnancies"] = df3["Pregnancies"].fillna(mean_value)
df3["Pregnancies"].head(7)
1 6.000000
2 1.000000
3 3.846859
4 3.846859
5 3.846859
6 3.846859
7 3.000000
Name: Pregnancies, dtype: float64
重複データへの対処
重複除去を学ぶため、元データに重複を追加します。pd.concat()でdf2を自分自身と縦結合し、df2の各行を完全に重複させます。
df3 = pd.concat([df2, df2])
df3.shape
(1536, 9)
すべての重複行(デフォルト)を.drop_duplicates()で除去できます。
df3 = df3.drop_duplicates()
df3.shape
(768, 9)
列名の変更
よくあるクレンジング作業に列名の変更があります。.rename()に古い名前から新しい名前へのマッピングをcolumns辞書で渡します。
df3 = df3.rename(columns={"DiabetesPedigreeFunction": "DPF"})
df3[["Glucose", "BMI", "DPF", "Age"]].head()
Glucose BMI DPF Age
1 148 33.6 0.627 50
2 85 26.6 0.351 31
3 183 23.3 0.672 32
4 89 28.1 0.167 21
5 137 43.1 2.288 33
また、.columnsに列名のリストを一括代入することもできます。リストは現在の列順すべてに対応している必要があります。pandasは位置で割り当てるため、順序が合わないとデータに誤ったラベルが静かに付与されます。
df3.columns = ["Pregnancies", "Glucose", "BloodPressure", "SkinThickness", "Insulin", "BMI", "DPF", "Age", "Outcome"]
list(df3.columns)
['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI', 'DPF', 'Age', 'Outcome']
データクレンジングの詳細や、より簡潔で予測可能なワークフローについては、一般的なデータクレンジングのチェックリストをご活用ください。
pandasでDataFrameを結合する
pandasは2つの方法でDataFrameを結合します。.merge()は共有キー列でテーブルを結合(SQLのJOINのように)、pd.concat()はテーブルを上下または左右に連結します。
.merge()での結合
2つのテーブルがキー列を共有しているときは.merge()を使います。例えば、Outcomeコードごとに読みやすいラベルを持つ第2テーブルがあるとします。Outcomeでの左結合により、各患者行にラベルを追加します。
outcome_labels = pd.DataFrame({"Outcome": [0, 1], "Diagnosis": ["Non-diabetic", "Diabetic"]})
df_labeled = df.merge(outcome_labels, on="Outcome", how="left")
df_labeled[["Glucose", "Outcome", "Diagnosis"]].head(3)
Glucose Outcome Diagnosis
0 148 1 Diabetic
1 85 0 Non-diabetic
2 183 1 Diabetic
how引数で結合タイプを指定します。"left"はdfの全行を保持、"inner"は両テーブルに一致がある行のみ、"outer"は両方の全行を保持します。詳細はDataFrame結合チュートリアルをご覧ください。
pd.concat()での連結
同じ列構成のテーブルの行を積み上げたい(例:2回に分かれて届いた患者記録)ときはpd.concat()を使います。ignore_index=Trueで、各バッチのラベルを保持せず0始まりの新しいインデックスにします。
batch_1 = df.iloc[:500]
batch_2 = df.iloc[500:]
df_combined = pd.concat([batch_1, batch_2], ignore_index=True)
df_combined.shape
(768, 9)
axis=1を指定すると、インデックスラベルで行を対応付けながら左右に並べます。
measurements = df[["Glucose", "BMI"]]
outcomes = df[["Outcome"]]
pd.concat([measurements, outcomes], axis=1).head(3)
Glucose BMI Outcome
0 148 33.6 1
1 85 26.6 0
2 183 23.3 1
両手法の実践には、Joining Data with pandasコースをお試しください。
pandasでのデータ分析
pandasの価値は、素早いデータ分析機能にあります。ここでは、pandasで使える代表的な分析手法を紹介します。
要約演算(平均・最頻値・中央値)
前述のとおり、各列の平均は.mean()で取得できます。
df.mean()
Pregnancies 3.845052
Glucose 120.894531
BloodPressure 69.105469
SkinThickness 20.536458
Insulin 79.799479
BMI 31.992578
DiabetesPedigreeFunction 0.471876
Age 33.240885
Outcome 0.348958
dtype: float64
最頻値は.mode()で同様に求められます。
df.mode()

pandasで列の最頻値を表示
中央値は.median()で計算します。
df.median()
Pregnancies 3.0000
Glucose 117.0000
BloodPressure 72.0000
SkinThickness 23.0000
Insulin 30.5000
BMI 32.0000
DiabetesPedigreeFunction 0.3725
Age 29.0000
Outcome 0.0000
dtype: float64
既存列から新しい列を作る
pandasは、2つ以上の列同士をスカラーのように組み合わせて高速に計算できます。以下はGlucoseをInsulinで割って、新しい列Glucose_Insulin_Ratioを作っています。
df2['Glucose_Insulin_Ratio'] = df2['Glucose']/df2['Insulin']
df2.head()

既存列から新しい列を作成
Insulinが0の行は、0で割っているためinfになります。このデータセットではInsulinの0は測定欠損(768行中374行)を意味するため、割る前に0を欠損として扱います。
df2["Glucose_Insulin_Ratio"] = df2["Glucose"] / df2["Insulin"].where(df2["Insulin"] > 0)
df2["Glucose_Insulin_Ratio"].head()
1 NaN
2 NaN
3 NaN
4 0.946809
5 0.815476
Name: Glucose_Insulin_Ratio, dtype: float64
.where()は条件を満たす値を残し、それ以外をNaNに置き換えます。これで比率は無限大ではなく欠損になります。さらに詳しい列の派生はpandasで列を追加をご覧ください。
.value_counts()で件数を数える
カテゴリを保持する列では、各カテゴリの観測数を数えたくなることがよくあります。これには.value_counts()を使います。以下ではOutcomeが糖尿病(1)と非糖尿病(0)の件数を数えています。
df['Outcome'].value_counts()
Outcome
0 500
1 268
Name: count, dtype: int64
normalizeを指定すると、件数ではなく比率を返します。
df['Outcome'].value_counts(normalize=True)
Outcome
0 0.651042
1 0.348958
Name: proportion, dtype: float64
結果の自動ソートはsort引数(デフォルトTrue)で無効化できます。デフォルトでは件数の降順です。
df['Outcome'].value_counts(sort=False)
Outcome
1 268
0 500
Name: count, dtype: int64
.value_counts()は列だけでなく、DataFrameとその特定の列集合にも適用できます。以下ではsubset引数に列リストを渡しています。
df.value_counts(subset=['Pregnancies', 'Outcome'])
Pregnancies Outcome
1 0 106
2 0 84
0 0 73
3 0 48
4 0 45
0 1 38
5 0 36
6 0 34
1 1 29
3 1 27
7 1 25
4 1 23
8 1 22
5 1 21
7 0 20
2 1 19
9 1 18
6 1 16
8 0 16
10 0 14
1 10
9 0 10
11 1 7
13 0 5
1 5
12 0 5
11 0 4
12 1 4
14 1 2
15 1 1
17 1 1
Name: count, dtype: int64
pandasの.groupby()で集計
.groupby()と要約メソッドを組み合わせると、特定の列値でグループ化して集計できます。以下はOutcomeごとに数値列の平均を表示します。
df.groupby('Outcome').mean()

1列でのグループ化集計
.groupby()は列名のリストを渡すことで複数列でもグループ化できます。
df.groupby(['Pregnancies', 'Outcome']).mean()

2列でのグループ化集計
使用できる要約メソッドは.min()、.max()、.mean()、.median()、.sum()などです。複数集計の.agg()などのパターンはpandas GroupByチュートリアルで解説しています。
ピボットテーブル
pandasではピボットテーブルでも要約統計を計算できます。複数の変数の組み合わせで結論を導きやすくなります。以下は行がPregnanciesの一意値、列がOutcomeの一意値、セルが該当グループのBMI平均です。
例えば、Pregnancies = 5かつOutcome = 0では平均BMIは31.1です。
pd.pivot_table(df, values="BMI", index='Pregnancies',
columns=['Outcome'], aggfunc='mean')
Outcome 0 1
Pregnancies
0 31.727397 39.213158
1 29.616038 37.793103
2 29.679762 34.578947
3 29.231250 32.548148
4 31.255556 33.873913
5 31.100000 36.780952
6 29.591176 31.775000
7 29.975000 34.756000
8 30.693750 32.204545
9 28.840000 33.300000
10 30.114286 31.380000
11 37.125000 39.385714
12 30.560000 34.575000
13 33.280000 36.720000
14 NaN 35.100000
15 NaN 37.100000
17 NaN 40.900000
pandasでのデータ可視化
pandasは、Matplotlibのプロット関数に対する便利なラッパーを提供し、DataFrameの可視化を容易にします。以下では一般的な可視化をpandasで行う方法を示します。
折れ線グラフ
pandasでは、変数間の関係を折れ線で描画できます。以下は行インデックスに対するBMIとGlucoseの折れ線グラフです。
df[['BMI', 'Glucose']].plot.line()

pandasの基本的な折れ線グラフ
色はcolor引数で指定できます。
df[['BMI', 'Glucose']].plot.line(color={"BMI": "red", "Glucose": "blue"})

カスタム色を使った基本的な折れ線グラフ
また、subplots引数で、dfの全列を個別のスケール・軸で描画できます。
df.plot.line(subplots=True)

折れ線グラフのサブプロット
棒グラフ
離散的な列は、カテゴリ件数の棒グラフで分布を可視化できます。二値のOutcomeを以下に示します。
df['Outcome'].value_counts().plot.bar()

pandasの棒グラフ
箱ひげ図
連続変数の四分位の分布は箱ひげ図で可視化できます。以下のコードで作成します。
df.boxplot(column=['BMI'], by='Outcome')

pandasの箱ひげ図
まとめ
これでpandasの中核ワークフローを身につけました。ファイルをDataFrameに読み込み、.head()、.info()、.describe()で確認し、.loc[]と.iloc[]で行を選択、欠損や重複をクリーンにし、テーブルを結合、.groupby()やピボットテーブルで要約します。
2026年以前にpandasを学んだ方は、習慣を1つ変える価値があります。inplace=Trueではなく結果を再代入し、更新は常に1回の.loc[]呼び出しで行ってください。残りを定着させる最速の方法は、関心のあるデータセットでこのワークフローを繰り返すことです。さらに学ぶには以下をどうぞ。
- [チートシート] 学習を通じて参照できるPythonやpandasのチートシート
- [ライブトレーニング] 無料のコードアロングセッション(多くがpandasを使用)
- [Courses] 対話的に練習できるData Manipulation with pandasとJoining Data with pandas
- [面接対策] 実力を試せるpandas面接質問集
- [その他のチュートリアル] pandasやPyDataエコシステムの他のチュートリアル(移動平均の実装やpandasの.apply()の使い方など)
pandasのFAQ
Pythonにおけるpandasとは?
pandasは表形式データを扱うためのオープンソースのPythonライブラリです。2つの中核データ構造であるDataFrame(表)とSeries(単一列)は、データのインポート、クレンジング、形状変更、集計、プロットのための関数を備えており、Pythonでのデータ分析の標準ツールとなっています。
なぜpandasを学ぶべきですか?
Pythonでデータを扱うなら、pandasはほぼ必須です。データの取り扱いと分析を簡素化し、洞察の抽出と価値創出に集中できます。小規模データから大規模データまで、pandasはその速度、柔軟性、使いやすいデータ構造で作業を楽にしてくれます。
pandasはどうやってインストールしますか?
ターミナルでpip install pandasを実行するか、conda利用時はconda install pandasを実行します。pandas 3はPython 3.11以降が必要です。Anacondaには標準で同梱され、DataCampのDataLabでも事前インストールされています。
pandasの基本的なデータ構造は何ですか?
pandasの主なデータ構造はSeriesとDataFrameです。Seriesは基本的に1つの列、DataFrameは複数のSeriesからなる多次元の表です。これらは柔軟で、整数、文字列、浮動小数など異なる型のデータを保持できます。
pandasは大規模データに向いていますか?
pandasはデータがPCメモリに収まる限り、数百万行でも快適に扱えます。収まらない場合はchunksizeで分割読み込みするか、Polars、Dask、PySparkなどの大規模データ向けツールに切り替えてください。
pandasへはどうやってデータをインポートしますか?
pandasはCSV、Excel、SQLデータベース、JSONなど多様な形式からデータを読み込めます。pd.read_csv()、pd.read_excel()、pd.read_sql()、pd.read_json()がそれぞれの形式に対応します。いずれもDataFrameを返し、pandasで操作できます。
pandas 3.0では何が変わりましたか?
2026年1月リリースのpandas 3.0ではCopy-on-Writeがデフォルトになり、あらゆる部分集合はコピーとして振る舞うため、df["col"][0] = xのような連鎖代入は元のDataFrameを更新しません。テキスト列は専用のstr型として推論され、Python 3.11以降が必要になりました。続くpandas 3.1では、dropna()やsort_values()などでinplace=Trueが非推奨になりました。
pandasにおけるlocとilocの違いは?
.loc[]はラベルで行・列を選択し、.iloc[]は0始まりの整数位置で選択します。スライスも異なり、.loc[100:110]は終端ラベルを含み、.iloc[100:110]は位置110の手前までです。詳しくはloc vs ilocガイドをご覧ください。
pandasで2つのDataFrameを結合するには?
SQLのJOINのように、共有列で2つのDataFrameを結合するにはdf1.merge(df2, on="key", how="left")を使います。howで"left"、"right"、"inner"、"outer"を選べます。行を積み上げるならpd.concat()を使います。
pandasはPythonの標準的なデータ分析パッケージで、PyPIでは月5億回以上ダウンロードされています。CSV、Excel、JSON、SQLなど多様な形式を読み書きでき、表形式データの日常的な整形、変換、集計、可視化の作業を幅広くカバーします。
このpandasチュートリアルでは、1つの実データセットを使ってワークフロー全体を通して解説します。pandasのインストール、データのインポートとエクスポート、DataFrameの確認、行の選択とフィルタリング、欠損値や重複のクリーニング、テーブルの結合、集計、プロットまで扱います。すべての例は現行リリースであるpandas 3.1で動作し、古いチュートリアルのコードを壊すpandas 3の変更点にも注意を促します。
必要なのはPythonの基礎だけで、pandasの事前経験は不要です。より長期的な学習計画は、pandasの学び方の記事を、対話的な練習はData Manipulation with pandasコースをご覧ください。
要点
pip install pandasでインストールします。pandas 3はPython 3.11以降が必要です。.loc[]はラベル指定、.iloc[]は位置指定で選択します。.loc[]呼び出しで更新してください。inplace=Trueではなく、結果を再代入します(例:df = df.dropna())。pandasとは?
pandasはPythonで表形式データを扱うためのデータ操作パッケージです。つまり、行と列からなるデータ(DataFrame)を対象にします。直感的には、DataFrameはExcelシートのようなものと考えられます。
pandasの機能には、行の並べ替えや部分抽出といった変換から、平均などの要約統計の計算、DataFrameの形状変更、DataFrame同士の結合まで含まれます。いわゆるPyDataエコシステムの他の人気Pythonライブラリとも相性が良く、次のようなものがあります。
pandasは何に使う?
pandasはデータ分析のワークフロー全体で使われます。例えば、次のことが可能です。
pandasには時系列分析やテキストデータの分析向け機能も含まれます。
pandasの主な利点
pandasには、日々のデータ作業に役立つ5つの実用的な利点があります。
pandasのインストール方法
pandasを使う前にインストールが必要です。無料のDataCampアカウント登録を行い、pandas(主要なPythonデータサイエンスパッケージ同梱)済みのクラウドIDEであるDataLabを使えば、この手順はスキップできます。