CSVを読み込んだあと、「列のデータ型は合っているのか」「欠損値はあるのか」「分析前に何を確認すればよいのか」と迷うことはありませんか。
そんなときに使うのが、Pandasのinfo()です。df.info()を実行すると、DataFrameの行数・列数・列名・欠損していない値の数・データ型・メモリ使用量をまとめて確認できます。
ただし、表示するだけでは十分ではありません。特に重要なのは、Non-Null CountとDtypeを対応させて読むことです。
- Non-Null Countが全行数より少ない列 → 欠損値がある
- Dtypeが想定と異なる列 → 型変換が必要な可能性がある
この記事では、info()の出力を上から順に読み、問題を発見し、必要な前処理を選び、修正後にもう一度確認するところまで解説します。
- この記事でわかること
- 先に結論:info()はデータの構造を最初に診断するときに使う
- 売上データを用意してinfo()を実行する
- Non-Null Countから欠損値を見つける
- Dtypeからデータ型の問題を見つける
- 問題を修正してからinfo()で再確認する
- print(df.info())でNoneが表示される理由
- info()・shape・dtypes・isnull()・describe()の使い分け
- コードは動いても結果を誤解しやすい場面
- info()でうまく確認できないときの原因と対処
- 自分のデータでinfo()を使うときの確認ポイント
- info()の確認結果を次の分析工程へつなげる
- まとめ:info()は問題を見つけて次の処理を選ぶために使う
- 次に読みたい関連記事
この記事でわかること
df.info()で確認できる内容- Non-Null CountとDtypeの読み方
- 欠損値や想定外のデータ型を見つける方法
info()・shape・dtypes・isnull()・describe()の使い分けprint(df.info())の最後にNoneが表示される理由- 確認結果から型変換や欠損値処理へ進む方法
この記事のゴールは、df.info()の結果から問題を発見し、次に必要な前処理を自分で判断できるようになることです。
先に結論:info()はデータの構造を最初に診断するときに使う
info()は、DataFrameの中身を変更するメソッドではありません。現在の構造をまとめて表示する確認用のメソッドです。
CSVを読み込んだら、次の順番で確認すると迷いにくくなります。
- 行数と列数が想定どおりか
- Non-Null Countが全行数より少ない列はないか
- Dtypeが想定どおりか
- 問題があれば、専用の確認・修正方法へ進む
たとえば、Non-Null Countが少なければisnull().sum()、数値にしたい列がobject型ならto_numeric()、日付列がobject型ならto_datetime()で詳しく確認・修正します。
売上データを用意してinfo()を実行する
CSVから読み込んだ状態を想定した、5行の売上データを使います。
日付は文字列売上にはカンマ付きの数字があり、文字列として保存返品数には欠損値が1つ存在
まず、実行前のDataFrameを確認しましょう。
import pandas as pd
import numpy as np
df = pd.DataFrame({
"日付": ["2026-08-01", "2026-08-02", "2026-08-03", "2026-08-04", "2026-08-05"],
"商品": ["ノート", "ペン", "ノート", "ファイル", "ペン"],
"売上": ["1,200", "900", "1,500", "800", "1,100"],
"返品数": [0, np.nan, 1, 0, 2]
})
df
| 日付 | 商品 | 売上 | 返品数 | |
|---|---|---|---|---|
| 0 | 2026-08-01 | ノート | 1,200 | 0.0 |
| 1 | 2026-08-02 | ペン | 900 | NaN |
| 2 | 2026-08-03 | ノート | 1,500 | 1.0 |
| 3 | 2026-08-04 | ファイル | 800 | 0.0 |
| 4 | 2026-08-05 | ペン | 1,100 | 2.0 |
日付や売上は見た目だけでは型を判断できません。また、返品数の2行目にはNaNがあります。次にdf.info()を実行し、DataFrame全体の構造を確認します。
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5 entries, 0 to 4 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 日付 5 non-null object 1 商品 5 non-null object 2 売上 5 non-null object 3 返品数 4 non-null float64 dtypes: float64(1), object(3) memory usage: 292.0+ bytes
出力は、次の順で読みます。
| 出力項目 | 確認できること | 今回の注目点 |
|---|---|---|
DataFrame |
対象の種類 | PandasのDataFrameである |
RangeIndex |
行数とインデックス範囲 | 5行、インデックスは0〜4 |
Data columns |
合計列数 | 4列 |
Column |
列番号と列名 | 日付・商品・売上・返品数 |
Non-Null Count |
欠損していない値の数 | 返品数だけ4件 |
Dtype |
Pandasが認識した型 | 日付・商品・売上はobject、返品数はfloat64 |
dtypes |
型ごとの列数 | float64が1列、objectが3列 |
memory usage |
DataFrameのおおよそのメモリ使用量 | データ規模の目安 |
最初に見るべきなのは、返品数のNon-Null Countが4であることと、日付・売上がobject型であることです。
info()はデータを表示・診断するだけなので、実行しても元のDataFrameは変わりません。
Non-Null Countから欠損値を見つける
Non-Null Countは、欠損していない値の数です。欠損数ではありません。
今回のDataFrameは全5行です。返品数は4 non-nullなので、欠損数は次のように求められます。
欠損数 = 全行数 − Non-Null Count = 5 − 4 = 1
各列の関係を整理すると、次のようになります。
| 列名 | 全行数 | Non-Null Count | 欠損数 |
|---|---|---|---|
| 日付 | 5 | 5 | 0 |
| 商品 | 5 | 5 | 0 |
| 売上 | 5 | 5 | 0 |
| 返品数 | 5 | 4 | 1 |
info()で欠損値の存在は分かりますが、どの行が欠損しているかまでは分かりません。詳しい件数と位置はisnull()で確認します。
# 列ごとの欠損数
df.isnull().sum()
| 0 | |
|---|---|
| 日付 | 0 |
| 商品 | 0 |
| 売上 | 0 |
| 返品数 | 1 |
# 欠損値がある行
df[df["返品数"].isnull()]
| 日付 | 商品 | 売上 | 返品数 | |
|---|---|---|---|---|
| 1 | 2026-08-02 | ペン | 900 | NaN |
返品数の欠損数は1件で、インデックス1の行にあることが分かりました。
ここで注意したいのは、欠損値を見つけても、すぐに0で埋めたり行を削除したりしないことです。0が「返品なし」を意味するのか、「記録漏れ」を意味するのかで適切な処理は変わります。
今回は、データの作成ルールとして空欄は返品なしを意味すると確認できたものとして、後ほど0で補完します。自分のデータでは、業務上の意味を確認してからfillna()またはdropna()を選んでください。
Dtypeからデータ型の問題を見つける
Dtypeは、各列をPandasがどのデータ型として認識しているかを示します。
今回の結果では、次の3点に注目します。
| 列名 | 現在のDtype | 期待する型 | 判断 |
|---|---|---|---|
| 日付 | object | datetime64[ns] | 日付計算や月別集計の前に変換候補 |
| 商品 | object | object | 商品名なのでそのままでよい |
| 売上 | object | int64 | 合計や平均を求める前に変換候補 |
| 返品数 | float64 | int64 | 欠損値のためfloat64になっている |
object型は必ず「普通の文字列」とは限らない
object型には、商品名のような文字列だけでなく、文字列として読み込まれた日付や数字も含まれます。そのため、object型を見つけても、すぐに機械的な型変換をせず、値の中身を確認します。
# object型の列と実際の値を確認
print(df.select_dtypes(include="object").columns.tolist())
df[["日付", "商品", "売上"]]
['日付', '商品', '売上']
| 日付 | 商品 | 売上 | |
|---|---|---|---|
| 0 | 2026-08-01 | ノート | 1,200 |
| 1 | 2026-08-02 | ペン | 900 |
| 2 | 2026-08-03 | ノート | 1,500 |
| 3 | 2026-08-04 | ファイル | 800 |
| 4 | 2026-08-05 | ペン | 1,100 |
日付は日付形式の文字列、売上はカンマを含む数字の文字列です。一方、商品は名称なのでobject型のままで問題ありません。
売上のような列へ単純にastype(int)を使うと、1,200のカンマを整数として解釈できず、変換エラーになります。カンマを除いてからto_numeric()を使うと、数値に変換できない値の確認もしやすくなります。
float64は必ず小数を記録した列とは限らない
返品数の値は0・1・2という整数ですが、欠損値NaNを含むため、今回の環境ではfloat64として表示されています。Dtypeだけを見て「返品数には小数がある」と判断しないようにしましょう。
問題を修正してからinfo()で再確認する
次の方針で修正します。
日付:to_datetime()で日付型へ変換売上:カンマを取り除き、to_numeric()で数値型へ変換返品数:空欄は返品なしというルールに基づき0で補完して整数型へ変換商品:名称なのでobject型のまま維持
元のDataFrameを残して比較できるように、コピーしたdf_fixedを修正します。
df_fixed = df.copy()
df_fixed["日付"] = pd.to_datetime(df_fixed["日付"])
df_fixed["売上"] = pd.to_numeric(
df_fixed["売上"].str.replace(",", "", regex=False)
)
df_fixed["返品数"] = df_fixed["返品数"].fillna(0).astype("int64")
df_fixed
| 日付 | 商品 | 売上 | 返品数 | |
|---|---|---|---|---|
| 0 | 2026-08-01 | ノート | 1200 | 0 |
| 1 | 2026-08-02 | ペン | 900 | 0 |
| 2 | 2026-08-03 | ノート | 1500 | 1 |
| 3 | 2026-08-04 | ファイル | 800 | 0 |
| 4 | 2026-08-05 | ペン | 1100 | 2 |
表示上は似ていますが、日付・売上・返品数のデータ型が変わっています。修正できたと決めつけず、もう一度info()を実行して検証します。
df_fixed.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5 entries, 0 to 4 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 日付 5 non-null datetime64[ns] 1 商品 5 non-null object 2 売上 5 non-null int64 3 返品数 5 non-null int64 dtypes: datetime64[ns](1), int64(2), object(1) memory usage: 292.0+ bytes
再確認では、次の変化に注目します。
日付:object → datetime64[ns]売上:object → int64返品数:4 non-null → 5 non-null、float64 → int64商品:objectのまま
処理前後を一覧でも確認しましょう。
comparison = pd.DataFrame({
"修正前_Dtype": df.dtypes.astype(str),
"修正後_Dtype": df_fixed.dtypes.astype(str),
"修正前_Non-Null": df.notna().sum(),
"修正後_Non-Null": df_fixed.notna().sum()
})
comparison
| 修正前_Dtype | 修正後_Dtype | 修正前_Non-Null | 修正後_Non-Null | |
|---|---|---|---|---|
| 日付 | object | datetime64[ns] | 5 | 5 |
| 商品 | object | object | 5 | 5 |
| 売上 | object | int64 | 5 | 5 |
| 返品数 | float64 | int64 | 4 | 5 |
この比較表によって、型変換と欠損値処理が想定どおり反映されたことを確認できます。
重要なのは、info()が自動的に問題を直したわけではないことです。info()で問題を発見し、別のメソッドで修正し、最後にinfo()で再確認しています。
print(df.info())でNoneが表示される理由
info()は、要約情報を画面へ表示するメソッドです。要約情報をDataFrameや文字列として返すのではなく、戻り値はNoneです。
そのため、print(df.info())と書くと、最初にinfo()の情報が表示され、そのあとに戻り値のNoneが表示されます。
print(df_fixed.info())
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5 entries, 0 to 4 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 日付 5 non-null datetime64[ns] 1 商品 5 non-null object 2 売上 5 non-null int64 3 返品数 5 non-null int64 dtypes: datetime64[ns](1), int64(2), object(1) memory usage: 292.0+ bytes None
最後のNoneはエラーではありません。通常は、次のようにprint()を付けずに実行します。
df_fixed.info()
また、次のコードでもresultに要約表が保存されるわけではありません。
result = df_fixed.info()
この場合、resultの値はNoneです。
info()・shape・dtypes・isnull()・describe()の使い分け
似た確認方法は、何を知りたいかで選びます。
| 方法 | 何を求めるか | 選ぶ場面 | 分からないこと・注意点 |
|---|---|---|---|
info() |
構造・非欠損数・型の全体像 | データ読込直後の診断 | 欠損位置や値の分布は分からない |
shape |
行数と列数 | 件数を値として取得したい | 型や欠損値は分からない |
dtypes |
列ごとのデータ型 | 型だけを一覧で確認したい | 非欠損数は分からない |
isnull().sum() |
列ごとの欠損数 | 欠損値を詳しく確認したい | 型や分布の確認が中心ではない |
describe() |
統計量と値の分布 | 平均・中央値・ばらつきを見たい | DataFrame全体の構造確認とは目的が違う |
迷ったら、最初にinfo()で全体を診断し、見つかった問題に応じて専用の方法へ進みます。
- 件数だけ必要 →
shape - 型だけ詳しく確認 →
dtypes - 欠損数や欠損位置を確認 →
isnull() - 数値の分布を確認 →
describe()
select_dtypes()は、特定の型の列だけを抽出したいときに使います。全体診断ではなく、info()で型を確認した後の処理です。
print("shape:", df_fixed.shape)
print("\ndtypes:")
print(df_fixed.dtypes)
print("\n欠損数:")
print(df_fixed.isnull().sum())
shape: (5, 4) dtypes: 日付 datetime64[ns] 商品 object 売上 int64 返品数 int64 dtype: object 欠損数: 日付 0 商品 0 売上 0 返品数 0 dtype: int64
コードは動いても結果を誤解しやすい場面
Non-Null Countを欠損数だと思う
現象: 返品数 4 non-nullを「欠損値が4件ある」と読む。
原因: Non-Nullは「欠損していない」という意味だからです。
確認方法: 全行数からNon-Null Countを引きます。
修正方法: 正確な列別件数はisnull().sum()で確認します。
修正後の確認: 今回は5−4で、欠損値は1件です。
object型をすべて文字列として扱う
現象: 売上の合計や日付による月別集計ができない、または想定外の結果になる。
原因: 数字や日付が文字列として読み込まれています。
確認方法: head()や対象列を表示し、実際の値と記号の混入を確認します。
修正方法: 数値はto_numeric()、日付はto_datetime()を検討します。一般的な型変換にはastype()を使います。
修正後の確認: info()を再実行し、Dtypeが想定した型へ変わったか確認します。
float64を「小数を記録した列」と決めつける
現象: 整数件数の列がfloat64と表示される。
原因: 欠損値を含む整数列が、今回のDataFrameではfloat64として保持されているためです。
確認方法: 実際の値と欠損値の有無を確認します。
修正方法: 欠損値の意味を確認して処理した後、必要なら整数型へ変換します。
修正後の確認: 今回の返品数は、補完後にint64となりました。
memory usageを厳密な全メモリ量だと思う
info()のmemory usageは、データ規模を知るための目安です。object型が参照するオブジェクトのメモリなど、条件によってはすべてを詳細に含む値ではありません。この記事ではメモリ最適化へ深入りせず、「急に大きなデータを読み込んでいないか」を確認する目安として使います。
info()でうまく確認できないときの原因と対処
NameError: name ‘df’ is not defined
現象: df.info()を実行するとNameErrorが出る。
原因: dfを作成・読み込みするセルをまだ実行していないか、変数名が違います。
確認方法: ColabでDataFrame作成セルが実行済みか、変数名がdfか確認します。
修正方法: DataFrameを作成・読み込みするセルから順に実行します。
修正後の確認: type(df)がpandas.core.frame.DataFrameとなり、df.info()が表示されることを確認します。
AttributeErrorが出る
現象: 対象によっては「infoという属性がない」というAttributeErrorが出る。
原因: dfがDataFrameではなく、リストなど別のオブジェクトになっている可能性があります。
確認方法: type(df)で対象の種類を確認します。
修正方法: 正しいDataFrame変数を指定するか、必要に応じてDataFrameへ変換します。
修正後の確認: type(df)とdf.info()の両方を再確認します。
自分のデータでinfo()を使うときの確認ポイント
サンプルを自分のCSVやExcelデータへ置き換えるときは、次を確認してください。
- 想定した行数と列数になっているか
- 必要な列名が存在するか
- 各列のNon-Null Countが全行数と一致するか
- 数値・日付・文字列のDtypeが想定どおりか
- object型の列に、数字・日付・記号などが混在していないか
- 郵便番号や商品コードなど、先頭の0を残すべき列を数値にしていないか
- 欠損値を0や平均値で埋めても、データの意味が変わらないか
- 修正後に再度
info()を実行したか
特に、郵便番号や商品コードは計算する数値ではありません。CSV読込時に数値として解釈されると先頭の0が失われることがあるため、読み込み段階で文字列として扱う方法を検討します。
info()の確認結果を次の分析工程へつなげる
info()は、データ分析のゴールではなく入口です。次の順で進めると、問題を見落としにくくなります。
- CSVやExcelからデータを読み込む
head()で実際の値を確認するinfo()で構造・非欠損数・型を確認するisnull()で欠損値を詳しく確認するto_numeric()・to_datetime()・astype()で型を整えるfillna()またはdropna()で欠損値を処理するdescribe()で分布や統計量を確認する- 必要な抽出・集計・可視化へ進む
構造と型を確認するのがinfo()、値の分布を確認するのがdescribe()です。この役割を分けると、どちらを使うか迷いにくくなります。
まとめ:info()は問題を見つけて次の処理を選ぶために使う
df.info()は、DataFrameの行数・列数・列名・Non-Null Count・Dtype・メモリ使用量をまとめて確認するメソッドです。
特に重要なポイントは次のとおりです。
- Non-Null Countは欠損していない値の数
- 欠損数は「全行数−Non-Null Count」で考える
- Dtypeが想定と違う場合は、実際の値を確認してから変換方法を選ぶ
- object型には、文字列だけでなく数字や日付の文字列も含まれる
- 欠損値を含む整数列がfloat64になる場合がある
info()はデータを修正せず、戻り値はNone- 修正後はもう一度
info()を実行して結果を検証する
最初にinfo()で全体を診断し、欠損値ならisnull()、型の問題ならto_numeric()・to_datetime()・astype()、分布の確認ならdescribe()へ進みましょう。
次に読みたい関連記事
- Pandas DataFrame入門|作り方と基本操作を初心者向けに解説
- pandas head()の使い方|df.head()で先頭5行を表示・tail()との違いも解説
- Google ColabでCSVを読み込む方法|アップロード・Drive・read_csv
- 欠損値を可視化して攻略!Pandas isnullとヒートマップ活用術
- pandas fillna()の使い方|欠損値を0・平均値・中央値・最頻値で埋める方法を初心者向けに解説
- Pandas dropna()・drop_duplicates()の使い方|欠損・重複の削除とdrop()基本
- pandas astype()の使い方|文字列・整数・小数の型変換とエラー対処
- pandas to_numeric()の使い方|文字列の数字を数値に変換する方法
- pandas to_datetime()の使い方|文字列の日付変換とformat・NaT対処
- pandas describe()の使い方|統計量の意味と結果の見方を解説
df.info()では何が分かりますか?
DataFrameの行数・列数・列名・各列のNon-Null Count・Dtype・型ごとの列数・おおよそのメモリ使用量が分かります。データ読込後の全体診断に向いています。
Non-Null Countとは何ですか?
欠損値ではない値の数です。全5行で4 non-nullなら、欠損値は1件あります。
info()で欠損値の場所まで確認できますか?
できません。info()では列ごとの非欠損数から欠損値の存在を判断できます。欠損数はisnull().sum()、欠損している行は条件抽出で確認します。
数字の列がobject型になるのはなぜですか?
カンマ・通貨記号・空文字・数字以外の文字などが混在している可能性があります。実際の値を確認し、不要な記号を処理してからto_numeric()による変換を検討します。
欠損値があると整数列がfloat64になるのはなぜですか?
今回のように通常のNumPy整数型で作成した列へNaNが含まれると、欠損値を保持するためfloat64になることがあります。欠損値の意味を確認して処理したあと、必要なら整数型へ変換します。
info()とdescribe()の違いは何ですか?
info()はDataFrameの構造・非欠損数・データ型を確認します。describe()は平均・中央値・標準偏差など、値の分布と統計量を確認します。
info()とdtypesの違いは何ですか?
info()は行数・列数・非欠損数・型などをまとめて表示します。dtypesは列ごとのデータ型だけを一覧で返します。
print(df.info())でNoneが表示されるのはなぜですか?
info()は要約情報を画面に表示し、戻り値としてNoneを返すためです。エラーではありません。通常はdf.info()だけを実行します。
info()を実行すると元のDataFrameは変わりますか?
変わりません。info()は確認用のメソッドです。型変換や欠損値処理を行うには、別のメソッドを使います。
コメント