<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>coin_collector | Python Data Lab（Pythonデータラボ）</title>
	<atom:link href="https://pythondatalab.com/author/coin_collector/feed/" rel="self" type="application/rss+xml" />
	<link>https://pythondatalab.com</link>
	<description>Python初心者向けに、わかりやすいデータ分析の解説を提供します。</description>
	<lastBuildDate>Sat, 12 Sep 2026 09:32:51 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>

<image>
	<url>https://pythondatalab.com/wp-content/uploads/2025/12/cropped-rogo-32x32.png</url>
	<title>coin_collector | Python Data Lab（Pythonデータラボ）</title>
	<link>https://pythondatalab.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>pandas drop()の使い方｜行・列を削除するindex・columns・axisを初心者向けに解説</title>
		<link>https://pythondatalab.com/pandas-drop-rows-columns/</link>
					<comments>https://pythondatalab.com/pandas-drop-rows-columns/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Sat, 12 Sep 2026 09:31:39 +0000</pubDate>
				<category><![CDATA[抽出・前処理]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2218</guid>

					<description><![CDATA[<p>pandasのdrop()でDataFrameの行・列を削除する方法を初心者向けに解説。index・columns・axisの違い、複数行・複数列、条件削除、反映されない原因、KeyErrorの対処までコードと処理前後表で確認できます。</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-drop-rows-columns/">pandas drop()の使い方｜行・列を削除するindex・columns・axisを初心者向けに解説</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<!-- WordPressのカスタムHTMLブロックへ、このファイルの内容を貼り付けてください。 -->
<style>
.pdl-article{max-width:100%;box-sizing:border-box;line-height:1.9;color:#222;overflow-wrap:anywhere}
.pdl-article *{box-sizing:border-box}
.pdl-article h2{margin:2.2em 0 .8em;padding:.55em .75em;border-left:6px solid #1769aa;background:#f2f7fb;font-size:1.5em;line-height:1.45}
.pdl-article h3{margin:1.7em 0 .65em;padding-bottom:.35em;border-bottom:2px solid #d7e4ef;font-size:1.2em;line-height:1.5}
.pdl-article p,.pdl-article li{font-size:1em}
.pdl-article a{overflow-wrap:anywhere}
.pdl-article .pdl-table-scroll{width:100%;max-width:100%;margin:1.2em 0;overflow-x:auto;-webkit-overflow-scrolling:touch}
.pdl-article table{width:100%;min-width:620px;border-collapse:collapse;border-spacing:0;background:#fff}
.pdl-article th,.pdl-article td{border:1px solid #9aa7b2;padding:.65em .75em;text-align:left;vertical-align:top;white-space:normal}
.pdl-article th{background:#eaf2f8;font-weight:700}
.pdl-article tr:nth-child(even) td{background:#fafcfd}
.pdl-article pre{width:100%;max-width:100%;margin:1em 0;padding:1em;overflow-x:auto;-webkit-overflow-scrolling:touch;white-space:pre;word-break:normal;overflow-wrap:normal;border-radius:6px;background:#1e1e1e;color:#f5f5f5;font-size:.9em;line-height:1.65}
.pdl-article pre.pdl-output{margin-top:.25em;background:#f6f8fa;color:#222;border:1px solid #c9d1d9}
.pdl-article .pdl-output-label{margin-top:1em;font-weight:700;color:#34495e}
.pdl-article code{font-family:Consolas,Monaco,'Courier New',monospace}
.pdl-article :not(pre)>code{padding:.12em .35em;border-radius:4px;background:#f1f3f5;color:#c7254e;overflow-wrap:anywhere}
@media (max-width:600px){
  .pdl-article{line-height:1.8}
  .pdl-article h2{font-size:1.3em}
  .pdl-article h3{font-size:1.12em}
  .pdl-article table{min-width:560px;font-size:.9em}
  .pdl-article th,.pdl-article td{padding:.55em .6em}
  .pdl-article pre{font-size:.82em;padding:.85em}
}
</style>
<div class="pdl-article">
<p>pandasのDataFrameから「この行だけ消したい」「この列は分析に使わないので削除したい」というときは、<code>drop()</code>を使います。</p>
<p>ただし、初めて使うと「<code>axis=0</code>と<code>axis=1</code>のどちら？」「削除したのに元のDataFrameが変わらない」「上から2行目を消したつもりが別の行が消えた」と迷いやすいメソッドでもあります。</p>
<p>この記事では、Google Colabでそのまま実行できるコードを使い、行・列の削除から複数指定、条件削除、エラー対策まで順番に確認します。</p>
<h2 id="この記事でわかること"><span id="toc1">この記事でわかること</span></h2>
<ul>
<li><code>drop(index=...)</code>で指定した行を削除する方法</li>
<li><code>drop(columns=...)</code>で指定した列を削除する方法</li>
<li>行ラベルと「上から何行目」という位置の違い</li>
<li>複数行・複数列や、行と列を同時に削除する方法</li>
<li><code>drop()</code>が反映されない原因と<code>inplace=True</code>の注意点</li>
<li><code>KeyError</code>が出たときの確認方法</li>
<li><code>drop()</code>・<code>dropna()</code>・<code>drop_duplicates()</code>の使い分け</li>
</ul>
<p>DataFrameそのものから確認したい方は、先に<a href="https://pythondatalab.com/pandas-dataframe/">DataFrameの作り方と基本操作</a>をご覧ください。</p>
<h2 id="先に結論行はindex列はcolumnsで削除する"><span id="toc2">先に結論：行はindex、列はcolumnsで削除する</span></h2>
<p>初心者は、次の2つを基本形として覚えると迷いにくくなります。</p>
<div class="pdl-table-scroll"><table>
<thead>
<tr class="header">
<th>削除したいもの</th>
<th>推奨コード</th>
<th>指定するもの</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>1行</td>
<td><code>df.drop(index=行ラベル)</code></td>
<td>DataFrameのindex</td>
</tr>
<tr class="even">
<td>1列</td>
<td><code>df.drop(columns="列名")</code></td>
<td>DataFrameの列名</td>
</tr>
<tr class="odd">
<td>複数行</td>
<td><code>df.drop(index=[行ラベル1, 行ラベル2])</code></td>
<td>行ラベルのリスト</td>
</tr>
<tr class="even">
<td>複数列</td>
<td><code>df.drop(columns=["列名1", "列名2"])</code></td>
<td>列名のリスト</td>
</tr>
</tbody>
</table></div>
<p><code>axis=0</code>と<code>axis=1</code>でも指定できますが、<code>index=</code>・<code>columns=</code>のほうが、行と列のどちらを削除するのかコードから読み取りやすくなります。</p>
<h2 id="pandas-dropとは"><span id="toc3">pandas drop()とは</span></h2>
<p><code>DataFrame.drop()</code>は、指定した<strong>行ラベルまたは列ラベルを除いたDataFrameを返す</strong>メソッドです。</p>
<p>通常は元のDataFrameを直接変更しません。結果を残す場合は、<code>df = df.drop(...)</code>のように変数へ代入します。この点が「実行したのに削除が反映されない」と感じる主な原因です。</p>
<h2 id="サンプルデータを用意する"><span id="toc4">サンプルデータを用意する</span></h2>
<p>最初にpandasのバージョンを確認し、5件の売上データを作ります。この記事では、すべてこのDataFrameを使います。</p>
<pre><code class="language-python">import pandas as pd

print("pandas version:", pd.__version__)

df = pd.DataFrame(
    {
        "商品": ["ノートPC", "マウス", "キーボード", "モニター", "USBメモリ"],
        "地域": ["東京", "大阪", "東京", "名古屋", "大阪"],
        "売上": [1200, 800, 1500, 700, 1100],
        "利益": [240, 160, 300, 140, 220],
    },
    index=[100, 101, 102, 103, 104],
)

print(df)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>pandas version: 2.2.3
         商品   地域    売上   利益
100   ノートPC   東京  1200  240
101     マウス   大阪   800  160
102   キーボード   東京  1500  300
103    モニター  名古屋   700  140
104  USBメモリ   大阪  1100  220</code></pre>

<p>左端の<code>100</code>〜<code>104</code>が行の<strong>indexラベル</strong>です。表の上から数えた位置とは別の情報として扱います。</p>
<h2 id="dropで行を削除する"><span id="toc5">drop()で行を削除する</span></h2>
<h3 id="indexラベルを指定して1行削除する"><span id="toc6">indexラベルを指定して1行削除する</span></h3>
<p>indexラベル<code>101</code>の行を削除します。目的は「マウスの行を削除する」ことです。</p>
<pre><code class="language-python">df_row_dropped = df.drop(index=101)
print(df_row_dropped)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>         商品   地域    売上   利益
100   ノートPC   東京  1200  240
102   キーボード   東京  1500  300
103    モニター  名古屋   700  140
104  USBメモリ   大阪  1100  220</code></pre>

<p>indexラベル<code>101</code>の行だけがなくなりました。元の<code>df</code>ではなく、結果を<code>df_row_dropped</code>へ代入しています。</p>
<h3 id="複数行をリストでまとめて削除する"><span id="toc7">複数行をリストでまとめて削除する</span></h3>
<p>複数の行は、indexラベルをリストで渡します。</p>
<pre><code class="language-python">df_rows_dropped = df.drop(index=[101, 103])
print(df_rows_dropped)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>         商品  地域    売上   利益
100   ノートPC  東京  1200  240
102   キーボード  東京  1500  300
104  USBメモリ  大阪  1100  220</code></pre>

<p>indexラベル<code>101</code>と<code>103</code>の2行が削除されました。</p>
<h3 id="行ラベルと行番号の違い"><span id="toc8">行ラベルと行番号の違い</span></h3>
<p><code>drop(index=101)</code>の<code>101</code>は「上から101行目」ではなく、<strong>indexラベル101</strong>です。</p>
<p>上から2行目を削除したい場合は、<code>df.index[1]</code>でその位置にあるラベルを取得します。Pythonは0から数えるため、<code>[1]</code>が上から2行目です。</p>
<pre><code class="language-python">second_row_label = df.index[1]
print("上から2行目のindexラベル:", second_row_label)

df_by_position = df.drop(index=second_row_label)
print(df_by_position)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>上から2行目のindexラベル: 101
         商品   地域    売上   利益
100   ノートPC   東京  1200  240
102   キーボード   東京  1500  300
103    モニター  名古屋   700  140
104  USBメモリ   大阪  1100  220</code></pre>

<p>今回は上から2行目のラベルが<code>101</code>なので、マウスの行が削除されました。indexが並べ替えられていたり、文字列になっていたりしても、位置からラベルを取得すれば意図を明確にできます。</p>
<h2 id="dropで列を削除する"><span id="toc9">drop()で列を削除する</span></h2>
<h3 id="columnsで1列削除する"><span id="toc10">columnsで1列削除する</span></h3>
<p>「利益」列を削除します。</p>
<pre><code class="language-python">df_column_dropped = df.drop(columns="利益")
print(df_column_dropped)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>         商品   地域    売上
100   ノートPC   東京  1200
101     マウス   大阪   800
102   キーボード   東京  1500
103    モニター  名古屋   700
104  USBメモリ   大阪  1100</code></pre>

<p>「利益」列だけがなくなり、「商品」「地域」「売上」は残っています。</p>
<h3 id="複数列をリストでまとめて削除する"><span id="toc11">複数列をリストでまとめて削除する</span></h3>
<pre><code class="language-python">df_columns_dropped = df.drop(columns=["地域", "利益"])
print(df_columns_dropped)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>         商品    売上
100   ノートPC  1200
101     マウス   800
102   キーボード  1500
103    モニター   700
104  USBメモリ  1100</code></pre>

<p>「地域」と「利益」の2列が削除されました。</p>
<h3 id="列番号で指定するときはdfcolumnsを使う"><span id="toc12">列番号で指定するときはdf.columnsを使う</span></h3>
<p>上からではなく左から2列目を削除したい場合は、<code>df.columns[1]</code>で列名を取得します。</p>
<pre><code class="language-python">second_column_name = df.columns[1]
print("左から2列目の列名:", second_column_name)

df_by_column_position = df.drop(columns=second_column_name)
print(df_by_column_position)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>左から2列目の列名: 地域
         商品    売上   利益
100   ノートPC  1200  240
101     マウス   800  160
102   キーボード  1500  300
103    モニター   700  140
104  USBメモリ  1100  220</code></pre>

<p>左から2列目は「地域」なので、その列が削除されました。列番号を直接<code>columns=1</code>へ渡すのではなく、<code>df.columns[1]</code>から実際の列名を取得する点が重要です。</p>
<h2 id="行と列を同時に削除する"><span id="toc13">行と列を同時に削除する</span></h2>
<p><code>index=</code>と<code>columns=</code>は同時に指定できます。ここでは2行と1列を一度に削除します。</p>
<pre><code class="language-python">df_both_dropped = df.drop(index=[101, 103], columns=["利益"])
print(df_both_dropped)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>         商品  地域    売上
100   ノートPC  東京  1200
102   キーボード  東京  1500
104  USBメモリ  大阪  1100</code></pre>

<p>indexラベル<code>101</code>・<code>103</code>の行と、「利益」列が同時に削除されています。</p>
<h2 id="axis0とaxis1の違い"><span id="toc14">axis=0とaxis=1の違い</span></h2>
<p><code>labels</code>と<code>axis</code>を組み合わせる書き方もあります。</p>
<div class="pdl-table-scroll"><table>
<thead>
<tr class="header">
<th style="text-align: right;">axis</th>
<th>対象</th>
<th><code>index</code>・<code>columns</code>で書く場合</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;"><code>axis=0</code>または<code>axis="index"</code></td>
<td>行</td>
<td><code>index=...</code></td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>axis=1</code>または<code>axis="columns"</code></td>
<td>列</td>
<td><code>columns=...</code></td>
</tr>
</tbody>
</table></div>
<p>次の2つは同じ結果になります。</p>
<pre><code class="language-python">result_with_axis = df.drop(labels="利益", axis=1)
result_with_columns = df.drop(columns="利益")

print("2つの結果は同じ:", result_with_axis.equals(result_with_columns))
print(result_with_axis)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>2つの結果は同じ: True
         商品   地域    売上
100   ノートPC   東京  1200
101     マウス   大阪   800
102   キーボード   東京  1500
103    モニター  名古屋   700
104  USBメモリ   大阪  1100</code></pre>

<p><code>True</code>と表示されれば、2つの結果は同じです。既存コードを読むために<code>axis</code>の意味は必要ですが、自分で書くときは<code>index=</code>・<code>columns=</code>を使うと取り違えを減らせます。</p>
<h2 id="条件に合う行を削除する"><span id="toc15">条件に合う行を削除する</span></h2>
<p>「売上が1000未満の行を削除する」場合は、最初に条件に合う行のindexを取得し、そのindexを<code>drop()</code>へ渡します。</p>
<pre><code class="language-python">delete_index = df.index[df["売上"] &lt; 1000]
print("削除対象のindex:", delete_index.tolist())

df_condition_dropped = df.drop(index=delete_index)
print(df_condition_dropped)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>削除対象のindex: [101, 103]
         商品  地域    売上   利益
100   ノートPC  東京  1200  240
102   キーボード  東京  1500  300
104  USBメモリ  大阪  1100  220</code></pre>

<p>売上が1000未満のindexラベル<code>101</code>と<code>103</code>が削除されました。</p>
<p>同じ結果は「売上が1000以上の行だけ残す」と考えて、条件抽出でも作れます。</p>
<pre><code class="language-python">df_filtered = df[df["売上"] &gt;= 1000]

print("drop()と条件抽出の結果は同じ:", df_condition_dropped.equals(df_filtered))
print(df_filtered)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>drop()と条件抽出の結果は同じ: True
         商品  地域    売上   利益
100   ノートPC  東京  1200  240
102   キーボード  東京  1500  300
104  USBメモリ  大阪  1100  220</code></pre>

<p>結果は同じです。削除対象のindexが明確なら<code>drop()</code>、残す条件をそのまま表現したいなら条件抽出が読みやすいことがあります。条件式を反転させると結果も逆になるため、処理前後の行数を必ず確認しましょう。</p>
<p>条件指定を詳しく確認したい方は、<a href="https://pythondatalab.com/pandas-filtering/">pandasでAND・OR・queryを使って条件抽出する方法</a>も参考にしてください。</p>
<h2 id="処理前後表で確認する"><span id="toc16">処理前後表で確認する</span></h2>
<div class="pdl-table-scroll"><table>
<thead>
<tr class="header">
<th>操作</th>
<th>処理前</th>
<th>指定</th>
<th>処理後</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>1行削除</td>
<td>5行×4列</td>
<td><code>index=101</code></td>
<td>4行×4列</td>
</tr>
<tr class="even">
<td>1列削除</td>
<td>5行×4列</td>
<td><code>columns="利益"</code></td>
<td>5行×3列</td>
</tr>
<tr class="odd">
<td>2行・1列を同時削除</td>
<td>5行×4列</td>
<td><code>index=[101, 103]</code>, <code>columns=["利益"]</code></td>
<td>3行×3列</td>
</tr>
<tr class="even">
<td>条件削除</td>
<td>5行×4列</td>
<td>売上1000未満</td>
<td>3行×4列</td>
</tr>
</tbody>
</table></div>
<p>行数・列数は<code>shape</code>でも検証できます。</p>
<pre><code class="language-python">print("処理前:", df.shape)
print("1行削除後:", df_row_dropped.shape)
print("1列削除後:", df_column_dropped.shape)
print("行・列の同時削除後:", df_both_dropped.shape)
print("条件削除後:", df_condition_dropped.shape)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>処理前: (5, 4)
1行削除後: (4, 4)
1列削除後: (5, 3)
行・列の同時削除後: (3, 3)
条件削除後: (3, 4)</code></pre>

<h2 id="dropが反映されない原因"><span id="toc17">drop()が反映されない原因</span></h2>
<h3 id="戻り値を変数へ代入する"><span id="toc18">戻り値を変数へ代入する</span></h3>
<p>通常の<code>drop()</code>は、削除後の新しいDataFrameを返します。元の<code>df</code>は変わりません。</p>
<pre><code class="language-python">temporary_result = df.drop(index=101)

print("削除結果の行数:", len(temporary_result))
print("元のdfの行数:", len(df))</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>削除結果の行数: 4
元のdfの行数: 5</code></pre>

<p>削除結果は4行ですが、元の<code>df</code>は5行のままです。結果を反映するなら、次のように再代入します。</p>
<pre><code class="language-python">df = df.drop(index=101)</code></pre>
<h3 id="inplacetrueの動作と注意点"><span id="toc19">inplace=Trueの動作と注意点</span></h3>
<p><code>inplace=True</code>を指定すると対象のDataFrameを直接変更し、戻り値は<code>None</code>になります。元のサンプルを壊さないよう、コピーで確認します。</p>
<pre><code class="language-python">df_copy = df.copy()
return_value = df_copy.drop(index=101, inplace=True)

print("戻り値:", return_value)
print("変更後のdf_copy:")
print(df_copy)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>戻り値: None
変更後のdf_copy:
         商品   地域    売上   利益
100   ノートPC   東京  1200  240
102   キーボード   東京  1500  300
103    モニター  名古屋   700  140
104  USBメモリ   大阪  1100  220</code></pre>

<p><code>return_value</code>は<code>None</code>ですが、<code>df_copy</code>からはindexラベル<code>101</code>の行が削除されています。</p>
<p>次の書き方は、<code>None</code>を<code>df</code>へ代入してしまうので避けてください。</p>
<pre><code class="language-python">df = df.drop(index=101, inplace=True)  # 誤り：dfがNoneになる</code></pre>
<p>初心者は、処理の結果を追いやすい<code>df = df.drop(...)</code>を基本にすると安全です。</p>
<h2 id="keyerrorが出る原因と対処法"><span id="toc20">KeyErrorが出る原因と対処法</span></h2>
<p>存在しない行ラベルや列名を指定すると、既定では<code>KeyError</code>になります。ここでは、存在しない「売上高」列を指定してエラーを確認します。</p>
<pre><code class="language-python">try:
    df.drop(columns="売上高")
except KeyError as error:
    print(type(error).__name__ + ":", error)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>KeyError: "['売上高'] not found in axis"</code></pre>

<h3 id="keyerrorの確認表"><span id="toc21">KeyErrorの確認表</span></h3>
<div class="pdl-table-scroll"><table>
<thead>
<tr class="header">
<th>確認項目</th>
<th>よくある原因</th>
<th>確認方法</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>列名</td>
<td>「売上」と「売上高」などの表記違い</td>
<td><code>df.columns.tolist()</code></td>
</tr>
<tr class="even">
<td>行ラベル</td>
<td>位置番号とindexラベルの混同</td>
<td><code>df.index.tolist()</code></td>
</tr>
<tr class="odd">
<td>大文字・小文字</td>
<td><code>Sales</code>と<code>sales</code>の違い</td>
<td>実際の列名を表示</td>
</tr>
<tr class="even">
<td>前後の空白</td>
<td><code>"売上 "</code>のような空白</td>
<td><code>repr()</code>などで確認</td>
</tr>
<tr class="odd">
<td>行・列</td>
<td><code>axis</code>の指定間違い</td>
<td><code>index=</code>・<code>columns=</code>を使う</td>
</tr>
</tbody>
</table></div>
<pre><code class="language-python">print("列名:", df.columns.tolist())
print("indexラベル:", df.index.tolist())</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>列名: ['商品', '地域', '売上', '利益']
indexラベル: [100, 101, 102, 103, 104]</code></pre>

<h3 id="errorsignoreを使ってよい場面"><span id="toc22">errors=&#8221;ignore&#8221;を使ってよい場面</span></h3>
<p><code>errors="ignore"</code>を指定すると、存在しないラベルを無視して、存在するラベルだけを削除できます。</p>
<pre><code class="language-python">df_ignored = df.drop(columns=["利益", "存在しない列"], errors="ignore")
print(df_ignored)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>         商品   地域    売上
100   ノートPC   東京  1200
101     マウス   大阪   800
102   キーボード   東京  1500
103    モニター  名古屋   700
104  USBメモリ   大阪  1100</code></pre>

<p>「利益」は削除され、「存在しない列」は無視されました。ただし、タイプミスまで見逃すため、手入力したコードのエラー回避として常用しないでください。削除候補が外部データから渡され、存在するものだけ処理したい場合など、意図が明確な場面に限定します。</p>
<h2 id="行削除後のindexを振り直す"><span id="toc23">行削除後のindexを振り直す</span></h2>
<p>行を削除してもindexは自動で連番に戻りません。必要な場合は<code>reset_index(drop=True)</code>を使います。</p>
<pre><code class="language-python">df_after_drop = df.drop(index=[101, 103])
df_after_reset = df_after_drop.reset_index(drop=True)

print("行削除後:")
print(df_after_drop)
print("\nindexを振り直した後:")
print(df_after_reset)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>行削除後:
         商品  地域    売上   利益
100   ノートPC  東京  1200  240
102   キーボード  東京  1500  300
104  USBメモリ  大阪  1100  220

</code><p><code>indexを振り直した後: 商品 地域 売上 利益 0 ノートPC 東京 1200 240 1 キーボード 東京 1500 300 2 USBメモリ 大阪 1100 220</code></p></pre><p></p>
<p><code>drop=True</code>を付けると、削除前のindexを新しい列として残さず、0からの連番にできます。詳しくは<a href="https://pythondatalab.com/pandas-reset-index/">reset_index()でインデックスを振り直す方法</a>をご覧ください。</p>
<h2 id="dropdropnadrop_duplicatesの違い"><span id="toc24">drop()・dropna()・drop_duplicates()の違い</span></h2>
<p>名前は似ていますが、削除する対象が異なります。</p>
<div class="pdl-table-scroll"><table>
<thead>
<tr class="header">
<th>目的</th>
<th>使うメソッド</th>
<th>代表例</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>指定した行・列を削除</td>
<td><code>drop()</code></td>
<td><code>df.drop(columns="利益")</code></td>
</tr>
<tr class="even">
<td>欠損値を含む行・列を削除</td>
<td><code>dropna()</code></td>
<td><code>df.dropna()</code></td>
</tr>
<tr class="odd">
<td>重複行を削除</td>
<td><code>drop_duplicates()</code></td>
<td><code>df.drop_duplicates()</code></td>
</tr>
<tr class="even">
<td>条件に合う行だけ残す</td>
<td>ブール条件</td>
<td><code>df[df["売上"] &gt;= 1000]</code></td>
</tr>
</tbody>
</table></div>
<ul>
<li>欠損値を削除したい場合：<a href="https://pythondatalab.com/pandas-drop/">dropna()で欠損値を削除する方法</a></li>
<li>重複行を削除したい場合：<a href="https://pythondatalab.com/pandas-drop-duplicates/">drop_duplicates()で重複行を削除する方法</a></li>
<li>削除前に重複を確認したい場合：<a href="https://pythondatalab.com/pandas-duplicated/">duplicated()で重複行を確認する方法</a></li>
</ul>
<h2 id="よくあるミス"><span id="toc25">よくあるミス</span></h2>
<div class="pdl-table-scroll"><table>
<thead>
<tr class="header">
<th>ミス</th>
<th>起こること</th>
<th>対処</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>df.drop(1)</code>を「上から2行目」と決めつける</td>
<td>indexラベル1を探す</td>
<td>位置なら<code>df.index[1]</code>を使う</td>
</tr>
<tr class="even">
<td>列名を指定したのに行として扱われる</td>
<td><code>KeyError</code>になる</td>
<td><code>columns="列名"</code>を使う</td>
</tr>
<tr class="odd">
<td>戻り値を保存しない</td>
<td>元のdfが変わらない</td>
<td>再代入する</td>
</tr>
<tr class="even">
<td>再代入と<code>inplace=True</code>を同時に使う</td>
<td>変数が<code>None</code>になる</td>
<td>どちらか一方にする</td>
</tr>
<tr class="odd">
<td><code>errors="ignore"</code>を常用する</td>
<td>タイプミスを見逃す</td>
<td>原則は既定の<code>raise</code>で確認</td>
</tr>
<tr class="even">
<td>行削除後に連番だと思い込む</td>
<td>indexが飛んだままになる</td>
<td>必要なら<code>reset_index(drop=True)</code></td>
</tr>
</tbody>
</table></div>
<h2 id="実務例分析に不要な列と取消データを除く"><span id="toc26">実務例：分析に不要な列と取消データを除く</span></h2>
<p>実務では、最初に不要な管理列を削除し、その後に対象外の行を除くことがあります。元データを残しながら、分析用DataFrameを作ります。</p>
<pre><code class="language-python">raw_df = pd.DataFrame(
    {
        "伝票ID": ["A001", "A002", "A003", "A004"],
        "商品": ["ノートPC", "マウス", "モニター", "キーボード"],
        "売上": [120000, 3000, 35000, 8000],
        "状態": ["確定", "取消", "確定", "確定"],
        "取込メモ": ["batch1", "batch1", "batch2", "batch2"],
    }
)

cancel_index = raw_df.index[raw_df["状態"] == "取消"]
analysis_df = raw_df.drop(index=cancel_index, columns=["取込メモ"])
analysis_df = analysis_df.reset_index(drop=True)

print("処理前:")
print(raw_df)
print("\n処理後:")
print(analysis_df)</code></pre>

<div class="pdl-output-label">実行結果</div><pre class="pdl-output"><code>処理前:
   伝票ID     商品      売上  状態    取込メモ
0  A001  ノートPC  120000  確定  batch1
1  A002    マウス    3000  取消  batch1
2  A003   モニター   35000  確定  batch2
3  A004  キーボード    8000  確定  batch2

</code><p><code>処理後: 伝票ID 商品 売上 状態 0 A001 ノートPC 120000 確定 1 A003 モニター 35000 確定 2 A004 キーボード 8000 確定</code></p></pre><p></p>
<p>取消行と分析に不要な「取込メモ」列が除かれ、indexも0から振り直されました。実務では、削除前後の行数やIDを確認し、必要なデータまで消していないか検証してください。</p>
<h2 id="まとめ"><span id="toc27">まとめ</span></h2>
<ul>
<li>行を削除する基本形は<code>df.drop(index=行ラベル)</code></li>
<li>列を削除する基本形は<code>df.drop(columns="列名")</code></li>
<li>複数指定はリストを渡す</li>
<li><code>drop()</code>は位置ではなくラベルを指定する</li>
<li>通常は元のDataFrameが変わらないため、結果を再代入する</li>
<li><code>inplace=True</code>の戻り値は<code>None</code></li>
<li><code>KeyError</code>が出たら<code>df.index</code>と<code>df.columns</code>を確認する</li>
<li>行削除後に連番が必要なら<code>reset_index(drop=True)</code>を使う</li>
<li>欠損値には<code>dropna()</code>、重複には<code>drop_duplicates()</code>を使う</li>
</ul>
<p>まずは<code>index=</code>と<code>columns=</code>を使い分け、処理前後のDataFrameと行数・列数を確認する習慣を付けましょう。</p>
<h3 id="次に読みたい関連記事"><span id="toc28">次に読みたい関連記事</span></h3>
<ul>
<li><a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrameとは？作り方・基本操作・Seriesとの違い</a></li>
<li><a href="https://pythondatalab.com/pandas-drop/">pandas dropna()の使い方｜欠損値を削除</a></li>
<li><a href="https://pythondatalab.com/pandas-drop-duplicates/">pandas drop_duplicates()の使い方｜重複行を削除</a></li>
<li><a href="https://pythondatalab.com/pandas-reset-index/">pandas reset_index()の使い方｜インデックスを振り直す</a></li>
<li><a href="https://pythondatalab.com/pandas-filtering/">pandas 条件抽出入門｜AND・OR・query</a></li>
</ul>
<h3 id="公式ドキュメント"><span id="toc29">公式ドキュメント</span></h3>
<ul>
<li><a rel="noopener" href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.drop.html" target="_blank">pandas.DataFrame.drop</a></li>
</ul>

<!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc30"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
 <p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1789205092243" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc31">pandasのdrop()で行を削除するにはどう書きますか？</span></h3>
<div class="rank-math-answer ">

<p><code>df.drop(index=行ラベル)</code>と書きます。複数行なら<code>df.drop(index=[行ラベル1, 行ラベル2])</code>のようにリストで指定します。</p>

</div>
</div>
<div id="faq-question-1789205103139" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc32">pandasのdrop()で列を削除するにはどう書きますか？</span></h3>
<div class="rank-math-answer ">

<p><code>df.drop(columns="列名")</code>と書きます。複数列なら<code>columns=["列名1", "列名2"]</code>と指定します。</p>

</div>
</div>
<div id="faq-question-1789205108935" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc33">axis=0とaxis=1の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p><code>axis=0</code>は行、<code>axis=1</code>は列です。自分でコードを書く場合は、意味が明確な<code>index=</code>・<code>columns=</code>を使うと間違いを減らせます。</p>

</div>
</div>
<div id="faq-question-1789205119557" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc34">drop()を実行しても元のDataFrameに反映されないのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>通常の<code>drop()</code>は削除後の新しいDataFrameを返し、元のDataFrameを変更しないためです。<code>df = df.drop(...)</code>のように再代入します。<code>inplace=True</code>も使えますが、戻り値は<code>None</code>です。</p>

</div>
</div>
<div id="faq-question-1789205132762" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc35">drop()・dropna()・drop_duplicates()はどう使い分けますか？</span></h3>
<div class="rank-math-answer ">

<p>指定した行・列なら<code>drop()</code>、欠損値を含む行・列なら<code>dropna()</code>、重複行なら<code>drop_duplicates()</code>を使います。削除の目的に合うメソッドを選びましょう。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-drop-rows-columns/">pandas drop()の使い方｜行・列を削除するindex・columns・axisを初心者向けに解説</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-drop-rows-columns/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas drop_duplicates()の使い方｜subset・keepで重複行を削除</title>
		<link>https://pythondatalab.com/pandas-drop-duplicates/</link>
					<comments>https://pythondatalab.com/pandas-drop-duplicates/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Fri, 11 Sep 2026 15:42:08 +0000</pubDate>
				<category><![CDATA[抽出・前処理]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2210</guid>

					<description><![CDATA[<p>pandasのdrop_duplicates()で重複行を安全に削除する方法を初心者向けに解説。subset・keepの選び方、削除前の確認、最新行の残し方、処理後の検算までGoogle Colabで実行できます。</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-drop-duplicates/">pandas drop_duplicates()の使い方｜subset・keepで重複行を削除</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<style>
  .colab-article pre.line-numbers,
  .colab-article pre.colab-output {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    padding: 1em;
  }
  .colab-article .table-scroll {
    overflow-x: auto;
    margin: 0;
  }
  .colab-article table.wp-block-table {
    width: auto;
    border-collapse: collapse;
  }
  .colab-article table.wp-block-table th,
  .colab-article table.wp-block-table td {
    border: 1px solid #cbd5e1;
    white-space: nowrap;
    padding: 0.2em 0.4em;
  }
  .colab-article table.wp-block-table th {
    background-color: #f8fafc;
    font-weight: 700;
  }
  .colab-article table.wp-block-table th:first-child,
  .colab-article table.wp-block-table td:first-child {
    min-width: 3em;
  }
</style>
<div class="colab-article">

<p>pandasで売上データを整理していると、同じ注文IDが複数行に現れることがあります。しかし、値が重複しているからといって、すぐ削除してよいとは限りません。完全な二重登録だけでなく、金額を訂正した更新後の記録が混ざっている可能性もあるためです。</p>
<p><code>drop_duplicates()</code>は、重複の正誤を自動判定するメソッドではありません。<strong>先に<code>duplicated(keep=False)</code>で候補を確認し、<code>subset</code>で同一レコードの基準、<code>keep</code>で残す記録を決めてから削除する</strong>のが基本です。</p>
<p>この記事では、注文データを使って、重複候補の確認から削除、削除後の検算までをGoogle Colabで順番に実行します。最後には、自分のデータで「なぜこの行を残したか」を説明できる状態を目指します。</p>
<h2><span id="toc1">この記事でわかること</span></h2>
<ul>
  <li><code>duplicated()</code>と<code>drop_duplicates()</code>の役割の違い</li>
  <li><code>subset</code>で重複を判定する列を選ぶ方法</li>
  <li><code>keep='first'</code>・<code>keep='last'</code>・<code>keep=False</code>の選び方</li>
  <li>更新日時を確認して最新の記録を残す方法</li>
  <li>削除前後の行数・残った値・重複件数を検算する方法</li>
  <li>重複が消えない、消えすぎる、元のDataFrameへ反映されない場合の確認方法</li>
</ul>
<p><code>drop_duplicates()</code>は、データ分析の「読み込み→状態確認→前処理→集計」のうち、<strong>集計前の前処理</strong>で使います。前処理全体の順序を先に確認したい場合は、<a href="https://pythondatalab.com/pandas-preprocessing-basic/">Pandasデータ前処理の基本</a>を参照してください。</p>
<h2><span id="toc2">先に結論：判定列と残す行を決めてから削除する</span></h2>
<p>重複削除では、次の2点を先に決めます。</p>
<ol>
  <li><strong>どの列が同じなら同一レコードとみなすか</strong>：<code>subset</code>で指定する</li>
  <li><strong>重複した記録のどれを残すか</strong>：<code>keep</code>で指定する</li>
</ol>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>判断したいこと</th>
        <th>選ぶ設定</th>
        <th>適する場面</th>
        <th>注意点</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>全列が同じ行だけを削除したい</td>
        <td><code>subset</code>を指定しない</td>
        <td>完全なコピー行を除く</td>
        <td>一部の値が違う更新記録は残る</td>
      </tr>
      <tr>
        <td>注文IDなど特定列で判定したい</td>
        <td><code>subset='注文ID'</code></td>
        <td>1注文1行に整理する</td>
        <td>注文明細が複数行なら消しすぎる</td>
      </tr>
      <tr>
        <td>最初の行を残したい</td>
        <td><code>keep='first'</code></td>
        <td>先着記録を正とする</td>
        <td>デフォルトだが、最初が正しいとは限らない</td>
      </tr>
      <tr>
        <td>最後の行を残したい</td>
        <td><code>keep='last'</code></td>
        <td>最新記録を残す</td>
        <td>先に更新日時で並べる必要がある</td>
      </tr>
      <tr>
        <td>重複したグループを全行除外したい</td>
        <td><code>keep=False</code></td>
        <td>重複群を保留対象にする</td>
        <td>1行も残らない</td>
      </tr>
    </tbody>
  </table>
</div>
<p>正しい記録を判断できない場合は、削除せず候補を別のDataFrameへ取り出して確認します。</p>
<h2><span id="toc3">注文データを用意して処理前の状態を確認する</span></h2>
<h3><span id="toc4">実行目的</span></h3>
<p>完全に同じ行と、注文IDは同じでも売上・更新日時が異なる行を含むDataFrameを作ります。以降は同じデータを使うため、コード、表、出力の違いを追いやすくなります。</p>
<pre class="line-numbers language-python"><code class="language-python">import pandas as pd

orders = pd.DataFrame({
    "注文ID": ["A100", "A101", "A100", "A102", "A101", "A103", "A104", "A104"],
    "商品": ["ペン", "ノート", "ペン", "ファイル", "ノート", "消しゴム", "ペン", "ペン"],
    "売上": [1200, 800, 1200, 500, 900, 300, 600, 600],
    "更新日時": [
        "2026-09-01 09:00", "2026-09-01 10:00", "2026-09-01 09:00",
        "2026-09-02 11:00", "2026-09-03 15:00", "2026-09-03 16:00",
        "2026-09-04 10:00", "2026-09-04 10:00"
    ]
})

orders["更新日時"] = pd.to_datetime(orders["更新日時"])
display(orders)
print("処理前の行数:", len(orders))
print("更新日時のdtype:", orders["更新日時"].dtype)
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
      <th>更新日時</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A100</td>
      <td>ペン</td>
      <td>1200</td>
      <td>2026-09-01 09:00:00</td>
    </tr>
    <tr>
      <td>1</td>
      <td>A101</td>
      <td>ノート</td>
      <td>800</td>
      <td>2026-09-01 10:00:00</td>
    </tr>
    <tr>
      <td>2</td>
      <td>A100</td>
      <td>ペン</td>
      <td>1200</td>
      <td>2026-09-01 09:00:00</td>
    </tr>
    <tr>
      <td>3</td>
      <td>A102</td>
      <td>ファイル</td>
      <td>500</td>
      <td>2026-09-02 11:00:00</td>
    </tr>
    <tr>
      <td>4</td>
      <td>A101</td>
      <td>ノート</td>
      <td>900</td>
      <td>2026-09-03 15:00:00</td>
    </tr>
    <tr>
      <td>5</td>
      <td>A103</td>
      <td>消しゴム</td>
      <td>300</td>
      <td>2026-09-03 16:00:00</td>
    </tr>
    <tr>
      <td>6</td>
      <td>A104</td>
      <td>ペン</td>
      <td>600</td>
      <td>2026-09-04 10:00:00</td>
    </tr>
    <tr>
      <td>7</td>
      <td>A104</td>
      <td>ペン</td>
      <td>600</td>
      <td>2026-09-04 10:00:00</td>
    </tr>
  </tbody>
</table>
</div>
<pre class="colab-output">処理前の行数: 8
更新日時のdtype: datetime64[ns]</pre>
<p><code>orders</code>は8行です。注文ID<code>A100</code>と<code>A104</code>は全列が同じ完全重複です。<code>A101</code>は2行ありますが、売上が800から900へ変わり、更新日時も異なります。</p>
<p>ここで見るべきなのは、注文IDだけではありません。<code>A101</code>の2行は更新前後の記録と考えられるため、どちらを残すか判断するには<code>更新日時</code>も必要です。</p>
<h2><span id="toc5">削除前にduplicated()で重複候補をすべて確認する</span></h2>
<h3><span id="toc6">実行目的</span></h3>
<p><code>drop_duplicates()</code>で消す前に、注文IDが重複する行をすべて表示します。<code>keep=False</code>は、重複グループの先頭行も含めてすべて<code>True</code>にする指定です。</p>
<pre class="line-numbers language-python"><code class="language-python">duplicate_mask = orders.duplicated(subset="注文ID", keep=False)
duplicate_candidates = orders.loc[duplicate_mask].sort_values(
    ["注文ID", "更新日時"]
)

display(duplicate_candidates)
print("重複候補の行数:", duplicate_mask.sum())
print("重複している注文ID:", duplicate_candidates["注文ID"].unique().tolist())
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
      <th>更新日時</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A100</td>
      <td>ペン</td>
      <td>1200</td>
      <td>2026-09-01 09:00:00</td>
    </tr>
    <tr>
      <td>2</td>
      <td>A100</td>
      <td>ペン</td>
      <td>1200</td>
      <td>2026-09-01 09:00:00</td>
    </tr>
    <tr>
      <td>1</td>
      <td>A101</td>
      <td>ノート</td>
      <td>800</td>
      <td>2026-09-01 10:00:00</td>
    </tr>
    <tr>
      <td>4</td>
      <td>A101</td>
      <td>ノート</td>
      <td>900</td>
      <td>2026-09-03 15:00:00</td>
    </tr>
    <tr>
      <td>6</td>
      <td>A104</td>
      <td>ペン</td>
      <td>600</td>
      <td>2026-09-04 10:00:00</td>
    </tr>
    <tr>
      <td>7</td>
      <td>A104</td>
      <td>ペン</td>
      <td>600</td>
      <td>2026-09-04 10:00:00</td>
    </tr>
  </tbody>
</table>
</div>
<pre class="colab-output">重複候補の行数: 6
重複している注文ID: ['A100', 'A101', 'A104']</pre>
<p>重複候補は6行で、注文IDは<code>A100</code>・<code>A101</code>・<code>A104</code>です。<code>A100</code>と<code>A104</code>は完全重複ですが、<code>A101</code>は売上と更新日時が違います。</p>
<p><code>duplicated()</code>は候補をTrue／Falseで<strong>確認</strong>し、<code>drop_duplicates()</code>は条件に合う行を実際に<strong>削除</strong>します。詳しい真偽値の読み方は、<a href="https://pythondatalab.com/pandas-duplicated/">pandas duplicated()の使い方</a>で確認できます。</p>
<h2><span id="toc7">引数なしでは全列が同じ行だけを削除する</span></h2>
<h3><span id="toc8">実行目的</span></h3>
<p>まず、すべての列が一致する完全重複だけを削除します。元データを残すため、結果を<code>exact_clean</code>という別のDataFrameへ代入します。</p>
<pre class="line-numbers language-python"><code class="language-python">exact_clean = orders.drop_duplicates()

display(exact_clean)
print("処理前の行数:", len(orders))
print("処理後の行数:", len(exact_clean))
print("削除した行数:", len(orders) - len(exact_clean))
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
      <th>更新日時</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A100</td>
      <td>ペン</td>
      <td>1200</td>
      <td>2026-09-01 09:00:00</td>
    </tr>
    <tr>
      <td>1</td>
      <td>A101</td>
      <td>ノート</td>
      <td>800</td>
      <td>2026-09-01 10:00:00</td>
    </tr>
    <tr>
      <td>3</td>
      <td>A102</td>
      <td>ファイル</td>
      <td>500</td>
      <td>2026-09-02 11:00:00</td>
    </tr>
    <tr>
      <td>4</td>
      <td>A101</td>
      <td>ノート</td>
      <td>900</td>
      <td>2026-09-03 15:00:00</td>
    </tr>
    <tr>
      <td>5</td>
      <td>A103</td>
      <td>消しゴム</td>
      <td>300</td>
      <td>2026-09-03 16:00:00</td>
    </tr>
    <tr>
      <td>6</td>
      <td>A104</td>
      <td>ペン</td>
      <td>600</td>
      <td>2026-09-04 10:00:00</td>
    </tr>
  </tbody>
</table>
</div>
<pre class="colab-output">処理前の行数: 8
処理後の行数: 6
削除した行数: 2</pre>
<p>8行から6行になり、完全に同じ<code>A100</code>と<code>A104</code>の2行目が削除されます。一方、<code>A101</code>は売上と更新日時が異なるため2行とも残ります。</p>
<p><strong>「注文IDが同じなら1行にしたい」場合、引数なしでは目的を達成できません。</strong> 次に<code>subset</code>で判定列を指定します。</p>
<h2><span id="toc9">subsetで重複を判定する列を選ぶ</span></h2>
<p><code>subset</code>には列名を1つ、または列名のリストを指定できます。</p>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>指定</th>
        <th>重複とみなす条件</th>
        <th>このデータでの意味</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>指定なし</td>
        <td>全列が一致</td>
        <td>完全なコピー行だけを削除</td>
      </tr>
      <tr>
        <td><code>subset='注文ID'</code></td>
        <td>注文IDが一致</td>
        <td>1注文を1行にする</td>
      </tr>
      <tr>
        <td><code>subset=['注文ID', '商品']</code></td>
        <td>注文IDと商品が両方一致</td>
        <td>注文と商品単位で1行にする</td>
      </tr>
    </tbody>
  </table>
</div>
<p>実データでは、注文IDが「注文全体」を表すのか「注文明細」を表すのかを確認してください。1つの注文IDに複数商品が正しく含まれるデータで<code>subset='注文ID'</code>を使うと、必要な明細まで消してしまいます。</p>
<h3><span id="toc10">実行目的</span></h3>
<p>注文IDを同一レコードの基準として、各注文を1行にします。まずはデフォルトの<code>keep='first'</code>で先頭行を残します。</p>
<pre class="line-numbers language-python"><code class="language-python">first_clean = orders.drop_duplicates(subset="注文ID", keep="first")
display(first_clean)
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
      <th>更新日時</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A100</td>
      <td>ペン</td>
      <td>1200</td>
      <td>2026-09-01 09:00:00</td>
    </tr>
    <tr>
      <td>1</td>
      <td>A101</td>
      <td>ノート</td>
      <td>800</td>
      <td>2026-09-01 10:00:00</td>
    </tr>
    <tr>
      <td>3</td>
      <td>A102</td>
      <td>ファイル</td>
      <td>500</td>
      <td>2026-09-02 11:00:00</td>
    </tr>
    <tr>
      <td>5</td>
      <td>A103</td>
      <td>消しゴム</td>
      <td>300</td>
      <td>2026-09-03 16:00:00</td>
    </tr>
    <tr>
      <td>6</td>
      <td>A104</td>
      <td>ペン</td>
      <td>600</td>
      <td>2026-09-04 10:00:00</td>
    </tr>
  </tbody>
</table>
</div>
<p><code>A101</code>は先に現れた売上800の行が残ります。コードは正常に動いていますが、更新後の売上900を残したい場合には誤った結果です。<code>first</code>は「正しい行」ではなく、<strong>現在の並び順で最初の行</strong>を意味します。</p>
<h2><span id="toc11">複数列の組み合わせで重複を判定する</span></h2>
<p>注文IDだけで判定すると、1つの注文に含まれる別の商品まで削除することがあります。注文明細を商品単位で残す場合は、<code>subset</code>へ複数の列をリストで指定します。</p>
<pre class="line-numbers language-python"><code class="language-python">detail_orders = pd.DataFrame({
    "注文ID": ["A300", "A300", "A300", "A301"],
    "商品": ["ペン", "ノート", "ペン", "ファイル"],
    "売上": [200, 500, 200, 800]
})

order_only = detail_orders.drop_duplicates(subset="注文ID")
order_and_product = detail_orders.drop_duplicates(
    subset=["注文ID", "商品"],
    keep="first",
    ignore_index=True
)

print("処理前")
display(detail_orders)
print("注文IDだけで判定した結果")
display(order_only)
print("注文IDと商品で判定した結果")
display(order_and_product)
</code></pre>
<pre class="colab-output">処理前</pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A300</td>
      <td>ペン</td>
      <td>200</td>
    </tr>
    <tr>
      <td>1</td>
      <td>A300</td>
      <td>ノート</td>
      <td>500</td>
    </tr>
    <tr>
      <td>2</td>
      <td>A300</td>
      <td>ペン</td>
      <td>200</td>
    </tr>
    <tr>
      <td>3</td>
      <td>A301</td>
      <td>ファイル</td>
      <td>800</td>
    </tr>
  </tbody>
</table>
</div>
<pre class="colab-output">注文IDだけで判定した結果</pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A300</td>
      <td>ペン</td>
      <td>200</td>
    </tr>
    <tr>
      <td>3</td>
      <td>A301</td>
      <td>ファイル</td>
      <td>800</td>
    </tr>
  </tbody>
</table>
</div>
<pre class="colab-output">注文IDと商品で判定した結果</pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A300</td>
      <td>ペン</td>
      <td>200</td>
    </tr>
    <tr>
      <td>1</td>
      <td>A300</td>
      <td>ノート</td>
      <td>500</td>
    </tr>
    <tr>
      <td>2</td>
      <td>A301</td>
      <td>ファイル</td>
      <td>800</td>
    </tr>
  </tbody>
</table>
</div>
<p><code>subset="注文ID"</code>では、注文<code>A300</code>の最初の「ペン」だけが残り、正しい明細である「ノート」まで消えます。<code>subset=["注文ID", "商品"]</code>では、注文IDと商品の組み合わせが同じ「ペン」の重複だけを削除し、「ノート」は残ります。</p>
<p>この結果から、<code>subset</code>は列数を増やせば安全になるのではなく、<strong>データの1行が何を表すかに合わせて選ぶ</strong>必要があると分かります。</p>
<h2><span id="toc12">keepで残す行を選ぶ</span></h2>
<p>同じ入力データで<code>keep</code>だけを変え、残る行を比較します。</p>
<h3><span id="toc13">実行目的</span></h3>
<p><code>first</code>・<code>last</code>・<code>False</code>の結果から、<code>A101</code>と重複グループ全体がどう変わるかを確認します。</p>
<pre class="line-numbers language-python"><code class="language-python">keep_first = orders.drop_duplicates(subset="注文ID", keep="first")
keep_last = orders.drop_duplicates(subset="注文ID", keep="last")
keep_none = orders.drop_duplicates(subset="注文ID", keep=False)

comparison = pd.DataFrame({
    "設定": ["first", "last", "False"],
    "残る注文ID": [
        keep_first["注文ID"].tolist(),
        keep_last["注文ID"].tolist(),
        keep_none["注文ID"].tolist()
    ],
    "A101で残る売上": [
        keep_first.loc[keep_first["注文ID"].eq("A101"), "売上"].tolist(),
        keep_last.loc[keep_last["注文ID"].eq("A101"), "売上"].tolist(),
        keep_none.loc[keep_none["注文ID"].eq("A101"), "売上"].tolist()
    ]
})

display(comparison)
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>設定</th>
      <th>残る注文ID</th>
      <th>A101で残る売上</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>first</td>
      <td>[A100, A101, A102, A103, A104]</td>
      <td>[800]</td>
    </tr>
    <tr>
      <td>1</td>
      <td>last</td>
      <td>[A100, A102, A101, A103, A104]</td>
      <td>[900]</td>
    </tr>
    <tr>
      <td>2</td>
      <td>False</td>
      <td>[A102, A103]</td>
      <td>[]</td>
    </tr>
  </tbody>
</table>
</div>
<p><code>first</code>では<code>A101</code>の800、<code>last</code>では900が残ります。<code>False</code>では重複した<code>A100</code>・<code>A101</code>・<code>A104</code>が全行消え、重複しない<code>A102</code>・<code>A103</code>だけが残ります。</p>
<p><code>keep=False</code>は「2行目以降を削除」ではありません。<strong>重複グループを1行も残さない</strong>指定です。重複データを保留用に分ける場合には使えますが、各注文を1行残したい処理では選びません。</p>
<h2><span id="toc14">最新の行を残すなら更新日時で並べてからkeep=&#8217;last&#8217;を使う</span></h2>
<p><code>keep='last'</code>の<code>last</code>は、時間的に最新という意味ではなく、現在の行順で最後という意味です。更新日時が文字列のまま、またはデータが順不同のままでは、古い記録を残す可能性があります。</p>
<h3><span id="toc15">実行目的</span></h3>
<p>更新日時を日時型にしたことを確認し、注文IDと更新日時で並べた後、注文ごとの最新行を残します。</p>
<pre class="line-numbers language-python"><code class="language-python">print("更新日時のdtype:", orders["更新日時"].dtype)
print("更新日時の欠損数:", orders["更新日時"].isna().sum())

orders_sorted = orders.sort_values(["注文ID", "更新日時"])
latest_orders = orders_sorted.drop_duplicates(
    subset="注文ID",
    keep="last",
    ignore_index=True
)

display(latest_orders)
</code></pre>
<pre class="colab-output">更新日時のdtype: datetime64[ns]
更新日時の欠損数: 0</pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>売上</th>
      <th>更新日時</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>A100</td>
      <td>ペン</td>
      <td>1200</td>
      <td>2026-09-01 09:00:00</td>
    </tr>
    <tr>
      <td>1</td>
      <td>A101</td>
      <td>ノート</td>
      <td>900</td>
      <td>2026-09-03 15:00:00</td>
    </tr>
    <tr>
      <td>2</td>
      <td>A102</td>
      <td>ファイル</td>
      <td>500</td>
      <td>2026-09-02 11:00:00</td>
    </tr>
    <tr>
      <td>3</td>
      <td>A103</td>
      <td>消しゴム</td>
      <td>300</td>
      <td>2026-09-03 16:00:00</td>
    </tr>
    <tr>
      <td>4</td>
      <td>A104</td>
      <td>ペン</td>
      <td>600</td>
      <td>2026-09-04 10:00:00</td>
    </tr>
  </tbody>
</table>
</div>
<p><code>A101</code>では更新日時が新しい売上900の行が残ります。<code>ignore_index=True</code>により、削除後のインデックスは0から4へ振り直されます。これは重複判定を変える指定ではなく、結果のインデックスを整える指定です。</p>
<p>更新日時に欠損がある場合や、どの記録が正しいか判断できない場合は、自動削除しないでください。日付文字列の変換方法は、<a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方</a>で確認できます。</p>
<h2><span id="toc16">削除後は行数・残った値・重複件数を検算する</span></h2>
<h3><span id="toc17">実行目的</span></h3>
<p>「エラーが出なかった」だけで終わらせず、削除行数、残った<code>A101</code>の売上、残存する注文ID重複を確認します。</p>
<pre class="line-numbers language-python"><code class="language-python">before_rows = len(orders)
after_rows = len(latest_orders)
removed_rows = before_rows - after_rows
remaining_duplicates = latest_orders.duplicated(
    subset="注文ID", keep=False
).sum()
a101_sales = latest_orders.loc[
    latest_orders["注文ID"].eq("A101"), "売上"
].iloc[0]

validation = pd.DataFrame({
    "確認項目": ["処理前の行数", "削除した行数", "処理後の行数", "残存する重複行数", "A101で残った売上"],
    "結果": [before_rows, removed_rows, after_rows, remaining_duplicates, a101_sales]
})

display(validation)
print("行数の式が一致:", before_rows - removed_rows == after_rows)
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>確認項目</th>
      <th>結果</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>処理前の行数</td>
      <td>8</td>
    </tr>
    <tr>
      <td>1</td>
      <td>削除した行数</td>
      <td>3</td>
    </tr>
    <tr>
      <td>2</td>
      <td>処理後の行数</td>
      <td>5</td>
    </tr>
    <tr>
      <td>3</td>
      <td>残存する重複行数</td>
      <td>0</td>
    </tr>
    <tr>
      <td>4</td>
      <td>A101で残った売上</td>
      <td>900</td>
    </tr>
  </tbody>
</table>
</div>
<pre class="colab-output">行数の式が一致: True</pre>
<p>処理前8行から3行を削除し、処理後は5行です。注文IDの残存重複行数は0、<code>A101</code>で残った売上は900です。行数の式も<code>True</code>になっています。</p>
<p>ただし、重複数が0でも判定列が正しいとは限りません。最終的には「注文IDだけで1レコードを表せるか」をデータの意味から確認してください。</p>
<h2><span id="toc18">よくある失敗を現象から確認・修正する</span></h2>
<h3><span id="toc19">重複が消えない</span></h3>
<ul>
  <li><strong>現象</strong>：見た目は同じ値なのに、<code>drop_duplicates()</code>後も複数行が残る</li>
  <li><strong>主な原因</strong>：前後空白、大文字・小文字、数値と文字列の型違い、<code>subset</code>の指定違い</li>
  <li><strong>確認方法</strong>：<code>df.dtypes</code>、<code>df.columns.tolist()</code>、<code>repr()</code>相当の表示、<code>duplicated(subset=..., keep=False)</code>で候補を確認する</li>
  <li><strong>修正方法</strong>：必要な列だけ空白・表記・型をそろえ、同じ<code>subset</code>で再確認してから削除する</li>
  <li><strong>修正後の確認</strong>：削除後に同じ<code>subset</code>で<code>duplicated(keep=False).sum()</code>が想定件数になったか確認する</li>
</ul>
<h3><span id="toc20">必要な行まで消えた</span></h3>
<ul>
  <li><strong>現象</strong>：正しい注文明細や異なる観測まで削除された</li>
  <li><strong>主な原因</strong>：<code>subset</code>が粗すぎる、または<code>keep=False</code>を使った</li>
  <li><strong>確認方法</strong>：削除前データから重複候補を全件表示し、判定列以外の値を比較する</li>
  <li><strong>修正方法</strong>：商品・明細番号など必要な列を<code>subset</code>へ追加する。各グループを1行残すなら<code>first</code>または<code>last</code>を選ぶ</li>
  <li><strong>修正後の確認</strong>：削除した行と残った行を注文IDごとに照合する</li>
</ul>
<h3><span id="toc21">最新ではない行が残った</span></h3>
<ul>
  <li><strong>現象</strong>：<code>keep='last'</code>を使ったのに古い値が残る</li>
  <li><strong>主な原因</strong>：<code>last</code>を「最新」と誤解し、更新日時で並べていない</li>
  <li><strong>確認方法</strong>：更新日時のdtype、欠損数、並び順を表示する</li>
  <li><strong>修正方法</strong>：<code>to_datetime()</code>で日時型へ変換し、更新日時で並べてから<code>keep='last'</code>を実行する</li>
  <li><strong>修正後の確認</strong>：重複していたIDの更新日時と残った値を個別に確認する</li>
</ul>
<h3><span id="toc22">元のDataFrameへ反映されない</span></h3>
<ul>
  <li><strong>現象</strong>：メソッドを実行した後も元の行数が変わらない</li>
  <li><strong>主な原因</strong>：<code>drop_duplicates()</code>は既定で新しいDataFrameを返し、元データを変更しない</li>
  <li><strong>確認方法</strong>：戻り値を変数へ代入したか確認する</li>
  <li><strong>修正方法</strong>：<code>clean_df = df.drop_duplicates(...)</code>のように別変数へ代入する</li>
  <li><strong>修正後の確認</strong>：<code>len(df)</code>と<code>len(clean_df)</code>を比較する</li>
</ul>
<p><code>inplace=True</code>でも変更できますが、初心者は元データと処理後データを比較できるよう、まず別変数への代入をおすすめします。</p>
<h2><span id="toc23">NaNを含む判定列は削除前に意味を確認する</span></h2>
<p>欠損した注文IDが複数あると、それらが重複候補として扱われる場合があります。しかし「注文ID不明」が同じ注文を意味するとは限りません。実際の挙動を確認します。</p>
<pre class="line-numbers language-python"><code class="language-python">missing_id_sample = pd.DataFrame({
    "注文ID": [None, None, "A200"],
    "商品": ["ペン", "ノート", "ファイル"]
})

missing_id_sample["重複候補"] = missing_id_sample.duplicated(
    subset="注文ID", keep=False
)
display(missing_id_sample)
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>注文ID</th>
      <th>商品</th>
      <th>重複候補</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>None</td>
      <td>ペン</td>
      <td>True</td>
    </tr>
    <tr>
      <td>1</td>
      <td>None</td>
      <td>ノート</td>
      <td>True</td>
    </tr>
    <tr>
      <td>2</td>
      <td>A200</td>
      <td>ファイル</td>
      <td>False</td>
    </tr>
  </tbody>
</table>
</div>
<p>2つの欠損した注文IDは重複候補になります。ただし、商品が異なるため、同一注文と断定して削除すると情報を失うおそれがあります。判定列に欠損がある場合は、欠損行を別に確認し、補完・保持・除外の方針を決めてください。欠損行の削除は重複行削除とは別の処理です。詳しくは<a href="https://pythondatalab.com/pandas-drop/">Pandas dropna()の使い方</a>を参照してください。</p>
<h2><span id="toc24">自分のDataFrameへ置き換える前のチェックリスト</span></h2>
<ul>
  <li><code>subset</code>に指定する列は、業務上の同一レコードを表しているか</li>
  <li>1つのIDに複数明細が存在してよいデータではないか</li>
  <li>残す行を決める更新日時・状態・優先順位の列があるか</li>
  <li>更新日時は日時型か、欠損していないか、正しく並んでいるか</li>
  <li>判定列に前後空白、表記ゆれ、型違い、NaNがないか</li>
  <li>元DataFrameを残し、処理後を別変数へ保存したか</li>
  <li>削除前後の行数、残った値、残存重複数を確認したか</li>
  <li>集計値が想定外に減っていないか</li>
</ul>
<p>判断根拠がない重複候補は、削除せず別DataFrameへ取り出して確認してください。</p>
<h2><span id="toc25">重複を削除したデータを集計へつなげる</span></h2>
<h3><span id="toc26">実行目的</span></h3>
<p>重複除去後の注文データを商品別に集計し、二重計上のない件数と売上合計を確認します。</p>
<pre class="line-numbers language-python"><code class="language-python">product_summary = (
    latest_orders.groupby("商品", as_index=False)
    .agg(注文件数=("注文ID", "count"), 売上合計=("売上", "sum"))
    .sort_values("売上合計", ascending=False, ignore_index=True)
)

display(product_summary)
print("集計した注文件数:", product_summary["注文件数"].sum())
print("重複除去後の売上合計:", product_summary["売上合計"].sum())
</code></pre>
<div class="table-scroll">
<table class="wp-block-table">
  <thead>
    <tr>
      <th></th>
      <th>商品</th>
      <th>注文件数</th>
      <th>売上合計</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>ペン</td>
      <td>2</td>
      <td>1800</td>
    </tr>
    <tr>
      <td>1</td>
      <td>ノート</td>
      <td>1</td>
      <td>900</td>
    </tr>
    <tr>
      <td>2</td>
      <td>ファイル</td>
      <td>1</td>
      <td>500</td>
    </tr>
    <tr>
      <td>3</td>
      <td>消しゴム</td>
      <td>1</td>
      <td>300</td>
    </tr>
  </tbody>
</table>
</div>
<pre class="colab-output">集計した注文件数: 5
重複除去後の売上合計: 3500</pre>
<p>集計した注文件数は5件、売上合計は3,500です。<code>latest_orders</code>の5行と件数が一致します。重複削除後は、件数だけでなく合計値も確認すると、削除しすぎや二重計上に気づきやすくなります。</p>
<p>複数列・複数集計へ進む場合は、<a href="https://pythondatalab.com/pandas-groupby-agg/">pandas groupby・aggの使い方</a>を参照してください。</p>
<h2><span id="toc27">まとめ</span></h2>
<ul>
  <li><code>drop_duplicates()</code>の前に<code>duplicated(keep=False)</code>で重複候補を確認する</li>
  <li><code>subset</code>は「何を同一レコードとみなすか」で選ぶ</li>
  <li><code>keep</code>は「どの記録を正として残すか」で選ぶ</li>
  <li>最新行を残す場合は、更新日時を日時型へ変換し、並べてから<code>keep='last'</code>を使う</li>
  <li><code>keep=False</code>は重複グループを全行削除するため、目的を確認して使う</li>
  <li>削除後は行数、残った値、残存重複数、集計値を検算する</li>
  <li>判断できない候補は自動削除せず、元データを残して確認する</li>
</ul>
<p>重複削除の目的は、単に行数を減らすことではありません。分析に使う正しい観測単位を決め、集計の二重計上や必要データの消失を防ぐことです。</p>
<h2><span id="toc28">関連記事</span></h2>
<ul>
  <li><a href="https://pythondatalab.com/pandas-duplicated/">pandas duplicated()の使い方｜重複行の確認・subset・keepを初心者向けに解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-preprocessing-basic/">Pandasデータ前処理の基本｜読み込み後に確認する順番と欠損・型・重複の選び方</a></li>
  <li><a href="https://pythondatalab.com/pandas-drop/">Pandas dropna()の使い方</a></li>
  <li><a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方｜文字列の日付変換とformat・NaT対処</a></li>
  <li><a href="https://pythondatalab.com/pandas-reset-index/">pandas reset_index()の使い方｜インデックスを振り直す・drop=Trueを解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-groupby-agg/">pandas groupby・aggの使い方｜複数列・複数集計と結果の見方</a></li>
</ul>
 <!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc29"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1789141189292" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc30">drop_duplicates()とduplicated()の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p><code>duplicated()</code>は重複候補をTrue／Falseで確認するメソッド、<code>drop_duplicates()</code>は重複行を除いたDataFrameを返すメソッドです。安全に処理するには、先に<code>duplicated(keep=False)</code>で全候補を表示してから削除します。</p>

</div>
</div>
<div id="faq-question-1789141250765" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc31">複数列が同じ行だけを削除するにはどうしますか？</span></h3>
<div class="rank-math-answer ">

<p><code>subset=['注文ID', '商品']</code>のように列名をリストで指定します。指定した列がすべて同じ行が重複と判定されます。列を増やす前に、それらが業務上の同一レコードを表すか確認してください。</p>

</div>
</div>
<div id="faq-question-1789141259683" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc32">最新の行だけを残すにはどうしますか？</span></h3>
<div class="rank-math-answer ">

<p>更新日時を日時型へ変換し、古い順に並べてから<code>keep='last'</code>を使います。<code>last</code>は現在の行順で最後という意味なので、並べ替えずに使っても最新行が残るとは限りません。</p>

</div>
</div>
<div id="faq-question-1789141272385" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc33">実行しても元のDataFrameが変わらないのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p><code>drop_duplicates()</code>は既定で新しいDataFrameを返すためです。<code>clean_df = df.drop_duplicates(...)</code>のように戻り値を代入してください。元データを残せるため、処理前後の比較もしやすくなります。</p>

</div>
</div>
<div id="faq-question-1789141284187" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc34">NaNを含む行はどう判定されますか？</span></h3>
<div class="rank-math-answer ">

<p>判定列で欠損値が重なる行は重複候補になり得ます。ただし、欠損値同士が同じ実体を示すとは限りません。削除前に欠損行を表示し、同一レコードとして扱ってよいかデータの意味から判断してください。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-drop-duplicates/">pandas drop_duplicates()の使い方｜subset・keepで重複行を削除</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-drop-duplicates/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas to_csv()の使い方｜indexなし・文字化け対策・保存先を解説</title>
		<link>https://pythondatalab.com/pandas-to-csv/</link>
					<comments>https://pythondatalab.com/pandas-to-csv/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Thu, 10 Sep 2026 15:14:30 +0000</pubDate>
				<category><![CDATA[基礎]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2206</guid>

					<description><![CDATA[<p>pandasのto_csv()でDataFrameをCSVに保存する方法を初心者向けに解説。index=False、文字化けを防ぐencoding、保存先、列指定、上書き・追記、保存後の確認方法までGoogle Colabで学べます。</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-to-csv/">pandas to_csv()の使い方｜indexなし・文字化け対策・保存先を解説</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<style>
  .colab-article pre.line-numbers,
  .colab-article pre.colab-output {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    padding: 1em;
  }
  .colab-article .table-scroll {
    overflow-x: auto;
    margin: 0;
  }
  .colab-article table.wp-block-table {
    width: auto;
    border-collapse: collapse;
  }
  .colab-article table.wp-block-table th,
  .colab-article table.wp-block-table td {
    border: 1px solid #cbd5e1;
    white-space: nowrap;
    padding: 0.2em 0.4em;
  }
  .colab-article table.wp-block-table th {
    background-color: #f8fafc;
    font-weight: 700;
  }
  .colab-article table.wp-block-table th:first-child,
  .colab-article table.wp-block-table td:first-child {
    min-width: 3em;
  }
</style>
<div class="colab-article">

<p>pandasで前処理や集計を終えたあと、「DataFrameをCSVに保存したいのに、ファイルがどこにあるか分からない」「開いたら左端に余計な列が増えた」「日本語が文字化けした」と困ることがあります。</p>
<p>DataFrameをCSVへ保存する基本形は、次の1行です。</p>
<pre class="line-numbers language-python"><code class="language-python">df.to_csv("sales.csv", index=False)</code></pre>
<p>ただし、正しく再利用できるCSVにするには、コードを書く前に次の順で決めることが大切です。</p>
<ol>
  <li><strong>どこへ保存するか</strong></li>
  <li><strong>インデックスを残すか</strong></li>
  <li><strong>どのアプリで開くかに応じて文字コードを選ぶ</strong></li>
  <li><strong>どの列を保存するか</strong></li>
  <li><strong>同名ファイルを上書きしてよいか</strong></li>
</ol>
<p>この記事では、Google Colabで再現できる売上データを使い、保存されたCSVをもう一度読み込んで、行数・列名・日本語が正しいところまで確認します。</p>
<h2><span id="toc1">この記事でわかること</span></h2>
<ul>
  <li><code>to_csv()</code>でDataFrameをCSVへ保存する基本形</li>
  <li>保存先、<code>index</code>、<code>encoding</code>、<code>columns</code>の選び方</li>
  <li><code>header</code>と<code>sep</code>で出力形式を変える方法</li>
  <li>余計な<code>Unnamed: 0</code>、文字化け、保存先不明、上書きの確認方法</li>
  <li><code>read_csv()</code>で読み込み直し、保存結果を検算する方法</li>
</ul>
<p><code>to_csv()</code>は、<strong>前処理・抽出・集計した結果を、共有や再利用のためにファイルへ書き出す処理</strong>です。データを整える前工程は、<a href="https://pythondatalab.com/pandas-preprocessing-basic/">Pandasデータ前処理の基本</a>で確認できます。</p>
<h2><span id="toc2">先に結論：保存先→index→文字コード→列→上書きの順に決める</span></h2>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>確認すること</th>
        <th>選ぶ基準</th>
        <th>主な指定</th>
        <th>注意点</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>保存先</td>
        <td>Colab終了後も残すか</td>
        <td>一時領域の相対パス／Google Driveの絶対パス</td>
        <td>Colabの一時領域はランタイム終了後に消える</td>
      </tr>
      <tr>
        <td>インデックス</td>
        <td>行ラベルに意味があるか</td>
        <td>通常は<code>index=False</code></td>
        <td>顧客IDなど意味のある値まで消さない</td>
      </tr>
      <tr>
        <td>文字コード</td>
        <td>どのアプリで開くか</td>
        <td>UTF-8／<code>utf-8-sig</code></td>
        <td>受け渡し先の指定があれば従う</td>
      </tr>
      <tr>
        <td>保存列</td>
        <td>全列が必要か</td>
        <td><code>columns=[...]</code></td>
        <td>列名の空白・表記違いに注意する</td>
      </tr>
      <tr>
        <td>書き込み方法</td>
        <td>同名ファイルを上書きしてよいか</td>
        <td>通常保存／<code>mode="x"</code>／<code>mode="a"</code></td>
        <td><code>mode="a"</code>は行の追記であり、値の更新ではない</td>
      </tr>
    </tbody>
  </table>
</div>
<p>最初は、実在する保存先へ<code>index=False</code>で保存し、読み込み直して確認するところから始めるのが安全です。</p>
<h2><span id="toc3">売上DataFrameを用意する</span></h2>
<h3><span id="toc4">実行目的</span></h3>
<p>同じデータを記事全体で使い、設定によってCSVの列や文字コードがどう変わるか比較します。<code>商品ID</code>は通常の列として保持し、DataFrameのインデックスは0から始まる連番です。</p>
<pre class="line-numbers language-python"><code class="language-python">import pandas as pd
from pathlib import Path

# Colabの一時領域または現在の作業フォルダ内に保存用フォルダを作る
output_dir = Path("python_data_lab_output")
output_dir.mkdir(exist_ok=True)

df = pd.DataFrame({
    "商品ID": [101, 102, 103, 104],
    "商品": ["ノート", "ペン", "ファイル", "付箋"],
    "カテゴリ": ["文具", "文具", "収納", "文具"],
    "売上": [1200, 900, 1500, 600],
    "備考": ["重点商品", None, "在庫確認", "新商品"],
})

print(df)
print("行数・列数:", df.shape)</code></pre>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>商品ID</th>
        <th>商品</th>
        <th>カテゴリ</th>
        <th>売上</th>
        <th>備考</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>101</td>
        <td>ノート</td>
        <td>文具</td>
        <td>1200</td>
        <td>重点商品</td>
      </tr>
      <tr>
        <td>1</td>
        <td>102</td>
        <td>ペン</td>
        <td>文具</td>
        <td>900</td>
        <td>None</td>
      </tr>
      <tr>
        <td>2</td>
        <td>103</td>
        <td>ファイル</td>
        <td>収納</td>
        <td>1500</td>
        <td>在庫確認</td>
      </tr>
      <tr>
        <td>3</td>
        <td>104</td>
        <td>付箋</td>
        <td>文具</td>
        <td>600</td>
        <td>新商品</td>
      </tr>
    </tbody>
  </table>
</div>
<pre class="colab-output">行数・列数: (4, 5)</pre>
<p>出力では4行5列なので、<code>shape</code>は<code>(4, 5)</code>です。<code>備考</code>の2行目にある<code>None</code>は欠損値ですが、今回は意味のある未記入として残します。保存のためだけに0や空文字へ置き換えません。</p>
<p>自分のデータでは、保存前に列名・データ型・欠損値を<a href="https://pythondatalab.com/pandas-info-method/">pandas info()の使い方</a>で確認しておくと、保存後の変化を判断しやすくなります。</p>
<h2><span id="toc5">基本：indexなしでCSVへ保存する</span></h2>
<h3><span id="toc6">実行目的</span></h3>
<p>連番インデックスをCSVへ含めず、DataFrameの5列だけを保存します。ファイル名だけを指定した相対パスは、現在の作業場所を基準に解釈されます。ここでは作成済みの<code>python_data_lab_output</code>フォルダへ保存します。</p>
<pre class="line-numbers language-python"><code class="language-python">basic_path = output_dir / "sales_basic.csv"
df.to_csv(basic_path, index=False)

print("保存先:", basic_path)
print("ファイルの存在:", basic_path.exists())
print("保存フォルダ内:", sorted(p.name for p in output_dir.iterdir()))
print("CSVの先頭3行:")
print("\n".join(basic_path.read_text(encoding="utf-8").splitlines()[:3]))</code></pre>
<pre class="colab-output">保存先: python_data_lab_output/sales_basic.csv
ファイルの存在: True
保存フォルダ内: ['sales_basic.csv']
CSVの先頭3行:
商品ID,商品,カテゴリ,売上,備考
101,ノート,文具,1200,重点商品
102,ペン,文具,900,</pre>
<p>最初に見るのは、次の3点です。</p>
<ul>
  <li><code>ファイルの存在</code>が<code>True</code>になっている</li>
  <li>1行目が<code>商品ID,商品,カテゴリ,売上,備考</code>になっている</li>
  <li>左端に0、1のようなDataFrameの連番インデックスが追加されていない</li>
</ul>
<p><code>to_csv()</code>へ保存先を渡した場合、ファイルが作成されます。戻り値を新しいDataFrameとして使うメソッドではありません。</p>
<h2><span id="toc7">index=Trueとindex=Falseの違い</span></h2>
<p><code>to_csv()</code>では、<code>index</code>の既定値が<code>True</code>です。指定を省略すると、DataFrameのインデックスもCSVへ出力されます。</p>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>指定</th>
        <th>CSVの左端</th>
        <th>選ぶ場面</th>
        <th>注意点</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><code>index=True</code>または省略</td>
        <td>インデックスが入る</td>
        <td>行ラベル自体に意味がある</td>
        <td>名前のない連番は再読込時に余計な列になりやすい</td>
      </tr>
      <tr>
        <td><code>index=False</code></td>
        <td>インデックスを入れない</td>
        <td>0始まりの連番が単なる管理番号</td>
        <td>意味のあるIDをインデックスにしている場合は失う</td>
      </tr>
      <tr>
        <td><code>reset_index()</code>後に<code>index=False</code></td>
        <td>意味のあるインデックスを通常列として入れる</td>
        <td>IDを明示的な列名で残したい</td>
        <td>列が重複しないか確認する</td>
      </tr>
    </tbody>
  </table>
</div>
<pre class="line-numbers language-python"><code class="language-python">with_index_path = output_dir / "sales_with_index.csv"
without_index_path = output_dir / "sales_without_index.csv"

df.to_csv(with_index_path)  # index=Trueが既定値
df.to_csv(without_index_path, index=False)

with_index = pd.read_csv(with_index_path)
without_index = pd.read_csv(without_index_path)

print("indexを保存したCSVの列:", with_index.columns.tolist())
print("index=FalseのCSVの列:", without_index.columns.tolist())
print(with_index.head(2))</code></pre>
<pre class="colab-output">indexを保存したCSVの列: ['Unnamed: 0', '商品ID', '商品', 'カテゴリ', '売上', '備考']
index=FalseのCSVの列: ['商品ID', '商品', 'カテゴリ', '売上', '備考']</pre>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>Unnamed: 0</th>
        <th>商品ID</th>
        <th>商品</th>
        <th>カテゴリ</th>
        <th>売上</th>
        <th>備考</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>0</td>
        <td>101</td>
        <td>ノート</td>
        <td>文具</td>
        <td>1200</td>
        <td>重点商品</td>
      </tr>
      <tr>
        <td>1</td>
        <td>1</td>
        <td>102</td>
        <td>ペン</td>
        <td>文具</td>
        <td>900</td>
        <td>NaN</td>
      </tr>
    </tbody>
  </table>
</div>
<p><code>index</code>を省略したCSVを読み込むと、列一覧の先頭に<code>Unnamed: 0</code>が現れます。これは元のデータ列ではなく、列名のない連番インデックスが保存されたものです。</p>
<h3><span id="toc8">意味のあるインデックスは消さない</span></h3>
<p><code>商品ID</code>をインデックスにしたあとで<code>index=False</code>にすると、CSVには商品IDが残りません。商品IDを再利用したい場合は、<code>reset_index()</code>で通常列へ戻してから保存します。</p>
<pre class="line-numbers language-python"><code class="language-python">indexed_df = df.set_index("商品ID")

lost_id_path = output_dir / "sales_id_lost.csv"
kept_id_path = output_dir / "sales_id_kept.csv"

indexed_df.to_csv(lost_id_path, index=False)
indexed_df.reset_index().to_csv(kept_id_path, index=False)

print("index=FalseでIDを消した列:", pd.read_csv(lost_id_path).columns.tolist())
print("IDを通常列へ戻した列:", pd.read_csv(kept_id_path).columns.tolist())</code></pre>
<pre class="colab-output">index=FalseでIDを消した列: ['商品', 'カテゴリ', '売上', '備考']
IDを通常列へ戻した列: ['商品ID', '商品', 'カテゴリ', '売上', '備考']</pre>
<p>注目するのは、前者には<code>商品ID</code>がなく、後者には残っている点です。<code>index=False</code>を機械的に付けるのではなく、<strong>現在のインデックスが単なる連番か、意味のある識別子か</strong>を先に確認してください。</p>
<h2><span id="toc9">日本語の文字化けを防ぐencodingの選び方</span></h2>
<p><code>encoding</code>は、CSVを利用する環境に合わせて選びます。</p>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>主な利用場面</th>
        <th>候補</th>
        <th>確認方法</th>
        <th>注意点</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Pythonや多くの現代的なツールで再利用</td>
        <td><code>utf-8</code></td>
        <td>同じencodingで読み込み直す</td>
        <td>アプリや読み込み方法によっては日本語表示を確認する</td>
      </tr>
      <tr>
        <td>日本語をExcelで直接開いて確認</td>
        <td><code>utf-8-sig</code></td>
        <td>実際のExcel環境で開く</td>
        <td>Excelのバージョンや開き方でも挙動が異なる</td>
      </tr>
      <tr>
        <td>受け渡し先から文字コード指定がある</td>
        <td>指定された文字コード</td>
        <td>相手先の手順で確認</td>
        <td>環境を無視して固定しない</td>
      </tr>
    </tbody>
  </table>
</div>
<p><code>utf-8-sig</code>はファイル先頭にBOMを付けたUTF-8です。日本語CSVをExcelで直接開く用途では有力な候補ですが、すべての用途で一律に選ぶ必要はありません。</p>
<pre class="line-numbers language-python"><code class="language-python">utf8_path = output_dir / "sales_utf8.csv"
utf8_sig_path = output_dir / "sales_utf8_sig.csv"

df.to_csv(utf8_path, index=False, encoding="utf-8")
df.to_csv(utf8_sig_path, index=False, encoding="utf-8-sig")

print("UTF-8の先頭3バイト:", utf8_path.read_bytes()[:3])
print("UTF-8 with BOMの先頭3バイト:", utf8_sig_path.read_bytes()[:3])

checked_japanese = pd.read_csv(utf8_sig_path, encoding="utf-8-sig")
print("再読み込みした商品:", checked_japanese["商品"].tolist())</code></pre>
<pre class="colab-output">UTF-8の先頭3バイト: b'\xe5\x95\x86'
UTF-8 with BOMの先頭3バイト: b'\xef\xbb\xbf'
再読み込みした商品: ['ノート', 'ペン', 'ファイル', '付箋']</pre>
<p><code>utf-8-sig</code>のファイルでは、先頭3バイトがBOMを表す<code>b'\xef\xbb\xbf'</code>になります。再読み込み後の商品が「ノート」「ペン」「ファイル」「付箋」と表示されれば、指定した文字コードで日本語を読めています。</p>
<p>文字化けが起きたら、保存コードだけを見るのではなく、<strong>CSVをどのアプリで、どの文字コードとして開いたか</strong>も確認します。</p>
<h2><span id="toc10">必要な列だけcolumnsで保存する</span></h2>
<h3><span id="toc11">実行目的</span></h3>
<p>社内共有用として、<code>商品</code>・<code>カテゴリ</code>・<code>売上</code>だけを保存します。個人情報や作業用列を含むデータでは、保存前に共有範囲を確認することも重要です。</p>
<pre class="line-numbers language-python"><code class="language-python">shared_columns = ["商品", "カテゴリ", "売上"]
shared_path = output_dir / "sales_shared.csv"

df.to_csv(
    shared_path,
    index=False,
    encoding="utf-8-sig",
    columns=shared_columns,
)

shared_df = pd.read_csv(shared_path, encoding="utf-8-sig")
print(shared_df)
print("保存した列:", shared_df.columns.tolist())</code></pre>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>商品</th>
        <th>カテゴリ</th>
        <th>売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>ノート</td>
        <td>文具</td>
        <td>1200</td>
      </tr>
      <tr>
        <td>1</td>
        <td>ペン</td>
        <td>文具</td>
        <td>900</td>
      </tr>
      <tr>
        <td>2</td>
        <td>ファイル</td>
        <td>収納</td>
        <td>1500</td>
      </tr>
      <tr>
        <td>3</td>
        <td>付箋</td>
        <td>文具</td>
        <td>600</td>
      </tr>
    </tbody>
  </table>
</div>
<pre class="colab-output">保存した列: ['商品', 'カテゴリ', '売上']</pre>
<p>出力は4行3列です。<code>商品ID</code>と<code>備考</code>が含まれず、列順も<code>columns</code>で指定した順になっていることを確認します。</p>
<p>列名を間違えると<code>KeyError</code>になります。自分のデータへ置き換える前に、<code>df.columns.tolist()</code>で実在する列名と前後の空白を確認してください。データ型を基準に列を選びたい場合は、<a href="https://pythondatalab.com/pandas-select-dtypes/">pandas select_dtypes()の使い方</a>へ進めます。</p>
<h2><span id="toc12">headerとsepは出力形式が必要なときだけ変更する</span></h2>
<p><code>header</code>は列名を出力するか、<code>sep</code>は何の文字で列を区切るかを決めます。</p>
<ul>
  <li>通常の単独CSVでは、列名を残す既定の<code>header=True</code>を使う</li>
  <li>列名が不要という明確な仕様がある場合だけ<code>header=False</code>を使う</li>
  <li>CSVは既定のカンマ区切り、TSVが必要な場合は<code>sep="\t"</code>を使う</li>
</ul>
<p>タブ区切りでは、文字列<code>"t"</code>ではなく、タブ文字を表す<code>"\t"</code>を指定します。</p>
<pre class="line-numbers language-python"><code class="language-python">no_header_path = output_dir / "sales_no_header.csv"
tsv_path = output_dir / "sales.tsv"

df[shared_columns].to_csv(no_header_path, index=False, header=False)
df[shared_columns].to_csv(tsv_path, index=False, sep="\t")

print("header=Falseの先頭行:")
print(no_header_path.read_text(encoding="utf-8").splitlines()[0])
print("TSVの先頭行（タブを見える形に変換）:")
print(tsv_path.read_text(encoding="utf-8").splitlines()[0].replace("\t", " [TAB] "))</code></pre>
<pre class="colab-output">header=Falseの先頭行:
ノート,文具,1200
TSVの先頭行（タブを見える形に変換）:
商品 [TAB] カテゴリ [TAB] 売上</pre>
<p><code>header=False</code>の先頭行は列名ではなく、最初の商品データになります。TSVの先頭行では、3つの列名がタブで区切られています。拡張子だけを<code>.tsv</code>へ変えても区切り文字は変わらないため、<code>sep</code>の指定とセットで確認します。</p>
<h2><span id="toc13">保存後はread_csv()で読み込み直して検算する</span></h2>
<p>ファイルが存在するだけでは、必要な内容を正しく保存できたとは限りません。共有用CSVを読み込み直し、保存前後を同じ項目で比べます。</p>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>確認項目</th>
        <th>保存前</th>
        <th>再読み込み後</th>
        <th>判断</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>行数</td>
        <td>共有対象の4行</td>
        <td>4行</td>
        <td>一致するか</td>
      </tr>
      <tr>
        <td>列数</td>
        <td>指定した3列</td>
        <td>3列</td>
        <td>余計な列や欠落がないか</td>
      </tr>
      <tr>
        <td>列名</td>
        <td>商品・カテゴリ・売上</td>
        <td>同じ3列</td>
        <td>名前と順序が一致するか</td>
      </tr>
      <tr>
        <td>日本語</td>
        <td>商品名・カテゴリ名</td>
        <td>同じ文字</td>
        <td>文字化けしていないか</td>
      </tr>
      <tr>
        <td>インデックス列</td>
        <td>保存対象外</td>
        <td><code>Unnamed: 0</code>なし</td>
        <td><code>index=False</code>が反映されたか</td>
      </tr>
    </tbody>
  </table>
</div>
<pre class="line-numbers language-python"><code class="language-python">source_for_export = df[shared_columns]
loaded = pd.read_csv(shared_path, encoding="utf-8-sig")

check_result = pd.DataFrame({
    "確認項目": ["行数", "列数", "列名", "Unnamed: 0", "商品名"],
    "結果": [
        len(source_for_export) == len(loaded),
        source_for_export.shape[1] == loaded.shape[1],
        source_for_export.columns.tolist() == loaded.columns.tolist(),
        "Unnamed: 0" not in loaded.columns,
        source_for_export["商品"].tolist() == loaded["商品"].tolist(),
    ],
})

print(check_result)
print("再読み込み後の型:")
print(loaded.dtypes)</code></pre>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>確認項目</th>
        <th>結果</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>行数</td>
        <td>True</td>
      </tr>
      <tr>
        <td>1</td>
        <td>列数</td>
        <td>True</td>
      </tr>
      <tr>
        <td>2</td>
        <td>列名</td>
        <td>True</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Unnamed: 0</td>
        <td>True</td>
      </tr>
      <tr>
        <td>4</td>
        <td>商品名</td>
        <td>True</td>
      </tr>
    </tbody>
  </table>
</div>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>dtype</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>商品</td>
        <td>o</td>
        <td>b</td>
        <td>j</td>
        <td>e</td>
        <td>c</td>
        <td>t</td>
      </tr>
      <tr>
        <td>カテゴリ</td>
        <td>o</td>
        <td>b</td>
        <td>j</td>
        <td>e</td>
        <td>c</td>
        <td>t</td>
      </tr>
      <tr>
        <td>売上</td>
        <td>i</td>
        <td>n</td>
        <td>t</td>
        <td>6</td>
        <td>4</td>
      </tr>
    </tbody>
  </table>
</div>
<p>5項目がすべて<code>True</code>なら、今回の目的に必要な行・列・日本語・インデックス設定は一致しています。</p>
<p>ただし、CSVはDataFrameの型情報を完全に保存する形式ではありません。日付、カテゴリ型、先頭に0を含むコードなどは、再読み込み時に想定と異なる型になることがあります。ファイルを次の分析へ使う前に、<code>dtypes</code>や<code>info()</code>を再確認してください。</p>
<h2><span id="toc14">よくある失敗を現象から確認・修正する</span></h2>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>起きる現象</th>
        <th>主な原因</th>
        <th>確認する箇所</th>
        <th>修正方針</th>
        <th>修正後の確認</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>保存したファイルが見つからない</td>
        <td>相対パスの基準を誤解</td>
        <td>現在の作業場所、<code>resolve()</code>、ファイル一覧</td>
        <td>保存先を明示する</td>
        <td><code>exists()</code>が<code>True</code></td>
      </tr>
      <tr>
        <td>存在しないフォルダへ保存できない</td>
        <td>親フォルダがない</td>
        <td>保存先の親フォルダ</td>
        <td>先にフォルダを作る</td>
        <td>目的のファイルがある</td>
      </tr>
      <tr>
        <td><code>Unnamed: 0</code>が増える</td>
        <td>名前のないindexも保存した</td>
        <td>保存時の<code>index</code>と再読込後の列名</td>
        <td>不要なら<code>index=False</code>で保存し直す</td>
        <td>列一覧から消える</td>
      </tr>
      <tr>
        <td>日本語が文字化けする</td>
        <td>保存時と読み手の文字コードが合わない</td>
        <td><code>encoding</code>と開くアプリ</td>
        <td>用途に合う文字コードで保存し直す</td>
        <td>商品名を正しく読める</td>
      </tr>
      <tr>
        <td>以前のファイルが消える</td>
        <td>同名へ既定モードで上書き</td>
        <td>保存先と同名ファイルの有無</td>
        <td>別名または<code>mode="x"</code></td>
        <td>意図したファイルが両方ある</td>
      </tr>
      <tr>
        <td>追記の途中に列名が入る</td>
        <td><code>mode="a"</code>でheaderも出力</td>
        <td>追記前後の先頭・末尾</td>
        <td>追記時だけ<code>header=False</code></td>
        <td>列名は先頭の1行だけ</td>
      </tr>
      <tr>
        <td>追記後に列がずれる</td>
        <td>列順・列数・区切りが不一致</td>
        <td>既存CSVと追加DataFrameの列</td>
        <td>列をそろえる。難しければ結合後に新規保存</td>
        <td>再読込後の各値が正しい列にある</td>
      </tr>
    </tbody>
  </table>
</div>
<h3><span id="toc15">存在しない保存先フォルダを直す</span></h3>
<h4><span id="toc16">起きる現象</span></h4>
<p>ファイル名は正しいのに、存在しない親フォルダを含むパスへ保存しようとしてエラーになります。</p>
<h4><span id="toc17">原因と確認方法</span></h4>
<p><code>to_csv()</code>は、指定した親フォルダを自動では作りません。<code>parent.exists()</code>で確認します。</p>
<h4><span id="toc18">修正方法</span></h4>
<p>必要なフォルダを作ってから保存します。</p>
<pre class="line-numbers language-python"><code class="language-python">nested_path = output_dir / "reports" / "sales_report.csv"

print("修正前に親フォルダがあるか:", nested_path.parent.exists())
nested_path.parent.mkdir(parents=True, exist_ok=True)
df.to_csv(nested_path, index=False)

print("修正後にファイルがあるか:", nested_path.exists())</code></pre>
<pre class="colab-output">修正前に親フォルダがあるか: False
修正後にファイルがあるか: True</pre>
<p>修正前の親フォルダは<code>False</code>、作成して保存した後のファイルは<code>True</code>になります。自分のデータでは、フォルダ名のスペルやGoogle Driveのマウント先も同時に確認してください。</p>
<h3><span id="toc19">上書きと追記はmodeで区別する</span></h3>
<p>通常の保存は、同名ファイルがあると上書きします。既存ファイルを残すなら<code>mode="x"</code>、既存CSVの末尾へ行を追加するなら<code>mode="a"</code>を使います。<code>mode="a"</code>は値の更新や列の追加ではありません。</p>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th>目的</th>
        <th>mode</th>
        <th>注意点</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>通常保存・上書き</td>
        <td>既定の<code>"w"</code></td>
        <td>同名ファイルの内容は置き換わる</td>
      </tr>
      <tr>
        <td>上書きを防いで新規保存</td>
        <td><code>"x"</code></td>
        <td>同名ファイルがあると<code>FileExistsError</code></td>
      </tr>
      <tr>
        <td>既存CSVへ行を追記</td>
        <td><code>"a"</code></td>
        <td>列順をそろえ、通常は<code>header=False</code></td>
      </tr>
    </tbody>
  </table>
</div>
<pre class="line-numbers language-python"><code class="language-python">protected_path = output_dir / "sales_protected.csv"
df.to_csv(protected_path, index=False)

try:
    df.to_csv(protected_path, index=False, mode="x")
except FileExistsError:
    print("同名ファイルがあるため、上書きを停止しました:", protected_path.name)

print("既存ファイルは残っているか:", protected_path.exists())</code></pre>
<pre class="colab-output">同名ファイルがあるため、上書きを停止しました: sales_protected.csv
既存ファイルは残っているか: True</pre>
<p><code>FileExistsError</code>が出たら、別名で保存するか、本当に上書きしてよいか判断します。続いて、列名と順序が同じデータを行方向へ追記する例を確認します。</p>
<pre class="line-numbers language-python"><code class="language-python">append_path = output_dir / "sales_append.csv"
base = df[shared_columns].iloc[:3]
new_row = df[shared_columns].iloc[3:]

base.to_csv(append_path, index=False, encoding="utf-8-sig")
new_row.to_csv(
    append_path,
    index=False,
    encoding="utf-8-sig",
    mode="a",
    header=False,
)

appended = pd.read_csv(append_path, encoding="utf-8-sig")
print(appended)
print("追記後の行数:", len(appended))</code></pre>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>商品</th>
        <th>カテゴリ</th>
        <th>売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>ノート</td>
        <td>文具</td>
        <td>1200</td>
      </tr>
      <tr>
        <td>1</td>
        <td>ペン</td>
        <td>文具</td>
        <td>900</td>
      </tr>
      <tr>
        <td>2</td>
        <td>ファイル</td>
        <td>収納</td>
        <td>1500</td>
      </tr>
      <tr>
        <td>3</td>
        <td>付箋</td>
        <td>文具</td>
        <td>600</td>
      </tr>
    </tbody>
  </table>
</div>
<pre class="colab-output">追記後の行数: 4</pre>
<p>追記後は4行で、列名は先頭の1回だけです。<code>header=False</code>を忘れると途中に列名が入ります。列構成が違う場合は追記せず、DataFrameを結合してから新しいCSVとして保存します。</p>
<h2><span id="toc20">Google Colabで保存するときの注意</span></h2>
<p>この記事の相対パスは、Colabではランタイムの一時領域へ保存されます。ランタイム終了後も残したい場合は、Google Driveをマウントし、実在するDrive内フォルダの絶対パスを指定します。手元のPCへダウンロードする操作と、Driveへ保存する操作は別です。</p>
<p>Driveの接続、パスのコピー、CSVの再読み込みは、<a href="https://pythondatalab.com/google-colab-csv/">Google ColabでCSVを読み込む方法</a>で詳しく確認してください。この記事ではto_csv()の設定と保存結果の検算に集中します。</p>
<h2><span id="toc21">自分のDataFrameへ置き換える前のチェックリスト</span></h2>
<ul>
  <li>DataFrame名は正しいか</li>
  <li>保存する列名と順序を<code>df.columns</code>で確認したか</li>
  <li>現在のindexは単なる連番か、意味のあるIDか</li>
  <li>保存前の行数・列数を<code>df.shape</code>で記録したか</li>
  <li>欠損値を空欄として出力してよいか</li>
  <li>親フォルダは実在するか</li>
  <li>同名ファイルを上書きしてよいか</li>
  <li>CSVを開くアプリと文字コードは合っているか</li>
  <li>追記する場合、既存CSVと列名・順序・区切り文字が同じか</li>
  <li>保存後にread_csv()で読み込み直したか</li>
</ul>
<p>Excelから読み込んだデータをCSVへ変換する場合は、先に<a href="https://pythondatalab.com/pandas-read-excel/">pandas read_excel()の使い方</a>でシート・見出し・必要列が正しいか確認してください。</p>
<h2><span id="toc22">保存したCSVを次の分析へつなげる</span></h2>
<p>CSV保存は分析の終点とは限りません。別のNotebookで読み込み直し、データの状態を確認してから集計へ進めます。</p>
<pre class="line-numbers language-python"><code class="language-python">reused = pd.read_csv(shared_path, encoding="utf-8-sig")

print("再利用するデータ:")
print(reused)
print("カテゴリ別の売上合計:")
print(reused.groupby("カテゴリ", as_index=False)["売上"].sum())</code></pre>
<pre class="colab-output">再利用するデータ:</pre>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>商品</th>
        <th>カテゴリ</th>
        <th>売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>ノート</td>
        <td>文具</td>
        <td>1200</td>
      </tr>
      <tr>
        <td>1</td>
        <td>ペン</td>
        <td>文具</td>
        <td>900</td>
      </tr>
      <tr>
        <td>2</td>
        <td>ファイル</td>
        <td>収納</td>
        <td>1500</td>
      </tr>
      <tr>
        <td>3</td>
        <td>付箋</td>
        <td>文具</td>
        <td>600</td>
      </tr>
    </tbody>
  </table>
</div>
<pre class="colab-output">カテゴリ別の売上合計:</pre>
<div class="table-scroll">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th></th>
        <th>カテゴリ</th>
        <th>売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>収納</td>
        <td>1500</td>
      </tr>
      <tr>
        <td>1</td>
        <td>文具</td>
        <td>2700</td>
      </tr>
    </tbody>
  </table>
</div>
<p>再読み込みしたデータから、カテゴリ別の売上合計を計算できました。保存後は、まず列・型・欠損を確認し、その後に<a href="https://pythondatalab.com/pandas-groupby-agg/">pandas groupby・aggの使い方</a>で複数列・複数集計へ進めます。</p>
<p>CSVを読み込み直したときに列名や型が想定と違う場合は、集計へ進む前に原因を修正してください。</p>
<h2><span id="toc23">まとめ</span></h2>
<ul>
  <li>DataFrameのCSV保存には<code>to_csv()</code>を使う</li>
  <li>最初に保存先を決め、index・文字コード・保存列・上書きの順で判断する</li>
  <li>連番インデックスが不要なら<code>index=False</code>を使う</li>
  <li>意味のあるIDをインデックスにしている場合は、消す前に通常列へ戻すか判断する</li>
  <li>日本語の文字コードは開く環境で選び、Excelで直接開く用途では<code>utf-8-sig</code>を候補にする</li>
  <li><code>columns</code>で保存範囲を絞り、<code>header</code>と<code>sep</code>は必要な仕様がある場合だけ変更する</li>
  <li>上書きを防ぐなら<code>mode="x"</code>、行を追記する場合だけ<code>mode="a"</code>を使う</li>
  <li>保存後はread_csv()で読み込み直し、行数・列名・日本語・不要列を検算する</li>
</ul>
<p>最小コードを実行して終わりにせず、<strong>保存されたCSVを次の環境で正しく読めるか</strong>まで確認することが、失敗を防ぐポイントです。</p>
<h2><span id="toc24">関連記事</span></h2>
<ul>
  <li><a href="https://pythondatalab.com/google-colab-csv/">Google ColabでCSVを読み込む方法｜アップロード・Drive・read_csv</a></li>
  <li><a href="https://pythondatalab.com/pandas-preprocessing-basic/">Pandasデータ前処理の基本｜読み込み後に確認する順番と欠損・型・重複の選び方</a></li>
  <li><a href="https://pythondatalab.com/pandas-info-method/">pandas info()の使い方｜Non-Null Count・データ型・欠損値の見方</a></li>
  <li><a href="https://pythondatalab.com/pandas-read-excel/">pandas read_excel()の使い方｜Excel読み込み・sheet_name・header・usecolsを初心者向けに解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-select-dtypes/">pandas select_dtypes()の使い方｜データ型で列を選ぶ方法を初心者向けに解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrameとは？作り方・基本操作・Seriesとの違いを初心者向けに解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-groupby-agg/">pandas groupby・aggの使い方｜複数列・複数集計と結果の見方</a></li>
</ul>
 <!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc25"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1789052749746" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc26">to_csv()でindex=Falseを付けるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>0から始まる連番インデックスがCSVへ追加され、再読み込み時に<code>Unnamed: 0</code>となるのを防ぐためです。ただし、顧客IDなど意味のあるインデックスは、通常列へ戻して残すか判断してください</p>

</div>
</div>
<div id="faq-question-1789052767316" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc27">CSVをExcelで開くと文字化けする場合はどうしますか？</span></h3>
<div class="rank-math-answer ">

<p>保存時の<code>encoding</code>と、Excelがどの文字コードとして開いているかを確認します。日本語をExcelで直接開く用途では<code>encoding="utf-8-sig"</code>を候補にし、実際の利用環境で表示を確認してください。受け渡し先に指定がある場合は、その指定を優先します。</p>

</div>
</div>
<div id="faq-question-1789052778892" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc28">to_csv()で保存したファイルはどこにありますか？</span></h3>
<div class="rank-math-answer ">

<p>相対パスなら現在の作業場所を基準に保存されます。<code>Path("ファイル名").resolve()</code>で絶対パスを確認できます。Colabの一時領域はランタイム終了後に消えるため、残したい場合はGoogle Driveなどへ保存します。</p>

</div>
</div>
<div id="faq-question-1789052789192" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc29">CSVへ追記するときにヘッダーが重複するのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p><code>mode="a"</code>で追記するときも、既定では列名が出力されるためです。既存CSVと列構成を確認し、行を追記するコードでは<code>header=False</code>を指定します。</p>

</div>
</div>
<div id="faq-question-1789052798467" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc30">CSVへ保存するとデータ型や日付形式は保持されますか？</span></h3>
<div class="rank-math-answer ">

<p>完全には保持されません。CSVは文字で表現されるため、再読み込み時に型が推定されます。先頭の0を持つコード、日付、カテゴリ型、欠損値などは、読み込み後に<code>dtypes</code>や<code>info()</code>で確認してください。</p>

</div>
</div>
<div id="faq-question-1789052813087" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc31">Google Colab終了後もCSVを残すにはどうしますか？</span></h3>
<div class="rank-math-answer ">

<p>Google DriveをマウントしてDrive内の実在パスへ保存するか、ランタイム終了前に端末へダウンロードします。Driveの接続とパス確認は関連記事を参照してください。</p>

</div>
</div>
<div id="faq-question-1789052838417" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc32">保存後に正しく出力できたか確認するにはどうしますか？</span></h3>
<div class="rank-math-answer ">

<p>read_csv()で読み込み直し、保存前後の<code>shape</code>、列名と順序、日本語、欠損値、<code>Unnamed: 0</code>の有無を比べます。重要なデータでは数行だけでなく、行数や集計値も確認してください。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-to-csv/">pandas to_csv()の使い方｜indexなし・文字化け対策・保存先を解説</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-to-csv/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pandasデータ前処理の基本｜読み込み後に確認する順番と欠損・型・重複の選び方</title>
		<link>https://pythondatalab.com/pandas-preprocessing-basic/</link>
					<comments>https://pythondatalab.com/pandas-preprocessing-basic/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Sun, 06 Sep 2026 08:12:27 +0000</pubDate>
				<category><![CDATA[抽出・前処理]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2190</guid>

					<description><![CDATA[<p>Pandasでデータ読み込み後に行う前処理の手順を解説。一律に処理するのではなく、info()での診断から空白除去、to_numeric()/astype()での型変換、欠損値・重複の判断、集計への進み方まで「確認→選択→再確認」の流れで網羅します。</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-preprocessing-basic/">Pandasデータ前処理の基本｜読み込み後に確認する順番と欠損・型・重複の選び方</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<style>
  .colab-article pre.line-numbers,.colab-article pre.colab-output{margin-top:0!important;margin-bottom:0!important;padding:1em}
  .colab-article .table-scroll{overflow-x:auto;margin:0}
  /* テーブル全体の枠線スタイルを追加 */
  .colab-article table.wp-block-table{width:auto;border-collapse:collapse;border:1px solid #ccc}
  /* ヘッダーとセルの枠線・パディング・背景色を追加 */
  .colab-article table.wp-block-table th,.colab-article table.wp-block-table td{white-space:nowrap;padding:.4em .8em;border:1px solid #ccc}
  .colab-article table.wp-block-table th{background-color:#f2f2f2}
  .colab-article table.wp-block-table th:first-child,.colab-article table.wp-block-table td:first-child{min-width:3em}
</style>
<div class="colab-article">
  <p>CSVやExcelを読み込んだ後、すぐに欠損値を埋めたり行を削除したりしていませんか。Pandasのデータ前処理で大切なのは、決まった処理をすべて行うことではありません。<strong>DataFrameの状態を確認し、問題がある列だけを直して、処理後にもう一度確認すること</strong>です。</p>
  <p>この記事では、Google Colabでそのまま実行できる小さな売上データを使い、分析前の確認から空白・型・欠損値・重複候補の判断、集計へ進むまでの流れを解説します。</p>
  <h2><span id="toc1">この記事でわかること</span></h2><ul><li>読み込み後に最初に確認する項目</li><li>空白、数値文字列、欠損値、重複候補の見分け方</li><li><code>to_numeric()</code>・<code>astype()</code>、<code>fillna()</code>・<code>dropna()</code>を選ぶ基準</li><li>前処理後に集計・可視化へ進む目安</li></ul>
  <h2><span id="toc2">先に結論：前処理は「確認→選択→再確認」で進めます</span></h2>
  <p>読み込み直後に行うことは、データを一律にきれいにすることではありません。まず<code>info()</code>で状態を確認し、問題がある列だけを処理します。</p>
  <div class="table-scroll"><table class="wp-block-table"><thead><tr><th>確認で見つかった状態</th><th>選ぶ処理</th><th>処理しない判断</th><th>処理後に確認する項目</th></tr></thead><tbody><tr><td>前後空白がある</td><td><code>str.strip()</code></td><td>空白に意味がある場合</td><td>値がそろったか</td></tr><tr><td>数値列が文字列</td><td><code>to_numeric()</code></td><td>IDなど文字列で保持すべき列</td><td>dtypeと変換後のNaN</td></tr><tr><td>欠損値がある</td><td>保持・<code>fillna()</code>・<code>dropna()</code></td><td>欠損が重要な情報の場合</td><td>件数、補完値、行数</td></tr><tr><td>重複候補がある</td><td><code>duplicated()</code>で確認</td><td>判定列や残す基準が未確定</td><td>候補行と行数</td></tr></tbody></table></div>
  <h2><span id="toc3">1. 実行前のデータを用意する</span></h2><p>商品名の前後空白、数値ではない売上、欠損した担当者、重複候補の注文IDを持つ店舗売上データです。実データでも、元データを残して作業用のDataFrameを作ると安全です。</p>
  <pre class="line-numbers language-python"><code class="language-python">import pandas as pd
from IPython.display import display

raw_df = pd.DataFrame({
    '注文ID': [1001, 1002, 1002, 1003, 1004],
    '商品名': [' ノート ', 'ペン', 'ペン', 'ノート', '消しゴム'],
    '売上': ['1200', '不明', '1500', '900', ''],
    '購入日': ['2026-09-01', '2026-09-01', '2026-09-01', '2026-09-02', '2026-09-02'],
    '担当者': ['佐藤', None, None, '田中', '鈴木']
})
df = raw_df.copy()
display(df)</code></pre>
  <h2><span id="toc4">2. まずinfo()で列・型・欠損値を診断する</span></h2><p><strong>実行目的</strong>：行数、列名、データ型、欠損値がある列を一度に確認します。<strong>出力で見る場所</strong>：<code>Non-Null Count</code>が行数より少ない列は欠損を含みます。見た目が数字でも<code>object</code>型の<code>売上</code>は、計算前に内容を確認します。</p>
  <pre class="line-numbers language-python"><code class="language-python">print('行数・列数:', df.shape)
print('
列名:', df.columns.tolist())
print('
--- df.info() の出力 ---')
df.info()
print('
列ごとの欠損数:')
display(df.isna().sum().rename('欠損数').to_frame())</code></pre>
  <p>この例では<code>担当者</code>に2件の欠損があります。一方、<code>売上</code>の空文字はまだ欠損値として数えられません。詳しい読み方は<a href="https://pythondatalab.com/pandas-info-method/">pandas info()の使い方</a>を参照してください。</p>
  <h2><span id="toc5">3. 空白と数値文字列を、対象列だけ整える</span></h2><p>商品名の前後空白を除き、売上を計算できる数値へ変換します。<code>不明</code>や空文字は0円とは限らないため、0を入れず、数値に変換できない値を<code>NaN</code>として確認します。</p>
  <pre class="line-numbers language-python"><code class="language-python">df['商品名_clean'] = df['商品名'].str.strip()
df['売上_数値'] = pd.to_numeric(df['売上'], errors='coerce')

display(df[['商品名', '商品名_clean', '売上', '売上_数値']])
print('売上_数値のdtype:', df['売上_数値'].dtype)
print('売上_数値の欠損数:', df['売上_数値'].isna().sum())

sales_problem_rows = df.loc[df['売上_数値'].isna(), ['注文ID', '売上', '売上_数値']]
display(sales_problem_rows)</code></pre>
  <p><strong>結果の読み方</strong>：<code> ノート </code>は<code>ノート</code>にそろい、<code>不明</code>と空文字は<code>NaN</code>になります。<code>errors='coerce'</code>はコードが止まらない一方、変換に失敗した元の値を必ず確認する必要があります。</p>
  <p>数値以外の文字が混ざる可能性があるなら<code>to_numeric()</code>、すでに正しい値を目的の型へそろえるなら<code>astype()</code>が目安です。IDや郵便番号のように文字そのものに意味がある列は数値化しません。詳しくは<a href="https://pythondatalab.com/pandas-to-numeric/">pandas to_numeric()の使い方</a>、<a href="https://pythondatalab.com/pandas-astype/">pandas astype()の使い方</a>を参照してください。</p>
  <h2><span id="toc6">4. 欠損値は「何を意味するか」で選ぶ</span></h2><p><code>担当者</code>の欠損は未確認であることを明示する文字列に置き換えます。一方、売上の<code>NaN</code>を0にすると、未確認の売上を0円と誤解させるため補完しません。</p>
  <pre class="line-numbers language-python"><code class="language-python">df['担当者_clean'] = df['担当者'].fillna('担当者未確認')
display(df[['注文ID', '担当者', '担当者_clean', '売上', '売上_数値']])
print('担当者_cleanの欠損数:', df['担当者_clean'].isna().sum())
print('売上_数値の欠損数:', df['売上_数値'].isna().sum())</code></pre>
  <p><strong>注意</strong>：<code>fillna(0)</code>を売上へ使うと、未確認の売上が集計へ混ざります。反対に<code>dropna()</code>で行を削除すると、担当者だけが欠損した売上まで失う可能性があります。欠損の列・意味・件数を見てから選んでください。<a href="https://pythondatalab.com/pandas-fillna/">pandas fillna()の使い方</a>、<a href="https://pythondatalab.com/pandas-drop/">Pandas dropna()・drop_duplicates()の使い方</a>も参照してください。</p>
  <h2><span id="toc7">5. 重複候補は、削除する前に判定列を決める</span></h2><p><code>注文ID</code>が1002の行は2つあります。ただし売上が異なるため、二重登録か修正履歴かは確定できません。まず候補を表示し、何を同一観測とみなすかを決めます。</p>
  <pre class="line-numbers language-python"><code class="language-python">duplicate_order_rows = df.loc[
    df.duplicated(subset=['注文ID'], keep=False),
    ['注文ID', '商品名_clean', '売上', '売上_数値', '購入日']
]
display(duplicate_order_rows)
print('注文IDが重複している候補行数:', len(duplicate_order_rows))</code></pre>
  <p>ここでは削除しません。更新日時・明細番号・取消区分などを確認してから、<code>drop_duplicates()</code>の対象列と<code>keep</code>を選びます。詳しくは<a href="https://pythondatalab.com/pandas-duplicated/">pandas duplicated()の使い方</a>を参照してください。</p>
  <h2><span id="toc8">6. 処理後の状態を再確認して集計へ進む</span></h2><p>今回は売上が数値として確認できた行だけを別のDataFrameへ取り出します。元データは削除せず、未確認の売上と重複候補は残します。</p>
  <pre class="line-numbers language-python"><code class="language-python">sales_ready = df.loc[df['売上_数値'].notna()].copy()
print('元データの行数:', len(df))
print('売上を集計できる行数:', len(sales_ready))
print('売上を集計できない行数:', df['売上_数値'].isna().sum())
sales_ready.info()
display(sales_ready[['注文ID', '商品名_clean', '売上_数値', '担当者_clean']])</code></pre>
  <p>この例では集計できる行は3行です。集計結果は「数値として確認できた売上」のみであり、未確認の売上は含まれません。この前提を説明できる状態になってから次へ進みます。</p>
  <h2><span id="toc9">7. 整えたデータを集計へつなげる</span></h2>
  <pre class="line-numbers language-python"><code class="language-python">product_sales = (
    sales_ready.groupby('商品名_clean', as_index=False)['売上_数値']
    .sum()
    .sort_values('売上_数値', ascending=False)
)
display(product_sales)</code></pre>
  <p>結果は<code>ノート</code>が2,100、<code>ペン</code>が1,500です。ただし未確認の売上は含みません。グループ別集計は<a href="https://pythondatalab.com/pandas-groupby-agg/">pandas groupby・aggの使い方</a>へ進んでください。日付ごとに分析したい場合は<code>to_datetime()</code>と<code>.dt</code>、<code>resample()</code>を使います。</p>
  <h2><span id="toc10">まとめ</span></h2><ul><li><code>info()</code>で列・型・欠損を確認する。</li><li>空白、型、欠損、重複のうち問題があるものだけを処理する。</li><li>元の値、行数、欠損数、dtypeを処理後に再確認する。</li><li>前提を理解したうえで集計・可視化へ進む。</li></ul>
  <h2><span id="toc11">関連記事</span></h2><ul><li><a href="https://pythondatalab.com/pandas-info-method/">pandas info()の使い方</a></li><li><a href="https://pythondatalab.com/pandas-str-strip/">pandas str.strip()の使い方</a></li><li><a href="https://pythondatalab.com/pandas-to-numeric/">pandas to_numeric()の使い方</a></li><li><a href="https://pythondatalab.com/pandas-astype/">pandas astype()の使い方</a></li><li><a href="https://pythondatalab.com/pandas-fillna/">pandas fillna()の使い方</a></li><li><a href="https://pythondatalab.com/pandas-drop/">Pandas dropna()・drop_duplicates()の使い方</a></li><li><a href="https://pythondatalab.com/pandas-duplicated/">pandas duplicated()の使い方</a></li><li><a href="https://pythondatalab.com/pandas-groupby-agg/">pandas groupby・aggの使い方</a></li></ul>
 <!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc12"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1788682065511" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc13">欠損値はすべて埋めるべきですか？</span></h3>
<div class="rank-math-answer ">

<p>いいえ。欠損が何を意味するか、補完すると集計や判断がどう変わるかで決めます。</p>

</div>
</div>
<div id="faq-question-1788682081397" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc14">to_numeric()とastype()はどちらを使えばよいですか？</span></h3>
<div class="rank-math-answer ">

<p>変換できない値を確認したい場合は<code>to_numeric()</code>、正しい値を目的のdtypeへそろえる場合は<code>astype()</code>が目安です。</p>

</div>
</div>
<div id="faq-question-1788682094082" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc15">重複行はすぐに削除してよいですか？</span></h3>
<div class="rank-math-answer ">

<p>いいえ。何を同一観測とみなすかを先に決め、<code>duplicated(..., keep=False)</code>で候補を確認してから判断します。</p>

</div>
</div>
<div id="faq-question-1788682108281" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc16">どこまで確認したら集計へ進めますか？</span></h3>
<div class="rank-math-answer ">

<p>集計に使う列の型、欠損値、対象外にした行数、重複候補の扱いを説明できる状態になったら進みます。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-preprocessing-basic/">Pandasデータ前処理の基本｜読み込み後に確認する順番と欠損・型・重複の選び方</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-preprocessing-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas explode()の使い方｜リスト列を複数行に展開する方法</title>
		<link>https://pythondatalab.com/pandas-explode/</link>
					<comments>https://pythondatalab.com/pandas-explode/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Thu, 03 Sep 2026 12:17:18 +0000</pubDate>
				<category><![CDATA[抽出・前処理]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2173</guid>

					<description><![CDATA[<p>pandasのexplode()でリスト形式の列を複数行に展開する方法を初心者向けに解説。ignore_index、文字列の分割、複数列、空リスト・NaN、ValueErrorの原因と修正、展開後の集計まで実例で学べます。<br />
パーマリンク</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-explode/">pandas explode()の使い方｜リスト列を複数行に展開する方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<div class="colab-article">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
  <style>
    .colab-article pre[class*="language-"] {
      margin: 0 !important;
      padding: 1em;
    }
    .colab-article .code-toolbar {
      margin: 1em 0;
    }
    .colab-article .code-toolbar pre[class*="language-"] {
      margin: 0 !important;
    }
    .colab-article .colab-output {
      margin: 0.75em 0 1.25em;
      padding: 0.8em 1em;
      overflow-x: auto;
      color: #222;
      background: #f6f7f7;
      border: 1px solid #dcdcde;
      white-space: pre;
    }
    .colab-article table.wp-block-table th,
    .colab-article table.wp-block-table td {
      border: 1px solid #dcdcde;
      text-align: left;
    }
    .colab-article table.wp-block-table thead th {
      background: #f0f0f1;
      font-weight: 700;
    }
  </style>

<p>アンケートの複数回答や商品タグのように、<strong>1つのセルに複数の値が入っていて、要素ごとに集計できない</strong>ことがあります。</p>

<p>セルの値がリスト形式なら、<code>pandas</code>の<code>explode()</code>を使うと、リストの各要素を1行ずつに展開できます。</p>

<pre class="line-numbers"><code class="language-python">df.explode("列名", ignore_index=True)</code></pre>

<p>ただし、カンマ区切りの文字列はそのままでは分割されません。また、展開後は行数が増え、指定していない列の値も繰り返されます。この記事では、コードを動かすだけでなく、<strong>行数・インデックス・空リスト・欠損値を確認し、集計結果が正しいか検算する方法</strong>まで説明します。</p>

<h2><span id="toc1">この記事でわかること</span></h2>

<ul>
<li><code>explode()</code>でリスト形式の列を1要素1行へ展開する方法</li>
<li><code>ignore_index=True</code>を使う場面</li>
<li><code>explode()</code>・<code>str.split()</code>・<code>melt()</code>・横方向展開の選び方</li>
<li>複数列を同時に展開する条件</li>
<li>空リスト、<code>NaN</code>、通常の文字列がどう扱われるか</li>
<li><code>ValueError</code>や想定外の行数が生じたときの確認・修正方法</li>
<li>展開後に<code>value_counts()</code>で件数を集計し、合計を検算する方法</li>
</ul>

<p><code>explode()</code>は、データ確認後、集計や可視化へ進む前にデータの形を整える処理です。</p>

<h2><span id="toc2">最初に確認：何をどの方向へ分けたいか</span></h2>

<p>似た処理でも、入力データと目的によって使う方法が変わります。</p>

<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">方法</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">入力の状態</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">求める結果</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">選ぶ場面</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">注意点</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>explode()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">セル内がリスト・タプルなど</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">各要素を縦方向の行へ展開</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">複数回答、タグ、商品一覧</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">行数が増え、元インデックスが繰り返される</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>str.split()</code> → <code>explode()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">セル内がカンマなどで区切られた文字列</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">文字列を分割してから行へ展開</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>"Python,SQL"</code>のような値</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">区切り文字と前後空白を確認する</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>melt()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">複数の列に値が分かれている</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">列名と値を縦持ちへ変換</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">月別列、科目別列など</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">セル内のリストを分ける処理ではない</td>
</tr>
</tbody>
</table>

</div><p>今回の目的は「セル内の複数回答を、回答1件につき1行へ変える」ことなので、<code>explode()</code>を選びます。なお、リスト要素を横方向の別列へ広げたい場合は<code>apply(pd.Series)</code>などを使いますが、この記事では深入りしません。</p>

<h2><span id="toc3">基本例：複数回答のリストを1要素1行へ展開する</span></h2>

<h3><span id="toc4">実行前のデータを確認する</span></h3>

<p>回答者ID、年代、学びたいテーマを持つアンケートデータを使います。<code>学びたいテーマ</code>列には、文字列ではなくPythonのリストが入っています。</p>

<pre class="line-numbers"><code class="language-python">import pandas as pd
import numpy as np

survey = pd.DataFrame({
    &quot;回答者ID&quot;: [101, 102, 103],
    &quot;年代&quot;: [&quot;20代&quot;, &quot;30代&quot;, &quot;20代&quot;],
    &quot;学びたいテーマ&quot;: [
        [&quot;Python&quot;, &quot;pandas&quot;],
        [&quot;pandas&quot;, &quot;可視化&quot;, &quot;SQL&quot;],
        [&quot;Python&quot;]
    ]
})

survey</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">年代</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">101</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">[Python, pandas]</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">102</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">[pandas, 可視化, SQL]</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">103</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">[Python]</td>
    </tr>
  </tbody>
</table></div>
<p>実行前は3行です。<code>学びたいテーマ</code>列のリストには、それぞれ2個、3個、1個の要素があります。合計は6個なので、すべてを展開すると6行になるはずです。</p>

<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">年代</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">101</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>[Python, pandas]</code></td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">102</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>[pandas, 可視化, SQL]</code></td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">103</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>[Python]</code></td>
</tr>
</tbody>
</table>
</div>
<h3><span id="toc5">explode()を実行する</span></h3>

<p>まずは元インデックスを残して展開します。<code>explode()</code>は元のDataFrameを自動で上書きしないため、結果を新しい変数へ代入します。</p>

<pre class="line-numbers"><code class="language-python">survey_long = survey.explode(&quot;学びたいテーマ&quot;)
survey_long</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">年代</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">101</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">101</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">102</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">102</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">可視化</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">102</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">103</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
    </tr>
  </tbody>
</table></div>
<p>出力では、次の3点に注目してください。</p>

<ol>
<li><code>学びたいテーマ</code>の各要素が別の行になっています。</li>
<li><code>回答者ID</code>と<code>年代</code>は、展開された各行へ繰り返されています。</li>
<li>左端のインデックスは<code>0, 0, 1, 1, 1, 2</code>となり、元の行番号が保持されています。</li>
</ol>

<p>インデックスの重複は、重複回答が発生したという意味ではありません。<strong>同じ元レコードから展開された行</strong>であることを示しています。</p>

<h3><span id="toc6">ignore_index=Trueで連番にする</span></h3>

<p>元の行番号を残す必要がなく、展開後の行へ<code>0</code>から連番を付けたい場合は、<code>ignore_index=True</code>を指定します。</p>

<pre class="line-numbers"><code class="language-python">survey_long = survey.explode(&quot;学びたいテーマ&quot;, ignore_index=True)
survey_long</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">年代</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">101</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">101</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">102</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">102</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">可視化</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">102</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">30代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">103</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20代</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
    </tr>
  </tbody>
</table></div>
<p><code>学びたいテーマ</code>の内容は同じですが、インデックスが<code>0</code>から<code>5</code>までの連番になりました。</p>

<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">指定</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">展開後のインデックス</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">選ぶ場面</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>ignore_index=False</code>（初期値）</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">元のインデックスを繰り返す</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">どの元行から展開されたか追跡したい</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>ignore_index=True</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">0から連番を振り直す</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">展開後の表を新しいデータとして扱いたい</td>
</tr>
</tbody>
</table>

</div><p>すでに<code>ignore_index=False</code>で展開した結果なら、<code>reset_index(drop=True)</code>でも後から連番へ直せます。</p>

<h2><span id="toc7">展開前後の行数を検算する</span></h2>

<p>コードがエラーなく動いても、期待した件数になっているとは限りません。リスト内の要素数を合計し、展開後の行数と比較します。</p>

<pre class="line-numbers"><code class="language-python">expected_rows = survey[&quot;学びたいテーマ&quot;].map(len).sum()
actual_rows = len(survey_long)

print(f&quot;展開前の行数: {len(survey)}&quot;)
print(f&quot;リスト内の要素数合計: {expected_rows}&quot;)
print(f&quot;展開後の行数: {actual_rows}&quot;)
print(f&quot;件数は一致: {expected_rows == actual_rows}&quot;)</code></pre>
<pre class="colab-output">展開前の行数: 3
リスト内の要素数合計: 6
展開後の行数: 6
件数は一致: True</pre>
<p>要素数合計と展開後の行数は、どちらも6です。これで、今回のデータでは回答を欠落・重複させず展開できたと確認できます。</p>

<p>ただし、空リストや<code>NaN</code>を含む場合は、単純な要素数合計と展開後行数が一致しないことがあります。後半で、その理由を確認します。</p>

<h2><span id="toc8">カンマ区切りの文字列は、先にstr.split()で分割する</span></h2>

<p><code>explode()</code>が展開するのは、リストやタプルなどのlist-likeな値です。<code>"Python, pandas"</code>のような通常の文字列を指定しても、カンマや1文字ごとには分かれません。</p>

<p>次のデータで違いを確認します。</p>

<pre class="line-numbers"><code class="language-python">survey_text = pd.DataFrame({
    &quot;回答者ID&quot;: [201, 202],
    &quot;学びたいテーマ&quot;: [&quot;Python, pandas&quot;, &quot;可視化, SQL&quot;]
})

not_split = survey_text.explode(&quot;学びたいテーマ&quot;, ignore_index=True)
not_split</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">201</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python, pandas</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">202</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">可視化, SQL</td>
    </tr>
  </tbody>
</table></div>
<p>行数は2行のままで、文字列は分割されていません。これはエラーではなく、<code>explode()</code>の仕様どおりの結果です。</p>

<h3><span id="toc9">確認方法と修正方法</span></h3>

<ul>
<li><strong>現象</strong>：<code>explode()</code>を実行しても行が増えない</li>
<li><strong>原因</strong>：セルの値がリストではなく1つの文字列</li>
<li><strong>確認方法</strong>：対象列の値と型を確認する</li>
<li><strong>修正方法</strong>：<code>str.split()</code>でリスト化し、前後空白を除いてから展開する</li>
</ul>

<pre class="line-numbers"><code class="language-python">print(&quot;変換前の値:&quot;, survey_text.loc[0, &quot;学びたいテーマ&quot;])
print(&quot;変換前の型:&quot;, type(survey_text.loc[0, &quot;学びたいテーマ&quot;]).__name__)

survey_text_fixed = survey_text.assign(
    学びたいテーマ=survey_text[&quot;学びたいテーマ&quot;].str.split(&quot;,&quot;)
)

survey_text_fixed[&quot;学びたいテーマ&quot;] = survey_text_fixed[&quot;学びたいテーマ&quot;].map(
    lambda items: [item.strip() for item in items]
)

text_long = survey_text_fixed.explode(&quot;学びたいテーマ&quot;, ignore_index=True)
text_long</code></pre>
<pre class="colab-output">変換前の値: Python, pandas
変換前の型: str</pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">201</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">201</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">202</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">可視化</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">202</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL</td>
    </tr>
  </tbody>
</table></div>
<p>修正後は4行になり、<code>Python</code>、<code>pandas</code>、<code>可視化</code>、<code>SQL</code>が1行ずつに分かれました。<code>str.split(",")</code>だけでは区切り後の空白が残るため、各要素へ<code>strip()</code>を適用しています。</p>

<p>自分のデータでは、カンマが半角か全角か、セミコロンやパイプで区切られていないかも確認してください。</p>

<h2><span id="toc10">複数列を同時に展開する</span></h2>

<p>複数列の各要素に対応関係がある場合は、列名のリストを渡して同時に展開できます。次の例では、1番目のテーマと1番目の習熟度、2番目どうしが対応しています。</p>

<pre class="line-numbers"><code class="language-python">skills = pd.DataFrame({
    &quot;回答者ID&quot;: [301, 302],
    &quot;学びたいテーマ&quot;: [[&quot;Python&quot;, &quot;pandas&quot;], [&quot;SQL&quot;, &quot;可視化&quot;]],
    &quot;習熟度&quot;: [[&quot;入門&quot;, &quot;初級&quot;], [&quot;初級&quot;, &quot;入門&quot;]]
})

skills_long = skills.explode(
    [&quot;学びたいテーマ&quot;, &quot;習熟度&quot;],
    ignore_index=True
)
skills_long</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">習熟度</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">301</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">入門</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">301</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">初級</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">302</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">初級</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">302</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">可視化</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">入門</td>
    </tr>
  </tbody>
</table></div>
<p>結果は4行になり、<code>Python―入門</code>、<code>pandas―初級</code>のように対応関係を保って展開されます。</p>

<h3><span id="toc11">複数列では、行ごとの要素数をそろえる</span></h3>

<p>同時に展開する列は、<strong>各行でリストの長さが一致している必要があります</strong>。長さが違うと<code>ValueError: columns must have matching element counts</code>が発生します。</p>

<pre class="line-numbers"><code class="language-python">skills_error = pd.DataFrame({
    &quot;回答者ID&quot;: [401, 402],
    &quot;学びたいテーマ&quot;: [[&quot;Python&quot;, &quot;pandas&quot;], [&quot;SQL&quot;, &quot;可視化&quot;]],
    &quot;習熟度&quot;: [[&quot;入門&quot;], [&quot;初級&quot;, &quot;入門&quot;]]
})

length_check = skills_error.assign(
    テーマ数=skills_error[&quot;学びたいテーマ&quot;].map(len),
    習熟度数=skills_error[&quot;習熟度&quot;].map(len)
)
length_check[[&quot;回答者ID&quot;, &quot;テーマ数&quot;, &quot;習熟度数&quot;]]</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">テーマ数</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">習熟度数</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">401</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">1</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">402</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2</td>
    </tr>
  </tbody>
</table></div>
<p>回答者ID<code>401</code>だけ、テーマ数が2、習熟度数が1です。この状態で2列を同時に展開すると、どの習熟度をどのテーマへ対応させるか決められません。</p>

<p>ここでは、元データを確認した結果、<code>pandas</code>の習熟度が未回答だったと分かったものとして、意味を勝手に補わず<code>pd.NA</code>を追加します。</p>

<pre class="line-numbers"><code class="language-python">skills_fixed = skills_error.copy()
skills_fixed.at[0, &quot;習熟度&quot;] = [&quot;入門&quot;, pd.NA]

fixed_long = skills_fixed.explode(
    [&quot;学びたいテーマ&quot;, &quot;習熟度&quot;],
    ignore_index=True
)
fixed_long</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答者ID</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">習熟度</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">401</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">入門</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">401</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">&lt;NA&gt;</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">402</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">初級</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">402</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">可視化</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">入門</td>
    </tr>
  </tbody>
</table></div>
<p>修正後は4行へ展開でき、<code>pandas</code>に対応する習熟度は欠損値として残りました。</p>

<p>重要なのは、エラーを消すためだけに値を複製しないことです。対応関係を元データで確認できない場合は、同時展開を中止するか、欠損として明示してください。</p>

<h2><span id="toc12">空リスト・NaN・通常の文字列の挙動を確認する</span></h2>

<p>セルの状態によって、展開後の結果が変わります。代表的な入力を1つの表で確認します。</p>

<pre class="line-numbers"><code class="language-python">mixed = pd.DataFrame({
    &quot;状態&quot;: [&quot;リスト&quot;, &quot;空リスト&quot;, &quot;NaN&quot;, &quot;通常の文字列&quot;, &quot;数値&quot;],
    &quot;値&quot;: [[&quot;Python&quot;, &quot;pandas&quot;], [], np.nan, &quot;SQL&quot;, 100]
})

mixed_long = mixed.explode(&quot;値&quot;, ignore_index=True)
mixed_long</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">状態</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">値</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">リスト</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">リスト</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">空リスト</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">通常の文字列</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">数値</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
    </tr>
  </tbody>
</table></div>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">入力</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">展開後の考え方</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">確認上の注意</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">要素を持つリスト</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">要素数だけ行へ展開</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">指定外列は各行へ複製される</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">空リスト</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>NaN</code>を持つ1行になる</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">「回答なし」か「空の選択肢」か、元データの意味を確認する</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>NaN</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">そのまま1行残る</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">欠損を削除・補完するかは分析目的で決める</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">通常の文字列</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">そのまま残る</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">区切り文字列なら先に<code>str.split()</code>する</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">数値などのスカラー</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">そのまま残る</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">リストとスカラーの混在が意図どおりか確認する</td>
</tr>
</tbody>
</table>

</div><p>空リストと<code>NaN</code>は展開後の表示が似ていますが、元データでの意味が同じとは限りません。処理前に業務上の定義を確認しましょう。</p>

<h2><span id="toc13">展開後にvalue_counts()で件数を集計する</span></h2>

<p>最初のアンケートデータに戻り、テーマ別の回答件数を数えます。</p>

<pre class="line-numbers"><code class="language-python">theme_counts = (
    survey_long[&quot;学びたいテーマ&quot;]
    .value_counts()
    .rename_axis(&quot;学びたいテーマ&quot;)
    .reset_index(name=&quot;回答件数&quot;)
)

theme_counts</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">学びたいテーマ</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">回答件数</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">Python</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">pandas</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">可視化</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">1</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">1</td>
    </tr>
  </tbody>
</table></div>
<p><code>Python</code>と<code>pandas</code>が2件、<code>可視化</code>と<code>SQL</code>が1件です。回答件数の合計は6件になり、展開後の有効なテーマ数と一致するはずです。</p>

<pre class="line-numbers"><code class="language-python">count_total = theme_counts[&quot;回答件数&quot;].sum()
valid_total = survey_long[&quot;学びたいテーマ&quot;].notna().sum()

print(f&quot;集計表の回答件数合計: {count_total}&quot;)
print(f&quot;展開後の有効テーマ数: {valid_total}&quot;)
print(f&quot;集計結果は一致: {count_total == valid_total}&quot;)</code></pre>
<pre class="colab-output">集計表の回答件数合計: 6
展開後の有効テーマ数: 6
集計結果は一致: True</pre>
<p>両方とも6件なので、展開から集計までの件数は一致しています。</p>

<p>ここで注意したいのは、展開後の<code>len(survey_long)</code>が回答者数ではないことです。回答者数を求めるなら<code>回答者ID.nunique()</code>、選択されたテーマの総数を求めるなら展開後の有効行数を使います。<strong>何を1件と数えるか</strong>を先に決めることが大切です。</p>

<h2><span id="toc14">自分のデータへ置き換えるときのチェックリスト</span></h2>

<ul>
<li><code>df.columns</code>で対象列名が正しいか</li>
<li>対象セルがリスト・タプル等か、区切り文字列か</li>
<li>文字列なら区切り記号と前後空白が何か</li>
<li>空リスト、<code>NaN</code>、空文字がそれぞれ何を意味するか</li>
<li>複数列を展開する場合、各行で要素数と対応順が一致するか</li>
<li>元インデックスを残す必要があるか</li>
<li>展開後に数えたい単位が、元レコード数か要素数か</li>
<li>展開前の要素数合計と、展開・欠損処理後の件数が整合するか</li>
</ul>

<p>対象列の型が混在していそうなら、実行前に値と型の組み合わせを確認します。次の例では、リストだけでなく、文字列・欠損値・数値が混ざっているため、そのまま<code>explode()</code>してもすべての行を同じようには展開できないと分かります。</p>

<pre class="line-numbers"><code class="language-python">type_check_data = pd.DataFrame({
    &quot;元の値&quot;: [[&quot;Python&quot;, &quot;pandas&quot;], &quot;SQL, 可視化&quot;, np.nan, 100]
})

type_check = type_check_data.assign(
    型=type_check_data[&quot;元の値&quot;].map(lambda value: type(value).__name__)
)

type_check</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto; margin: 1em 0;"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">元の値</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">型</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">[Python, pandas]</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">list</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">SQL, 可視化</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">str</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">float</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">int</td>
    </tr>
  </tbody>
</table></div>
<h2><span id="toc15">まとめ</span></h2>

<ul>
<li>セル内のリストを1要素1行へ展開するには<code>explode()</code>を使います。</li>
<li>区切り文字列は、先に<code>str.split()</code>でリスト化します。</li>
<li><code>ignore_index=True</code>なら、展開後のインデックスを0から振り直せます。</li>
<li>指定外の列は繰り返されるため、展開後の行数を回答者数と混同しないようにします。</li>
<li>複数列を同時に展開するには、各行でリストの長さと要素の対応をそろえます。</li>
<li>空リスト、<code>NaN</code>、通常の文字列、スカラーでは挙動が異なるため、元データの型と意味を確認します。</li>
<li>最後に要素数や集計値を照合し、「コードが動いた」だけでなく「正しく展開できた」ことを検算します。</li>
</ul>

<p>展開後は、<a href="https://pythondatalab.com/pandas-value-counts/"><code>value_counts()</code>で全体件数を確認</a>したり、<a href="https://pythondatalab.com/pandas-groupby-agg/"><code>groupby()</code>と<code>agg()</code>で年代別に集計</a>したりできます。必要に応じて欠損処理や表記ゆれの修正を行い、棒グラフなどの可視化へ進みましょう。</p>

<h2><span id="toc16">関連記事</span></h2>

<ul>
<li><a href="https://pythondatalab.com/pandas-melt/">pandas melt()の使い方｜横持ちデータを縦持ちに変換する方法</a>：セル内ではなく、複数の列を縦持ちへ変換したい場合</li>
<li><a href="https://pythondatalab.com/pandas-reset-index/">pandas reset_index()の使い方</a>：展開後のインデックスを後から整理したい場合</li>
<li><a href="https://pythondatalab.com/pandas-value-counts/">pandas value_counts()の使い方</a>：展開した要素の件数・割合を数えたい場合</li>
<li><a href="https://pythondatalab.com/pandas-groupby-agg/">pandas groupby・aggの使い方</a>：年代などの属性別に集計したい場合</li>
<li><a href="https://pythondatalab.com/pandas-fillna/">pandas fillna()の使い方</a>：展開後の欠損値を目的に合わせて補完したい場合</li>
<li><a href="https://pythondatalab.com/pandas-str-strip/">pandas str.strip()の使い方</a>：文字列要素の前後空白を削除したい場合</li>
<li><a href="https://pythondatalab.com/matplotlib-bar-barh-stacked/">Matplotlib 棒グラフ入門</a>：集計した件数をグラフで比較したい場合</li>
</ul>

<!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc17"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p>

  <script>Prism.highlightAll();</script>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1788437736004" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc18">explode()で文字列が1文字ずつ分かれないのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>通常の文字列はlist-likeな複数要素として展開されず、そのまま残るためです。カンマ区切りなどの文字列なら、先に<code>str.split()</code>でリスト化してから<code>explode()</code>を実行します。</p>

</div>
</div>
<div id="faq-question-1788437758129" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc19">複数列を同時に展開するとValueErrorになるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>同時に展開する列のリスト長が、同じ行の中で一致していない可能性があります。各列へ<code>map(len)</code>を適用して要素数を確認し、元データ上の対応関係に従って長さをそろえるか、同時展開をやめてください。</p>

</div>
</div>
<div id="faq-question-1788437771241" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc20">展開後にインデックスが重複するのは問題ですか？</span></h3>
<div class="rank-math-answer ">

<p>初期設定では元インデックスを保持するため、正常な動作です。元行を追跡するならそのまま使い、連番が必要なら<code>ignore_index=True</code>を指定します</p>

</div>
</div>
<div id="faq-question-1788437782393" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc21">空リストとNaNは展開後にどうなりますか？</span></h3>
<div class="rank-math-answer ">

<p>空リストは<code>NaN</code>を持つ1行になり、もともとの<code>NaN</code>もそのまま残ります。表示が似ていても元データでの意味は異なる場合があるため、削除や補完の前に意味を確認してください。</p>

</div>
</div>
<div id="faq-question-1788437792903" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc22">explode()とmelt()はどう使い分けますか？</span></h3>
<div class="rank-math-answer ">

<p>セル内のリスト要素を行へ分けるなら<code>explode()</code>、複数の列を「項目名の列」と「値の列」へまとめるなら<code>melt()</code>を使います</p>

</div>
</div>
<div id="faq-question-1788437804157" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc23">展開後の行数が正しいか、どう確認しますか？</span></h3>
<div class="rank-math-answer ">

<p>欠損や空リストがない単純なデータなら、展開前の各リストの長さを合計し、展開後の行数と比較します。欠損や空リストがある場合は、それらが1行として残る仕様を考慮し、有効値の件数も併せて確認してください。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-explode/">pandas explode()の使い方｜リスト列を複数行に展開する方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-explode/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas info()の使い方｜Non-Null Count・データ型・欠損値の見方</title>
		<link>https://pythondatalab.com/pandas-info-method/</link>
					<comments>https://pythondatalab.com/pandas-info-method/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Sun, 30 Aug 2026 00:56:45 +0000</pubDate>
				<category><![CDATA[基礎]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2156</guid>

					<description><![CDATA[<p>pandasのinfo()で行数・列数・Non-Null Count・データ型を確認する方法を初心者向けに解説。欠損値やobject型を見つけ、型変換・欠損値処理後に再確認する流れ、shape・dtypes・isnull()・describe()との違いも紹介します。</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-info-method/">pandas info()の使い方｜Non-Null Count・データ型・欠損値の見方</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<div class="colab-article">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
  <style>
    .colab-article pre[class*="language-"],
    .colab-article pre.line-numbers {
      margin: 0 !important;
      padding: 1em;
    }
    .colab-article .colab-output {
      margin: 0;
      padding: 1em;
      overflow-x: auto;
      background: #f6f8fa;
      border: 1px solid #d0d7de;
      color: #24292f;
      white-space: pre;
    }
    .colab-article .table-scroll {
      width: 100%;
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
    }
    .colab-article table.wp-block-table {
      width: auto;
      border-collapse: collapse;
    }
    .colab-article table.wp-block-table th,
    .colab-article table.wp-block-table td {
      border: 1px solid #d0d7de;
    }
  </style>


  <p>CSVを読み込んだあと、「列のデータ型は合っているのか」「欠損値はあるのか」「分析前に何を確認すればよいのか」と迷うことはありませんか。</p>

  <p>そんなときに使うのが、Pandasの<code>info()</code>です。<code>df.info()</code>を実行すると、DataFrameの行数・列数・列名・欠損していない値の数・データ型・メモリ使用量をまとめて確認できます。</p>

  <p>ただし、表示するだけでは十分ではありません。特に重要なのは、<strong>Non-Null CountとDtypeを対応させて読むこと</strong>です。</p>

  <ul>
  <li>Non-Null Countが全行数より少ない列 → 欠損値がある</li>
  <li>Dtypeが想定と異なる列 → 型変換が必要な可能性がある</li>
  </ul>

  <p>この記事では、<code>info()</code>の出力を上から順に読み、問題を発見し、必要な前処理を選び、修正後にもう一度確認するところまで解説します。</p>
  <h2 id="この記事でわかること"><span id="toc1">この記事でわかること</span></h2>

  <ul>
  <li><code>df.info()</code>で確認できる内容</li>
  <li>Non-Null CountとDtypeの読み方</li>
  <li>欠損値や想定外のデータ型を見つける方法</li>
  <li><code>info()</code>・<code>shape</code>・<code>dtypes</code>・<code>isnull()</code>・<code>describe()</code>の使い分け</li>
  <li><code>print(df.info())</code>の最後に<code>None</code>が表示される理由</li>
  <li>確認結果から型変換や欠損値処理へ進む方法</li>
  </ul>

  <p>この記事のゴールは、<strong><code>df.info()</code>の結果から問題を発見し、次に必要な前処理を自分で判断できるようになること</strong>です。</p>
  <h2 id="先に結論infoはデータの構造を最初に診断するときに使う"><span id="toc2">先に結論：info()はデータの構造を最初に診断するときに使う</span></h2>

  <p><code>info()</code>は、DataFrameの中身を変更するメソッドではありません。現在の構造をまとめて表示する<strong>確認用のメソッド</strong>です。</p>

  <p>CSVを読み込んだら、次の順番で確認すると迷いにくくなります。</p>

  <ol type="1">
  <li>行数と列数が想定どおりか</li>
  <li>Non-Null Countが全行数より少ない列はないか</li>
  <li>Dtypeが想定どおりか</li>
  <li>問題があれば、専用の確認・修正方法へ進む</li>
  </ol>

  <p>たとえば、Non-Null Countが少なければ<code>isnull().sum()</code>、数値にしたい列がobject型なら<code>to_numeric()</code>、日付列がobject型なら<code>to_datetime()</code>で詳しく確認・修正します。</p>
  <h2 id="売上データを用意してinfoを実行する"><span id="toc3">売上データを用意してinfo()を実行する</span></h2>

  <p>CSVから読み込んだ状態を想定した、5行の売上データを使います。</p>

  <ul>
  <li><code>日付</code>は文字列</li>
  <li><code>売上</code>にはカンマ付きの数字があり、文字列として保存</li>
  <li><code>返品数</code>には欠損値が1つ存在</li>
  </ul>

  <p>まず、実行前のDataFrameを確認しましょう。</p>
  <pre class="line-numbers"><code class="language-python">import pandas as pd
import numpy as np

df = pd.DataFrame({
    &quot;日付&quot;: [&quot;2026-08-01&quot;, &quot;2026-08-02&quot;, &quot;2026-08-03&quot;, &quot;2026-08-04&quot;, &quot;2026-08-05&quot;],
    &quot;商品&quot;: [&quot;ノート&quot;, &quot;ペン&quot;, &quot;ノート&quot;, &quot;ファイル&quot;, &quot;ペン&quot;],
    &quot;売上&quot;: [&quot;1,200&quot;, &quot;900&quot;, &quot;1,500&quot;, &quot;800&quot;, &quot;1,100&quot;],
    &quot;返品数&quot;: [0, np.nan, 1, 0, 2]
})

df</code></pre>
  <div id="df-d1bfa9b0-3501-4e1f-a6d7-22c86f437612" class="colab-df-container">
      <div>
  <style scoped>
      .dataframe tbody tr th:only-of-type {
          vertical-align: middle;
      }

      .dataframe tbody tr th {
          vertical-align: top;
      }

      .dataframe thead th {
          text-align: right;
      }
  </style>
  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr style="text-align: right;">
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">商品</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">返品数</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ノート</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ペン</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">900</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ノート</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,500</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ファイル</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">800</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ペン</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2.0</td>
      </tr>
    </tbody>
  </table>
  </div></div>
      <div class="colab-df-buttons">

    <div class="colab-df-container">
      <button class="colab-df-convert" onclick="convertToInteractive('df-d1bfa9b0-3501-4e1f-a6d7-22c86f437612')" title="Convert this dataframe to an interactive table." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 -960 960 960">
      <path d="M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z"></path>
    </svg>
      </button>

    <style>
      .colab-df-container {
        display:flex;
        gap: 12px;
      }

      .colab-df-convert {
        background-color: #E8F0FE;
        border: none;
        border-radius: 50%;
        cursor: pointer;
        display: none;
        fill: #1967D2;
        height: 32px;
        padding: 0 0 0 0;
        width: 32px;
      }

      .colab-df-convert:hover {
        background-color: #E2EBFA;
        box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
        fill: #174EA6;
      }

      .colab-df-buttons div {
        margin-bottom: 4px;
      }

      [theme=dark] .colab-df-convert {
        background-color: #3B4455;
        fill: #D2E3FC;
      }

      [theme=dark] .colab-df-convert:hover {
        background-color: #434B5C;
        box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
        filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
        fill: #FFFFFF;
      }
    </style>

      <script>
        const buttonEl =
          document.querySelector('#df-d1bfa9b0-3501-4e1f-a6d7-22c86f437612 button.colab-df-convert');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        async function convertToInteractive(key) {
          const element = document.querySelector('#df-d1bfa9b0-3501-4e1f-a6d7-22c86f437612');
          const dataTable =
            await google.colab.kernel.invokeFunction('convertToInteractive',
                                                      [key], {});
          if (!dataTable) return;

          const docLinkHtml = 'Like what you see? Visit the ' +
            '<a target="_blank" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'
            + ' to learn more about interactive tables.';
          element.innerHTML = '';
          dataTable['output_type'] = 'display_data';
          await google.colab.output.renderOutput(dataTable, element);
          const docLink = document.createElement('div');
          docLink.innerHTML = docLinkHtml;
          element.appendChild(docLink);
        }
      </script>
    </div>


    <div id="id_ff17c524-add2-414a-a85f-c84db8272f36">
      <style>
        .colab-df-generate {
          background-color: #E8F0FE;
          border: none;
          border-radius: 50%;
          cursor: pointer;
          display: none;
          fill: #1967D2;
          height: 32px;
          padding: 0 0 0 0;
          width: 32px;
        }

        .colab-df-generate:hover {
          background-color: #E2EBFA;
          box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
          fill: #174EA6;
        }

        [theme=dark] .colab-df-generate {
          background-color: #3B4455;
          fill: #D2E3FC;
        }

        [theme=dark] .colab-df-generate:hover {
          background-color: #434B5C;
          box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
          filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
          fill: #FFFFFF;
        }
      </style>
      <button class="colab-df-generate" onclick="generateWithVariable('df')" title="Generate code using this dataframe." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 0 24 24" width="24px">
      <path d="M7,19H8.4L18.45,9,17,7.55,7,17.6ZM5,21V16.75L18.45,3.32a2,2,0,0,1,2.83,0l1.4,1.43a1.91,1.91,0,0,1,.58,1.4,1.91,1.91,0,0,1-.58,1.4L9.25,21ZM18.45,9,17,7.55Zm-12,3A5.31,5.31,0,0,0,4.9,8.1,5.31,5.31,0,0,0,1,6.5,5.31,5.31,0,0,0,4.9,4.9,5.31,5.31,0,0,0,6.5,1,5.31,5.31,0,0,0,8.1,4.9,5.31,5.31,0,0,0,12,6.5,5.46,5.46,0,0,0,6.5,12Z"></path>
    </svg>
      </button>
      <script>
        (() => {
        const buttonEl =
          document.querySelector('#id_ff17c524-add2-414a-a85f-c84db8272f36 button.colab-df-generate');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        buttonEl.onclick = () => {
          google.colab.notebook.generateWithVariable('df');
        }
        })();
      </script>
    </div>

      </div>
    </div>
  <p><code>日付</code>や<code>売上</code>は見た目だけでは型を判断できません。また、<code>返品数</code>の2行目には<code>NaN</code>があります。次に<code>df.info()</code>を実行し、DataFrame全体の構造を確認します。</p>
  <pre class="line-numbers"><code class="language-python">df.info()</code></pre>
  <pre class="colab-output">&lt;class &#x27;pandas.core.frame.DataFrame&#x27;&gt;
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</pre>
  <p>出力は、次の順で読みます。</p>

  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
  <tr class="header">
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">出力項目</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">確認できること</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">今回の注目点</th>
  </tr>
  </thead>
  <tbody>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>DataFrame</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">対象の種類</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">PandasのDataFrameである</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>RangeIndex</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">行数とインデックス範囲</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5行、インデックスは0〜4</td>
  </tr>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>Data columns</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">合計列数</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">4列</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>Column</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">列番号と列名</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">日付・商品・売上・返品数</td>
  </tr>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>Non-Null Count</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">欠損していない値の数</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">返品数だけ4件</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>Dtype</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">Pandasが認識した型</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">日付・商品・売上はobject、返品数はfloat64</td>
  </tr>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>dtypes</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">型ごとの列数</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">float64が1列、objectが3列</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>memory usage</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">DataFrameのおおよそのメモリ使用量</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">データ規模の目安</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>最初に見るべきなのは、<strong>返品数のNon-Null Countが4であること</strong>と、<strong>日付・売上がobject型であること</strong>です。</p>

  <p><code>info()</code>はデータを表示・診断するだけなので、実行しても元のDataFrameは変わりません。</p>
  <h2 id="non-null-countから欠損値を見つける"><span id="toc4">Non-Null Countから欠損値を見つける</span></h2>

  <p>Non-Null Countは、<strong>欠損していない値の数</strong>です。欠損数ではありません。</p>

  <p>今回のDataFrameは全5行です。<code>返品数</code>は4 non-nullなので、欠損数は次のように求められます。</p>

  <p><strong>欠損数 = 全行数 − Non-Null Count = 5 − 4 = 1</strong></p>

  <p>各列の関係を整理すると、次のようになります。</p>

  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
  <tr class="header">
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">列名</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">全行数</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">Non-Null Count</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">欠損数</th>
  </tr>
  </thead>
  <tbody>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">商品</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
  </tr>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">売上</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">返品数</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">4</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">1</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p><code>info()</code>で欠損値の存在は分かりますが、<strong>どの行が欠損しているかまでは分かりません</strong>。詳しい件数と位置は<code>isnull()</code>で確認します。</p>
  <pre class="line-numbers"><code class="language-python"># 列ごとの欠損数
df.isnull().sum()</code></pre>
  <div>
  <style scoped>
      .dataframe tbody tr th:only-of-type {
          vertical-align: middle;
      }

      .dataframe tbody tr th {
          vertical-align: top;
      }

      .dataframe thead th {
          text-align: right;
      }
  </style>
  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr style="text-align: right;">
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">0</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">商品</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">売上</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">返品数</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      </tr>
    </tbody>
  </table>
  </div></div>
  <br>
  <label><b>dtype:</b> int64</label>
  <pre class="line-numbers"><code class="language-python"># 欠損値がある行
df[df[&quot;返品数&quot;].isnull()]</code></pre>
  <div id="df-3236b103-63f5-412c-a961-94f76096f6a7" class="colab-df-container">
      <div>
  <style scoped>
      .dataframe tbody tr th:only-of-type {
          vertical-align: middle;
      }

      .dataframe tbody tr th {
          vertical-align: top;
      }

      .dataframe thead th {
          text-align: right;
      }
  </style>
  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr style="text-align: right;">
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">商品</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">返品数</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ペン</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">900</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
    </tbody>
  </table>
  </div></div>
      <div class="colab-df-buttons">

    <div class="colab-df-container">
      <button class="colab-df-convert" onclick="convertToInteractive('df-3236b103-63f5-412c-a961-94f76096f6a7')" title="Convert this dataframe to an interactive table." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 -960 960 960">
      <path d="M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z"></path>
    </svg>
      </button>

    <style>
      .colab-df-container {
        display:flex;
        gap: 12px;
      }

      .colab-df-convert {
        background-color: #E8F0FE;
        border: none;
        border-radius: 50%;
        cursor: pointer;
        display: none;
        fill: #1967D2;
        height: 32px;
        padding: 0 0 0 0;
        width: 32px;
      }

      .colab-df-convert:hover {
        background-color: #E2EBFA;
        box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
        fill: #174EA6;
      }

      .colab-df-buttons div {
        margin-bottom: 4px;
      }

      [theme=dark] .colab-df-convert {
        background-color: #3B4455;
        fill: #D2E3FC;
      }

      [theme=dark] .colab-df-convert:hover {
        background-color: #434B5C;
        box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
        filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
        fill: #FFFFFF;
      }
    </style>

      <script>
        const buttonEl =
          document.querySelector('#df-3236b103-63f5-412c-a961-94f76096f6a7 button.colab-df-convert');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        async function convertToInteractive(key) {
          const element = document.querySelector('#df-3236b103-63f5-412c-a961-94f76096f6a7');
          const dataTable =
            await google.colab.kernel.invokeFunction('convertToInteractive',
                                                      [key], {});
          if (!dataTable) return;

          const docLinkHtml = 'Like what you see? Visit the ' +
            '<a target="_blank" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'
            + ' to learn more about interactive tables.';
          element.innerHTML = '';
          dataTable['output_type'] = 'display_data';
          await google.colab.output.renderOutput(dataTable, element);
          const docLink = document.createElement('div');
          docLink.innerHTML = docLinkHtml;
          element.appendChild(docLink);
        }
      </script>
    </div>


      </div>
    </div>
  <p><code>返品数</code>の欠損数は1件で、インデックス1の行にあることが分かりました。</p>

  <p>ここで注意したいのは、欠損値を見つけても、すぐに0で埋めたり行を削除したりしないことです。0が「返品なし」を意味するのか、「記録漏れ」を意味するのかで適切な処理は変わります。</p>

  <p>今回は、データの作成ルールとして<strong>空欄は返品なしを意味する</strong>と確認できたものとして、後ほど0で補完します。自分のデータでは、業務上の意味を確認してから<code>fillna()</code>または<code>dropna()</code>を選んでください。</p>
  <h2 id="dtypeからデータ型の問題を見つける"><span id="toc5">Dtypeからデータ型の問題を見つける</span></h2>

  <p><code>Dtype</code>は、各列をPandasがどのデータ型として認識しているかを示します。</p>

  <p>今回の結果では、次の3点に注目します。</p>

  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
  <tr class="header">
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">列名</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">現在のDtype</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">期待する型</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">判断</th>
  </tr>
  </thead>
  <tbody>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">datetime64[ns]</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">日付計算や月別集計の前に変換候補</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">商品</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">商品名なのでそのままでよい</td>
  </tr>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">売上</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">int64</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">合計や平均を求める前に変換候補</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">返品数</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">float64</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">int64</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">欠損値のためfloat64になっている</td>
  </tr>
  </tbody>
  </table>
  </div>
  <h3 id="object型は必ず普通の文字列とは限らない"><span id="toc6">object型は必ず「普通の文字列」とは限らない</span></h3>

  <p>object型には、商品名のような文字列だけでなく、文字列として読み込まれた日付や数字も含まれます。そのため、object型を見つけても、すぐに機械的な型変換をせず、値の中身を確認します。</p>
  <pre class="line-numbers"><code class="language-python"># object型の列と実際の値を確認
print(df.select_dtypes(include=&quot;object&quot;).columns.tolist())
df[[&quot;日付&quot;, &quot;商品&quot;, &quot;売上&quot;]]</code></pre>
  <pre class="colab-output">[&#x27;日付&#x27;, &#x27;商品&#x27;, &#x27;売上&#x27;]</pre>
  <div id="df-b02564b3-888d-406c-9733-670602d53f57" class="colab-df-container">
      <div>
  <style scoped>
      .dataframe tbody tr th:only-of-type {
          vertical-align: middle;
      }

      .dataframe tbody tr th {
          vertical-align: top;
      }

      .dataframe thead th {
          text-align: right;
      }
  </style>
  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr style="text-align: right;">
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">商品</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ノート</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,200</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ペン</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">900</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ノート</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,500</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ファイル</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">800</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ペン</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,100</td>
      </tr>
    </tbody>
  </table>
  </div></div>
      <div class="colab-df-buttons">

    <div class="colab-df-container">
      <button class="colab-df-convert" onclick="convertToInteractive('df-b02564b3-888d-406c-9733-670602d53f57')" title="Convert this dataframe to an interactive table." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 -960 960 960">
      <path d="M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z"></path>
    </svg>
      </button>

    <style>
      .colab-df-container {
        display:flex;
        gap: 12px;
      }

      .colab-df-convert {
        background-color: #E8F0FE;
        border: none;
        border-radius: 50%;
        cursor: pointer;
        display: none;
        fill: #1967D2;
        height: 32px;
        padding: 0 0 0 0;
        width: 32px;
      }

      .colab-df-convert:hover {
        background-color: #E2EBFA;
        box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
        fill: #174EA6;
      }

      .colab-df-buttons div {
        margin-bottom: 4px;
      }

      [theme=dark] .colab-df-convert {
        background-color: #3B4455;
        fill: #D2E3FC;
      }

      [theme=dark] .colab-df-convert:hover {
        background-color: #434B5C;
        box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
        filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
        fill: #FFFFFF;
      }
    </style>

      <script>
        const buttonEl =
          document.querySelector('#df-b02564b3-888d-406c-9733-670602d53f57 button.colab-df-convert');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        async function convertToInteractive(key) {
          const element = document.querySelector('#df-b02564b3-888d-406c-9733-670602d53f57');
          const dataTable =
            await google.colab.kernel.invokeFunction('convertToInteractive',
                                                      [key], {});
          if (!dataTable) return;

          const docLinkHtml = 'Like what you see? Visit the ' +
            '<a target="_blank" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'
            + ' to learn more about interactive tables.';
          element.innerHTML = '';
          dataTable['output_type'] = 'display_data';
          await google.colab.output.renderOutput(dataTable, element);
          const docLink = document.createElement('div');
          docLink.innerHTML = docLinkHtml;
          element.appendChild(docLink);
        }
      </script>
    </div>


      </div>
    </div>
  <p><code>日付</code>は日付形式の文字列、<code>売上</code>はカンマを含む数字の文字列です。一方、<code>商品</code>は名称なのでobject型のままで問題ありません。</p>

  <p><code>売上</code>のような列へ単純に<code>astype(int)</code>を使うと、<code>1,200</code>のカンマを整数として解釈できず、変換エラーになります。カンマを除いてから<code>to_numeric()</code>を使うと、数値に変換できない値の確認もしやすくなります。</p>

  <h3 id="float64は必ず小数を記録した列とは限らない"><span id="toc7">float64は必ず小数を記録した列とは限らない</span></h3>

  <p><code>返品数</code>の値は0・1・2という整数ですが、欠損値<code>NaN</code>を含むため、今回の環境ではfloat64として表示されています。Dtypeだけを見て「返品数には小数がある」と判断しないようにしましょう。</p>
  <h2 id="問題を修正してからinfoで再確認する"><span id="toc8">問題を修正してからinfo()で再確認する</span></h2>

  <p>次の方針で修正します。</p>

  <ul>
  <li><code>日付</code>：<code>to_datetime()</code>で日付型へ変換</li>
  <li><code>売上</code>：カンマを取り除き、<code>to_numeric()</code>で数値型へ変換</li>
  <li><code>返品数</code>：空欄は返品なしというルールに基づき0で補完して整数型へ変換</li>
  <li><code>商品</code>：名称なのでobject型のまま維持</li>
  </ul>

  <p>元のDataFrameを残して比較できるように、コピーした<code>df_fixed</code>を修正します。</p>
  <pre class="line-numbers"><code class="language-python">df_fixed = df.copy()

df_fixed[&quot;日付&quot;] = pd.to_datetime(df_fixed[&quot;日付&quot;])
df_fixed[&quot;売上&quot;] = pd.to_numeric(
    df_fixed[&quot;売上&quot;].str.replace(&quot;,&quot;, &quot;&quot;, regex=False)
)
df_fixed[&quot;返品数&quot;] = df_fixed[&quot;返品数&quot;].fillna(0).astype(&quot;int64&quot;)

df_fixed</code></pre>
  <div id="df-7332f704-7e2a-4109-b818-1c26d28dc7cc" class="colab-df-container">
      <div>
  <style scoped>
      .dataframe tbody tr th:only-of-type {
          vertical-align: middle;
      }

      .dataframe tbody tr th {
          vertical-align: top;
      }

      .dataframe thead th {
          text-align: right;
      }
  </style>
  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr style="text-align: right;">
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">商品</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">返品数</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ノート</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ペン</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">900</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ノート</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1500</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ファイル</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">800</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">ペン</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      </tr>
    </tbody>
  </table>
  </div></div>
      <div class="colab-df-buttons">

    <div class="colab-df-container">
      <button class="colab-df-convert" onclick="convertToInteractive('df-7332f704-7e2a-4109-b818-1c26d28dc7cc')" title="Convert this dataframe to an interactive table." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 -960 960 960">
      <path d="M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z"></path>
    </svg>
      </button>

    <style>
      .colab-df-container {
        display:flex;
        gap: 12px;
      }

      .colab-df-convert {
        background-color: #E8F0FE;
        border: none;
        border-radius: 50%;
        cursor: pointer;
        display: none;
        fill: #1967D2;
        height: 32px;
        padding: 0 0 0 0;
        width: 32px;
      }

      .colab-df-convert:hover {
        background-color: #E2EBFA;
        box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
        fill: #174EA6;
      }

      .colab-df-buttons div {
        margin-bottom: 4px;
      }

      [theme=dark] .colab-df-convert {
        background-color: #3B4455;
        fill: #D2E3FC;
      }

      [theme=dark] .colab-df-convert:hover {
        background-color: #434B5C;
        box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
        filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
        fill: #FFFFFF;
      }
    </style>

      <script>
        const buttonEl =
          document.querySelector('#df-7332f704-7e2a-4109-b818-1c26d28dc7cc button.colab-df-convert');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        async function convertToInteractive(key) {
          const element = document.querySelector('#df-7332f704-7e2a-4109-b818-1c26d28dc7cc');
          const dataTable =
            await google.colab.kernel.invokeFunction('convertToInteractive',
                                                      [key], {});
          if (!dataTable) return;

          const docLinkHtml = 'Like what you see? Visit the ' +
            '<a target="_blank" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'
            + ' to learn more about interactive tables.';
          element.innerHTML = '';
          dataTable['output_type'] = 'display_data';
          await google.colab.output.renderOutput(dataTable, element);
          const docLink = document.createElement('div');
          docLink.innerHTML = docLinkHtml;
          element.appendChild(docLink);
        }
      </script>
    </div>


    <div id="id_a628a5d8-fa21-43aa-befa-989e8101c575">
      <style>
        .colab-df-generate {
          background-color: #E8F0FE;
          border: none;
          border-radius: 50%;
          cursor: pointer;
          display: none;
          fill: #1967D2;
          height: 32px;
          padding: 0 0 0 0;
          width: 32px;
        }

        .colab-df-generate:hover {
          background-color: #E2EBFA;
          box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
          fill: #174EA6;
        }

        [theme=dark] .colab-df-generate {
          background-color: #3B4455;
          fill: #D2E3FC;
        }

        [theme=dark] .colab-df-generate:hover {
          background-color: #434B5C;
          box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
          filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
          fill: #FFFFFF;
        }
      </style>
      <button class="colab-df-generate" onclick="generateWithVariable('df_fixed')" title="Generate code using this dataframe." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 0 24 24" width="24px">
      <path d="M7,19H8.4L18.45,9,17,7.55,7,17.6ZM5,21V16.75L18.45,3.32a2,2,0,0,1,2.83,0l1.4,1.43a1.91,1.91,0,0,1,.58,1.4,1.91,1.91,0,0,1-.58,1.4L9.25,21ZM18.45,9,17,7.55Zm-12,3A5.31,5.31,0,0,0,4.9,8.1,5.31,5.31,0,0,0,1,6.5,5.31,5.31,0,0,0,4.9,4.9,5.31,5.31,0,0,0,6.5,1,5.31,5.31,0,0,0,8.1,4.9,5.31,5.31,0,0,0,12,6.5,5.46,5.46,0,0,0,6.5,12Z"></path>
    </svg>
      </button>
      <script>
        (() => {
        const buttonEl =
          document.querySelector('#id_a628a5d8-fa21-43aa-befa-989e8101c575 button.colab-df-generate');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        buttonEl.onclick = () => {
          google.colab.notebook.generateWithVariable('df_fixed');
        }
        })();
      </script>
    </div>

      </div>
    </div>
  <p>表示上は似ていますが、<code>日付</code>・<code>売上</code>・<code>返品数</code>のデータ型が変わっています。修正できたと決めつけず、もう一度<code>info()</code>を実行して検証します。</p>
  <pre class="line-numbers"><code class="language-python">df_fixed.info()</code></pre>
  <pre class="colab-output">&lt;class &#x27;pandas.core.frame.DataFrame&#x27;&gt;
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</pre>
  <p>再確認では、次の変化に注目します。</p>

  <ul>
  <li><code>日付</code>：object → datetime64[ns]</li>
  <li><code>売上</code>：object → int64</li>
  <li><code>返品数</code>：4 non-null → 5 non-null、float64 → int64</li>
  <li><code>商品</code>：objectのまま</li>
  </ul>

  <p>処理前後を一覧でも確認しましょう。</p>
  <pre class="line-numbers"><code class="language-python">comparison = pd.DataFrame({
    &quot;修正前_Dtype&quot;: df.dtypes.astype(str),
    &quot;修正後_Dtype&quot;: df_fixed.dtypes.astype(str),
    &quot;修正前_Non-Null&quot;: df.notna().sum(),
    &quot;修正後_Non-Null&quot;: df_fixed.notna().sum()
})

comparison</code></pre>
  <div id="df-e61355ca-2479-42a6-979f-9c2337bd28a6" class="colab-df-container">
      <div>
  <style scoped>
      .dataframe tbody tr th:only-of-type {
          vertical-align: middle;
      }

      .dataframe tbody tr th {
          vertical-align: top;
      }

      .dataframe thead th {
          text-align: right;
      }
  </style>
  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr style="text-align: right;">
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">修正前_Dtype</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">修正後_Dtype</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">修正前_Non-Null</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">修正後_Non-Null</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">datetime64[ns]</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">商品</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">売上</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">object</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">int64</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">返品数</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">float64</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">int64</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">5</td>
      </tr>
    </tbody>
  </table>
  </div></div>
      <div class="colab-df-buttons">

    <div class="colab-df-container">
      <button class="colab-df-convert" onclick="convertToInteractive('df-e61355ca-2479-42a6-979f-9c2337bd28a6')" title="Convert this dataframe to an interactive table." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 -960 960 960">
      <path d="M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z"></path>
    </svg>
      </button>

    <style>
      .colab-df-container {
        display:flex;
        gap: 12px;
      }

      .colab-df-convert {
        background-color: #E8F0FE;
        border: none;
        border-radius: 50%;
        cursor: pointer;
        display: none;
        fill: #1967D2;
        height: 32px;
        padding: 0 0 0 0;
        width: 32px;
      }

      .colab-df-convert:hover {
        background-color: #E2EBFA;
        box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
        fill: #174EA6;
      }

      .colab-df-buttons div {
        margin-bottom: 4px;
      }

      [theme=dark] .colab-df-convert {
        background-color: #3B4455;
        fill: #D2E3FC;
      }

      [theme=dark] .colab-df-convert:hover {
        background-color: #434B5C;
        box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
        filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
        fill: #FFFFFF;
      }
    </style>

      <script>
        const buttonEl =
          document.querySelector('#df-e61355ca-2479-42a6-979f-9c2337bd28a6 button.colab-df-convert');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        async function convertToInteractive(key) {
          const element = document.querySelector('#df-e61355ca-2479-42a6-979f-9c2337bd28a6');
          const dataTable =
            await google.colab.kernel.invokeFunction('convertToInteractive',
                                                      [key], {});
          if (!dataTable) return;

          const docLinkHtml = 'Like what you see? Visit the ' +
            '<a target="_blank" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'
            + ' to learn more about interactive tables.';
          element.innerHTML = '';
          dataTable['output_type'] = 'display_data';
          await google.colab.output.renderOutput(dataTable, element);
          const docLink = document.createElement('div');
          docLink.innerHTML = docLinkHtml;
          element.appendChild(docLink);
        }
      </script>
    </div>


    <div id="id_e323f409-55c6-46c4-96dd-23f6c5ca5153">
      <style>
        .colab-df-generate {
          background-color: #E8F0FE;
          border: none;
          border-radius: 50%;
          cursor: pointer;
          display: none;
          fill: #1967D2;
          height: 32px;
          padding: 0 0 0 0;
          width: 32px;
        }

        .colab-df-generate:hover {
          background-color: #E2EBFA;
          box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
          fill: #174EA6;
        }

        [theme=dark] .colab-df-generate {
          background-color: #3B4455;
          fill: #D2E3FC;
        }

        [theme=dark] .colab-df-generate:hover {
          background-color: #434B5C;
          box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
          filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
          fill: #FFFFFF;
        }
      </style>
      <button class="colab-df-generate" onclick="generateWithVariable('comparison')" title="Generate code using this dataframe." style="display:none;">

    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewbox="0 0 24 24" width="24px">
      <path d="M7,19H8.4L18.45,9,17,7.55,7,17.6ZM5,21V16.75L18.45,3.32a2,2,0,0,1,2.83,0l1.4,1.43a1.91,1.91,0,0,1,.58,1.4,1.91,1.91,0,0,1-.58,1.4L9.25,21ZM18.45,9,17,7.55Zm-12,3A5.31,5.31,0,0,0,4.9,8.1,5.31,5.31,0,0,0,1,6.5,5.31,5.31,0,0,0,4.9,4.9,5.31,5.31,0,0,0,6.5,1,5.31,5.31,0,0,0,8.1,4.9,5.31,5.31,0,0,0,12,6.5,5.46,5.46,0,0,0,6.5,12Z"></path>
    </svg>
      </button>
      <script>
        (() => {
        const buttonEl =
          document.querySelector('#id_e323f409-55c6-46c4-96dd-23f6c5ca5153 button.colab-df-generate');
        buttonEl.style.display =
          google.colab.kernel.accessAllowed ? 'block' : 'none';

        buttonEl.onclick = () => {
          google.colab.notebook.generateWithVariable('comparison');
        }
        })();
      </script>
    </div>

      </div>
    </div>
  <p>この比較表によって、型変換と欠損値処理が想定どおり反映されたことを確認できます。</p>

  <p>重要なのは、<code>info()</code>が自動的に問題を直したわけではないことです。<code>info()</code>で問題を発見し、別のメソッドで修正し、最後に<code>info()</code>で再確認しています。</p>
  <h2 id="printdfinfoでnoneが表示される理由"><span id="toc9">print(df.info())でNoneが表示される理由</span></h2>

  <p><code>info()</code>は、要約情報を画面へ表示するメソッドです。要約情報をDataFrameや文字列として返すのではなく、戻り値は<code>None</code>です。</p>

  <p>そのため、<code>print(df.info())</code>と書くと、最初にinfo()の情報が表示され、そのあとに戻り値の<code>None</code>が表示されます。</p>
  <pre class="line-numbers"><code class="language-python">print(df_fixed.info())</code></pre>
  <pre class="colab-output">&lt;class &#x27;pandas.core.frame.DataFrame&#x27;&gt;
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</pre>
  <p>最後の<code>None</code>はエラーではありません。通常は、次のように<code>print()</code>を付けずに実行します。</p>

  <pre class="line-numbers"><code class="language-python">df_fixed.info()</code></pre>

  <p>また、次のコードでも<code>result</code>に要約表が保存されるわけではありません。</p>

  <pre class="line-numbers"><code class="language-python">result = df_fixed.info()</code></pre>

  <p>この場合、<code>result</code>の値は<code>None</code>です。</p>
  <h2 id="infoshapedtypesisnulldescribeの使い分け"><span id="toc10">info()・shape・dtypes・isnull()・describe()の使い分け</span></h2>

  <p>似た確認方法は、<strong>何を知りたいか</strong>で選びます。</p>

  <div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
  <tr class="header">
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">方法</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">何を求めるか</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">選ぶ場面</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">分からないこと・注意点</th>
  </tr>
  </thead>
  <tbody>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>info()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">構造・非欠損数・型の全体像</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">データ読込直後の診断</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">欠損位置や値の分布は分からない</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>shape</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">行数と列数</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">件数を値として取得したい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">型や欠損値は分からない</td>
  </tr>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>dtypes</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">列ごとのデータ型</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">型だけを一覧で確認したい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">非欠損数は分からない</td>
  </tr>
  <tr class="even">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>isnull().sum()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">列ごとの欠損数</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">欠損値を詳しく確認したい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">型や分布の確認が中心ではない</td>
  </tr>
  <tr class="odd">
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>describe()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">統計量と値の分布</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">平均・中央値・ばらつきを見たい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">DataFrame全体の構造確認とは目的が違う</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>迷ったら、最初に<code>info()</code>で全体を診断し、見つかった問題に応じて専用の方法へ進みます。</p>

  <ul>
  <li>件数だけ必要 → <code>shape</code></li>
  <li>型だけ詳しく確認 → <code>dtypes</code></li>
  <li>欠損数や欠損位置を確認 → <code>isnull()</code></li>
  <li>数値の分布を確認 → <code>describe()</code></li>
  </ul>

  <p><code>select_dtypes()</code>は、特定の型の列だけを抽出したいときに使います。全体診断ではなく、info()で型を確認した後の処理です。</p>
  <pre class="line-numbers"><code class="language-python">print(&quot;shape:&quot;, df_fixed.shape)
print(&quot;\ndtypes:&quot;)
print(df_fixed.dtypes)
print(&quot;\n欠損数:&quot;)
print(df_fixed.isnull().sum())</code></pre>
  <pre class="colab-output">shape: (5, 4)

dtypes:
日付     datetime64[ns]
商品             object
売上              int64
返品数             int64
dtype: object

欠損数:
日付     0
商品     0
売上     0
返品数    0
dtype: int64</pre>
  <h2 id="コードは動いても結果を誤解しやすい場面"><span id="toc11">コードは動いても結果を誤解しやすい場面</span></h2>

  <h3 id="non-null-countを欠損数だと思う"><span id="toc12">Non-Null Countを欠損数だと思う</span></h3>

  <p><strong>現象：</strong> <code>返品数 4 non-null</code>を「欠損値が4件ある」と読む。<br>
  <strong>原因：</strong> Non-Nullは「欠損していない」という意味だからです。<br>
  <strong>確認方法：</strong> 全行数からNon-Null Countを引きます。<br>
  <strong>修正方法：</strong> 正確な列別件数は<code>isnull().sum()</code>で確認します。<br>
  <strong>修正後の確認：</strong> 今回は5−4で、欠損値は1件です。</p>

  <h3 id="object型をすべて文字列として扱う"><span id="toc13">object型をすべて文字列として扱う</span></h3>

  <p><strong>現象：</strong> 売上の合計や日付による月別集計ができない、または想定外の結果になる。<br>
  <strong>原因：</strong> 数字や日付が文字列として読み込まれています。<br>
  <strong>確認方法：</strong> <code>head()</code>や対象列を表示し、実際の値と記号の混入を確認します。<br>
  <strong>修正方法：</strong> 数値は<code>to_numeric()</code>、日付は<code>to_datetime()</code>を検討します。一般的な型変換には<code>astype()</code>を使います。<br>
  <strong>修正後の確認：</strong> <code>info()</code>を再実行し、Dtypeが想定した型へ変わったか確認します。</p>

  <h3 id="float64を小数を記録した列と決めつける"><span id="toc14">float64を「小数を記録した列」と決めつける</span></h3>

  <p><strong>現象：</strong> 整数件数の列がfloat64と表示される。<br>
  <strong>原因：</strong> 欠損値を含む整数列が、今回のDataFrameではfloat64として保持されているためです。<br>
  <strong>確認方法：</strong> 実際の値と欠損値の有無を確認します。<br>
  <strong>修正方法：</strong> 欠損値の意味を確認して処理した後、必要なら整数型へ変換します。<br>
  <strong>修正後の確認：</strong> 今回の<code>返品数</code>は、補完後にint64となりました。</p>

  <h3 id="memory-usageを厳密な全メモリ量だと思う"><span id="toc15">memory usageを厳密な全メモリ量だと思う</span></h3>

  <p><code>info()</code>のmemory usageは、データ規模を知るための目安です。object型が参照するオブジェクトのメモリなど、条件によってはすべてを詳細に含む値ではありません。この記事ではメモリ最適化へ深入りせず、「急に大きなデータを読み込んでいないか」を確認する目安として使います。</p>
  <h2 id="infoでうまく確認できないときの原因と対処"><span id="toc16">info()でうまく確認できないときの原因と対処</span></h2>

  <h3 id="nameerror-name-df-is-not-defined"><span id="toc17">NameError: name &#8216;df&#8217; is not defined</span></h3>

  <p><strong>現象：</strong> <code>df.info()</code>を実行するとNameErrorが出る。<br>
  <strong>原因：</strong> <code>df</code>を作成・読み込みするセルをまだ実行していないか、変数名が違います。<br>
  <strong>確認方法：</strong> ColabでDataFrame作成セルが実行済みか、変数名が<code>df</code>か確認します。<br>
  <strong>修正方法：</strong> DataFrameを作成・読み込みするセルから順に実行します。<br>
  <strong>修正後の確認：</strong> <code>type(df)</code>が<code>pandas.core.frame.DataFrame</code>となり、<code>df.info()</code>が表示されることを確認します。</p>

  <h3 id="attributeerrorが出る"><span id="toc18">AttributeErrorが出る</span></h3>

  <p><strong>現象：</strong> 対象によっては「infoという属性がない」というAttributeErrorが出る。<br>
  <strong>原因：</strong> <code>df</code>がDataFrameではなく、リストなど別のオブジェクトになっている可能性があります。<br>
  <strong>確認方法：</strong> <code>type(df)</code>で対象の種類を確認します。<br>
  <strong>修正方法：</strong> 正しいDataFrame変数を指定するか、必要に応じてDataFrameへ変換します。<br>
  <strong>修正後の確認：</strong> <code>type(df)</code>と<code>df.info()</code>の両方を再確認します。</p>
  <h2 id="自分のデータでinfoを使うときの確認ポイント"><span id="toc19">自分のデータでinfo()を使うときの確認ポイント</span></h2>

  <p>サンプルを自分のCSVやExcelデータへ置き換えるときは、次を確認してください。</p>

  <ul>
  <li>想定した行数と列数になっているか</li>
  <li>必要な列名が存在するか</li>
  <li>各列のNon-Null Countが全行数と一致するか</li>
  <li>数値・日付・文字列のDtypeが想定どおりか</li>
  <li>object型の列に、数字・日付・記号などが混在していないか</li>
  <li>郵便番号や商品コードなど、先頭の0を残すべき列を数値にしていないか</li>
  <li>欠損値を0や平均値で埋めても、データの意味が変わらないか</li>
  <li>修正後に再度<code>info()</code>を実行したか</li>
  </ul>

  <p>特に、郵便番号や商品コードは計算する数値ではありません。CSV読込時に数値として解釈されると先頭の0が失われることがあるため、読み込み段階で文字列として扱う方法を検討します。</p>
  <h2 id="infoの確認結果を次の分析工程へつなげる"><span id="toc20">info()の確認結果を次の分析工程へつなげる</span></h2>

  <p><code>info()</code>は、データ分析のゴールではなく入口です。次の順で進めると、問題を見落としにくくなります。</p>

  <ol type="1">
  <li>CSVやExcelからデータを読み込む</li>
  <li><code>head()</code>で実際の値を確認する</li>
  <li><code>info()</code>で構造・非欠損数・型を確認する</li>
  <li><code>isnull()</code>で欠損値を詳しく確認する</li>
  <li><code>to_numeric()</code>・<code>to_datetime()</code>・<code>astype()</code>で型を整える</li>
  <li><code>fillna()</code>または<code>dropna()</code>で欠損値を処理する</li>
  <li><code>describe()</code>で分布や統計量を確認する</li>
  <li>必要な抽出・集計・可視化へ進む</li>
  </ol>

  <p>構造と型を確認するのが<code>info()</code>、値の分布を確認するのが<code>describe()</code>です。この役割を分けると、どちらを使うか迷いにくくなります。</p>
  <h2 id="まとめinfoは問題を見つけて次の処理を選ぶために使う"><span id="toc21">まとめ：info()は問題を見つけて次の処理を選ぶために使う</span></h2>

  <p><code>df.info()</code>は、DataFrameの行数・列数・列名・Non-Null Count・Dtype・メモリ使用量をまとめて確認するメソッドです。</p>

  <p>特に重要なポイントは次のとおりです。</p>

  <ul>
  <li>Non-Null Countは欠損していない値の数</li>
  <li>欠損数は「全行数−Non-Null Count」で考える</li>
  <li>Dtypeが想定と違う場合は、実際の値を確認してから変換方法を選ぶ</li>
  <li>object型には、文字列だけでなく数字や日付の文字列も含まれる</li>
  <li>欠損値を含む整数列がfloat64になる場合がある</li>
  <li><code>info()</code>はデータを修正せず、戻り値は<code>None</code></li>
  <li>修正後はもう一度<code>info()</code>を実行して結果を検証する</li>
  </ul>

  <p>最初に<code>info()</code>で全体を診断し、欠損値なら<code>isnull()</code>、型の問題なら<code>to_numeric()</code>・<code>to_datetime()</code>・<code>astype()</code>、分布の確認なら<code>describe()</code>へ進みましょう。</p>
  <h2 id="次に読みたい関連記事"><span id="toc22">次に読みたい関連記事</span></h2>

  <ul>
  <li><a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrame入門｜作り方と基本操作を初心者向けに解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-head/">pandas head()の使い方｜df.head()で先頭5行を表示・tail()との違いも解説</a></li>
  <li><a href="https://pythondatalab.com/google-colab-csv/">Google ColabでCSVを読み込む方法｜アップロード・Drive・read_csv</a></li>
  <li><a href="https://pythondatalab.com/pandas-isnull/">欠損値を可視化して攻略！Pandas isnullとヒートマップ活用術</a></li>
  <li><a href="https://pythondatalab.com/pandas-fillna/">pandas fillna()の使い方｜欠損値を0・平均値・中央値・最頻値で埋める方法を初心者向けに解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-drop/">Pandas dropna()・drop_duplicates()の使い方｜欠損・重複の削除とdrop()基本</a></li>
  <li><a href="https://pythondatalab.com/pandas-astype/">pandas astype()の使い方｜文字列・整数・小数の型変換とエラー対処</a></li>
  <li><a href="https://pythondatalab.com/pandas-to-numeric/">pandas to_numeric()の使い方｜文字列の数字を数値に変換する方法</a></li>
  <li><a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方｜文字列の日付変換とformat・NaT対処</a></li>
  <li><a href="https://pythondatalab.com/pandas-info-describe/">pandas describe()の使い方｜統計量の意味と結果の見方を解説</a></li>
  </ul>
<!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc23"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1788050751258" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc24">df.info()では何が分かりますか？</span></h3>
<div class="rank-math-answer ">

<p>DataFrameの行数・列数・列名・各列のNon-Null Count・Dtype・型ごとの列数・おおよそのメモリ使用量が分かります。データ読込後の全体診断に向いています。</p>

</div>
</div>
<div id="faq-question-1788050779638" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc25">Non-Null Countとは何ですか？</span></h3>
<div class="rank-math-answer ">

<p>欠損値ではない値の数です。全5行で4 non-nullなら、欠損値は1件あります。</p>

</div>
</div>
<div id="faq-question-1788050790838" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc26">info()で欠損値の場所まで確認できますか？</span></h3>
<div class="rank-math-answer ">

<p>できません。info()では列ごとの非欠損数から欠損値の存在を判断できます。欠損数は<code>isnull().sum()</code>、欠損している行は条件抽出で確認します。</p>

</div>
</div>
<div id="faq-question-1788050802361" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc27">数字の列がobject型になるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>カンマ・通貨記号・空文字・数字以外の文字などが混在している可能性があります。実際の値を確認し、不要な記号を処理してから<code>to_numeric()</code>による変換を検討します。</p>

</div>
</div>
<div id="faq-question-1788050818426" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc28">欠損値があると整数列がfloat64になるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>今回のように通常のNumPy整数型で作成した列へ<code>NaN</code>が含まれると、欠損値を保持するためfloat64になることがあります。欠損値の意味を確認して処理したあと、必要なら整数型へ変換します。</p>

</div>
</div>
<div id="faq-question-1788050829184" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc29">info()とdescribe()の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p>info()はDataFrameの構造・非欠損数・データ型を確認します。describe()は平均・中央値・標準偏差など、値の分布と統計量を確認します。</p>

</div>
</div>
<div id="faq-question-1788050840930" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc30">info()とdtypesの違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p>info()は行数・列数・非欠損数・型などをまとめて表示します。dtypesは列ごとのデータ型だけを一覧で返します。</p>

</div>
</div>
<div id="faq-question-1788050855362" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc31">print(df.info())でNoneが表示されるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>info()は要約情報を画面に表示し、戻り値として<code>None</code>を返すためです。エラーではありません。通常は<code>df.info()</code>だけを実行します。</p>

</div>
</div>
<div id="faq-question-1788050864690" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc32">info()を実行すると元のDataFrameは変わりますか？</span></h3>
<div class="rank-math-answer ">

<p>変わりません。info()は確認用のメソッドです。型変換や欠損値処理を行うには、別のメソッドを使います。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-info-method/">pandas info()の使い方｜Non-Null Count・データ型・欠損値の見方</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-info-method/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas shift()の使い方｜前の行・次の行の値を取得して比較する方法</title>
		<link>https://pythondatalab.com/pandas-shift/</link>
					<comments>https://pythondatalab.com/pandas-shift/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Sat, 29 Aug 2026 05:51:24 +0000</pubDate>
				<category><![CDATA[集計・変形]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2151</guid>

					<description><![CDATA[<p>pandasのshift()で前の行・2行前・次の行の値を取得する方法を初心者向けに解説。periodsの正負、NaNが出る理由、日付順の注意点、diff()・pct_change()との違いも具体例で学べます。</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-shift/">pandas shift()の使い方｜前の行・次の行の値を取得して比較する方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<style>
  .colab-article pre[class*="language-"],
  .colab-article pre.line-numbers {
    margin: 0 !important;
    padding: 1em;
  }
  .colab-article .table-scroll {
    overflow-x: auto;
    margin: 1em 0;
  }
  .colab-article table.wp-block-table {
    width: auto;
    border-collapse: collapse;
  }
  .colab-article table.wp-block-table th,
  .colab-article table.wp-block-table td {
    border: 1px solid #d0d0d0;
  }
</style>
<div class="colab-article">


<p>「今日の売上を、前日の売上と比べたい」「前の行の値を別の列に入れたい」と思っても、行をずらす方向や、先頭に<code>NaN</code>が出る理由が分かりにくいことがあります。</p>


<p><strong>前の行の値を取得する基本形は<code>df['売上'].shift(1)</code>です。</strong> <code>shift(1)</code>で1行前、<code>shift(2)</code>で2行前、<code>shift(-1)</code>で次の行の値を取得できます。</p>


<p>ただし、<code>shift()</code>が参照するのは「前日」ではなく、<strong>現在の並び順における前の行</strong>です。日付データでは、先に日付型へ変換して昇順に並べることが重要です。</p>

<h2><span id="toc1">この記事でわかること</span></h2>


<ul>
<li><code>shift()</code>で1行前・2行前・次の行の値を取得する方法</li>
<li><code>periods</code>の正負と、値が移動する方向</li>
<li>元の売上と前日売上を比較し、差額や増減率を計算する方法</li>
<li>先頭や末尾に<code>NaN</code>が出る理由</li>
<li><code>shift()</code>・<code>diff()</code>・<code>pct_change()</code>・<code>rolling()</code>の使い分け</li>
<li>コードは動いても結果を誤解しやすい「並び順」の注意点</li>
</ul>


<p><code>shift()</code>は、DataFrameの確認・日付変換・並び替えを終えた後に、時系列データの比較元を作る処理です。差額や増減率を求める前の基礎として位置づけられます。</p>

<h2><span id="toc2">先に結論：目的に応じて4つの機能を使い分ける</span></h2>


<p>比較元となる値を列に残して確認したい場合は<code>shift()</code>を選びます。求めたい結果が最初から決まっている場合は、専用のメソッドを使うと簡潔です。</p>


<div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">機能名</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">何を求めるか</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">選ぶ場面</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">注意点</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>shift()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">前後の行の値</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">比較元の値を列に残したい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">行の並び順が基準になる</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>diff()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行との差額</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">増減した量だけを求めたい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">最初の比較不能行は<code>NaN</code>になる</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>pct_change()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行からの増減率</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">前日比・前月比を求めたい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>0.1</code>は10%を表す</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>rolling()</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">一定範囲の集計値</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">移動平均などで変動をならしたい</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>window</code>分の行をまとめて計算する</td>
</tr>
</tbody>
</table>

</div>
<p>この記事では、比較元を作る<code>shift()</code>に焦点を絞ります。差額・増減率・移動平均の詳しい使い方は、それぞれの関連記事で確認できます。</p>

<h2><span id="toc3">日別売上のサンプルデータを準備する</span></h2>


<p>日付と売上を持つDataFrameを作ります。自分のデータへ置き換えるときも、最初に日付の型と並び順を確認してください。</p>

<pre class="line-numbers"><code class="language-python">import pandas as pd

df = pd.DataFrame({
    "日付": ["2026-08-01", "2026-08-02", "2026-08-03", "2026-08-04", "2026-08-05"],
    "売上": [100, 120, 90, 135, 150]
})

df["日付"] = pd.to_datetime(df["日付"])
df = df.sort_values("日付").reset_index(drop=True)
df</code></pre>
<p><strong>実行結果</strong></p>
<div class="table-scroll"><table border="1" class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
    </tr>
  </tbody>
</table>
</div>
<p>日付は2026年8月1日から5日までの昇順です。8月2日の1行前は8月1日なので、このサンプルでは「前の行の売上」を「前日売上」として扱えます。</p>


<p><strong>ただし、日付が連続していないデータでは、取得できるのは前日ではなく「前の観測日の値」です。</strong> 自分のデータでは、並び順だけでなく日付の欠けも確認してください。</p>


<p>日付変換は<a href="https://pythondatalab.com/pandas-to-datetime/">「pandas to_datetime()の使い方」</a>、並び替えは<a href="https://pythondatalab.com/pandas-sort/">「pandas 並び替え（sort）入門」</a>で詳しく解説しています。</p>

<h2><span id="toc4">shift(1)で1行前の値を取得する</span></h2>


<p><code>Series.shift(1)</code>を使い、売上列の1行前の値を「前日売上」列へ追加します。<code>shift()</code>の<code>periods</code>は省略すると<code>1</code>なので、<code>shift()</code>と<code>shift(1)</code>は同じ結果です。</p>

<pre class="line-numbers"><code class="language-python">df["前日売上"] = df["売上"].shift(1)
df</code></pre>
<p>処理前後を比べると、売上の値が1行下へずれています。</p>


<div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上（処理前）</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日売上（<code>shift(1)</code>）</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
</tr>
</tbody>
</table>

</div>
<p>注目するのは8月2日以降の「前日売上」列です。8月2日には8月1日の<code>100</code>、8月3日には8月2日の<code>120</code>が入ります。</p>


<p>8月1日の前にはデータがないため、比較元が存在せず<code>NaN</code>になります。元のDataFrameから行が削除されたわけではなく、<code>shift()</code>がずらした結果を新しい列として返しています。</p>

<h2><span id="toc5">periodsで2行前・次の行の値を取得する</span></h2>


<p><code>periods</code>には、ずらす行数を指定します。正の値では過去側の行、負の値では未来側の行を各行から参照できます。</p>


<div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">指定</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">各行に入る値</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">値の見かけ上の移動</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">比較元がない場所</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>shift(1)</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">1行前の値</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">1行下へ移動</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">先頭1行</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>shift(2)</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">2行前の値</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">2行下へ移動</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">先頭2行</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>shift(-1)</code></td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">次の行の値</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">1行上へ移動</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">末尾1行</td>
</tr>
</tbody>
</table>

</div>
<p>「正なら上、負なら下」と暗記するより、<strong>現在の行から見て、どの行の値が入るか</strong>で考えると混乱しにくくなります。</p>

<pre class="line-numbers"><code class="language-python">df["2日前売上"] = df["売上"].shift(2)
df["翌日売上"] = df["売上"].shift(-1)

df[["日付", "売上", "前日売上", "2日前売上", "翌日売上"]]</code></pre>
<div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日売上</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">2日前売上</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">翌日売上</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
</tr>
</tbody>
</table>

</div>
<p>8月3日の行を見ると、2日前の売上は8月1日の<code>100</code>、翌日の売上は8月4日の<code>135</code>です。<code>shift(-1)</code>では末尾より後の行が存在しないため、最後の「翌日売上」が<code>NaN</code>になります。</p>


<p><code>shift(1)</code>は1行前、<code>shift(-1)</code>は次の行です。時系列分析では、過去の値を表す列を<strong>ラグ（lag）</strong>、次の値を表す考え方を**リード（lead）**と呼ぶことがあります。</p>

<h2><span id="toc6">前日売上と比較して差額・増減率を計算する</span></h2>


<p>比較元の「前日売上」列を残しておくと、計算過程を確認しながら差額や増減率を求められます。</p>


<ul>
<li>差額：<code>当日売上 - 前日売上</code></li>
<li>増減率：<code>(当日売上 - 前日売上) / 前日売上</code></li>
</ul>

<pre class="line-numbers"><code class="language-python">df["前日差"] = df["売上"] - df["前日売上"]
df["前日比"] = (df["売上"] - df["前日売上"]) / df["前日売上"]

df[["日付", "売上", "前日売上", "前日差", "前日比"]]</code></pre>
<div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日売上</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日差</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日比</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">20</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.20</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">-30</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.25</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">45</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.50</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">15</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">約0.1111</td>
</tr>
</tbody>
</table>

</div>
<p>8月3日は売上<code>90</code>、前日売上<code>120</code>なので、前日差は<code>-30</code>、前日比は<code>-0.25</code>です。つまり、前日より30減り、25%減少したと読めます。</p>


<p>前日比の<code>0.20</code>は0.20%ではなく**20%**です。表示をパーセントに変える場合も、元の値の意味は変わりません。</p>

<pre class="line-numbers"><code class="language-python">result = df[["日付", "売上", "前日売上", "前日差", "前日比"]].copy()
result["前日比（表示用）"] = result["前日比"].map(
    lambda x: f"{x:.1%}" if pd.notna(x) else "—"
)
result</code></pre>
<p><strong>実行結果</strong></p>
<div class="table-scroll"><table border="1" class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日売上</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日差</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日比</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日比（表示用）</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">—</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.200000</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20.0%</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">120.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">-30.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.250000</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">-25.0%</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">90.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">45.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.500000</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">50.0%</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">135.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">15.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.111111</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">11.1%</td>
    </tr>
  </tbody>
</table>
</div>
<p>表示用の列では、<code>0.20</code>が<code>20.0%</code>、<code>-0.25</code>が<code>-25.0%</code>になります。計算に使う列は数値のまま残し、文字列へ変えた表示用の列とは分けておくと安全です。</p>


<p>差額だけが必要なら<a href="https://pythondatalab.com/pandas-diff/">「pandas diff()の使い方」</a>、増減率だけが必要なら<a href="https://pythondatalab.com/pandas-pct-change/">「pandas pct_change()の使い方」</a>を使うと、同じ計算をより簡潔に書けます。<code>shift()</code>を使う利点は、比較元の値を見ながら結果を検算できることです。</p>

<h2><span id="toc7">shift()・diff()・pct_change()の結果を同じデータで比較する</span></h2>


<p>条件をそろえて、3つの方法の役割を確認します。<code>shift()</code>は前の値、<code>diff()</code>は差額、<code>pct_change()</code>は増減率を返します。</p>

<pre class="line-numbers"><code class="language-python">comparison = df[["日付", "売上"]].copy()
comparison["shift_前の値"] = comparison["売上"].shift(1)
comparison["diff_差額"] = comparison["売上"].diff()
comparison["pct_change_増減率"] = comparison["売上"].pct_change(fill_method=None)
comparison</code></pre>
<p><strong>実行結果</strong></p>
<div class="table-scroll"><table border="1" class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">shift_前の値</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">diff_差額</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">pct_change_増減率</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">20.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.200000</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">120.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">-30.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.250000</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">135</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">90.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">45.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.500000</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">135.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">15.0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.111111</td>
    </tr>
  </tbody>
</table>
</div>
<p>8月4日の行では、<code>shift()</code>が比較元の<code>90</code>、<code>diff()</code>が差額の<code>45</code>、<code>pct_change()</code>が増減率の<code>0.50</code>を返します。どれが優れているという関係ではなく、<strong>何を結果として残したいか</strong>で選びます。</p>


<p>複数日の値をまとめて移動平均を求めたい場合は、前後の1行を参照する<code>shift()</code>ではなく<a href="https://pythondatalab.com/pandas-rolling/">「pandas rolling()の使い方」</a>が適しています。</p>

<h2><span id="toc8">コードは動くが結果を誤解しやすい例：日付が並んでいない</span></h2>


<p><code>shift()</code>は、日付の大小ではなく現在の行順を基準にします。次のDataFrameは日付が不規則ですが、コード自体はエラーになりません。</p>

<pre class="line-numbers"><code class="language-python">df_unsorted = pd.DataFrame({
    "日付": pd.to_datetime(["2026-08-03", "2026-08-01", "2026-08-02"]),
    "売上": [90, 100, 120]
})

df_unsorted["前の行の売上"] = df_unsorted["売上"].shift(1)
df_unsorted</code></pre>
<div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">前の行の売上</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
</tr>
</tbody>
</table>

</div>
<h3><span id="toc9">症状・原因・確認方法・修正方法</span></h3>


<div class="table-scroll"><table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr>
  <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">確認項目</th>
  <th style="white-space: nowrap; padding: 0.2em 0.4em;">内容</th>
</tr>
</thead>
<tbody>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">症状</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">8月1日の「前の行」に8月3日の売上<code>90</code>が入る</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">原因</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>shift()</code>の実行前に日付順へ並べていない</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">確認方法</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;">日付列と行順を表示し、昇順になっているか確認する</td>
</tr>
<tr>
  <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">修正方法</td>
  <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>sort_values('日付')</code>を実行してから<code>shift(1)</code>を使う</td>
</tr>
</tbody>
</table>

</div>
<p>この結果の<code>90</code>を「前日売上」と呼ぶのは誤りです。8月1日の1つ前に<strong>並んでいる行</strong>が8月3日だから入った値であり、暦上の前日を表していません。</p>

<pre class="line-numbers"><code class="language-python">df_sorted = df_unsorted[["日付", "売上"]].sort_values("日付").reset_index(drop=True)
df_sorted["前日売上"] = df_sorted["売上"].shift(1)
df_sorted</code></pre>
<p><strong>実行結果</strong></p>
<div class="table-scroll"><table border="1" class="wp-block-table" style="width: auto; border-collapse: collapse;">
  <thead>
    <tr style="text-align: right;">
      <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日売上</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
    </tr>
    <tr>
      <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">90</td>
      <td style="white-space: nowrap; padding: 0.2em 0.4em;">120.0</td>
    </tr>
  </tbody>
</table>
</div>
<p>修正後は、8月2日の前日売上に8月1日の<code>100</code>が入ります。日付が欠けている場合は前日ではなく前の観測行になるため、基本例で確認したとおり日付の連続性にも注意してください。</p>

<h2><span id="toc10">NaNは無条件に0で埋めない</span></h2>


<p><code>shift(1)</code>の先頭や<code>shift(-1)</code>の末尾に出る<code>NaN</code>は、比較元の行が存在しないことを表します。これは処理の失敗ではありません。</p>


<p>先頭の前日売上を<code>0</code>で埋めると、「前日の売上は0だった」という別の意味に変わります。その事実を確認できない場合は、<code>NaN</code>のまま残すか、比較計算から除外するのが安全です。</p>


<h3><span id="toc11">fill_valueを使う場合も値の意味を確認する</span></h3>


<p><code>shift(1, fill_value=0)</code>のように指定すると、移動によって空いた場所を<code>0</code>で埋められます。ただし、これは実際の前日売上を取得したわけではありません。<code>0</code>に分析上の根拠がある場合だけ使い、単に<code>NaN</code>を消す目的では使わないようにしましょう。</p>


<p>欠損値を何で埋めるかは分析目的によって異なります。<a href="https://pythondatalab.com/pandas-fillna/">「pandas fillna()の使い方」</a>で選択基準を確認してください。</p>

<h2><span id="toc12">「値をずらす」と「日付をずらす」は同じではない</span></h2>


<p>この記事の<code>df['売上'].shift(1)</code>は、<strong>売上の値を1行ずらし、比較元を作る処理</strong>です。日付列の値自体は変わりません。</p>


<p>一方、日付インデックスを持つデータでは、<code>freq</code>を指定してインデックスを時間方向へ移動する使い方もあります。これは行の値を前後比較する今回の目的とは挙動が異なります。初心者のうちは、まず<code>freq</code>を指定しない基本形で「行をずらす」考え方を身につければ十分です。</p>

<h2><span id="toc13">データ分析の流れでshift()を使う位置</span></h2>


<p>日別データで前日値を比較するときは、次の順番で進めます。</p>


<ol>
<li>DataFrameを読み込み、列名・値・データ型を確認する</li>
<li>日付列を<code>to_datetime()</code>で日付型へ変換する</li>
<li><code>sort_values()</code>で日付の昇順へ並べる</li>
<li><code>shift()</code>で比較元となる前の行の値を作る</li>
<li>目的に応じて差額・増減率を計算する</li>
<li>表やグラフで変化を確認する</li>
</ol>


<p>DataFrameの基本は<a href="https://pythondatalab.com/pandas-dataframe/">「Pandas DataFrame入門」</a>、列を追加する方法全般は<a href="https://pythondatalab.com/pandas-add-column/">「pandasで新しい列を追加する方法」</a>で確認できます。</p>


<p>自分のデータへ置き換えるときは、<strong>日付型・並び順・日付の欠け・比較元が存在しない行</strong>の4点を確認してください。</p>

<h2><span id="toc14">まとめ</span></h2>


<ul>
<li>前の行の値は<code>shift(1)</code>、2行前は<code>shift(2)</code>、次の行は<code>shift(-1)</code>で取得する</li>
<li><code>shift(1)</code>では値が1行下へずれ、各行に1行前の値が入る</li>
<li>先頭や末尾の<code>NaN</code>は比較元が存在しないことを示すため、根拠なく0で埋めない</li>
<li><code>shift()</code>は前後の値、<code>diff()</code>は差額、<code>pct_change()</code>は増減率、<code>rolling()</code>は一定範囲の集計値を求める</li>
<li><code>shift()</code>が参照するのは前日ではなく、現在の並び順における前の行である</li>
<li>日付データでは、日付型への変換と昇順への並び替えを済ませてから実行する</li>
</ul>


<p>比較元の値を残して計算過程を確かめたいときに<code>shift()</code>を使えば、前の行との比較を安全に組み立てられます。</p>

<h2><span id="toc15">関連記事</span></h2>


<ul>
<li><a href="https://pythondatalab.com/pandas-diff/">pandas diff()の使い方｜前の行との差分・前日からの増減を計算する方法</a></li>
<li><a href="https://pythondatalab.com/pandas-pct-change/">pandas pct_change()の使い方｜前日比・増減率の計算方法</a></li>
<li><a href="https://pythondatalab.com/pandas-rolling/">pandas rolling()の使い方｜移動平均・window・NaNを初心者向けに解説</a></li>
<li><a href="https://pythondatalab.com/pandas-sort/">pandas 並び替え（sort）入門｜sort<em>values・sort</em>indexの違いと複数列ソート</a></li>
<li><a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方｜文字列の日付変換とformat・NaT対処</a></li>
<li><a href="https://pythondatalab.com/pandas-add-column/">pandasで新しい列を追加する方法</a></li>
<li><a href="https://pythondatalab.com/pandas-fillna/">pandas fillna()の使い方｜欠損値を0・平均値・中央値で埋める方法</a></li>
</ul>

<!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc16"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p>

</div>
<script>Prism.highlightAll();</script>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1787982540051" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc17">shift(1)とshift(-1)の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p><code>shift(1)</code>は各行に1行前の値を入れ、先頭が<code>NaN</code>になります。<code>shift(-1)</code>は各行に次の行の値を入れ、末尾が<code>NaN</code>になります。</p>

</div>
</div>
<div id="faq-question-1787982570541" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc18">先頭にNaNが出るのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p><code>shift(1)</code>を実行した先頭行には、比較元となる1行前のデータがないためです。エラーではなく、比較不能であることを示す自然な結果です。</p>

</div>
</div>
<div id="faq-question-1787982582990" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc19">shift()とdiff()の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p><code>shift()</code>は前の行の値そのものを返し、<code>diff()</code>は現在値と前の行との差額を返します。比較元を確認したいなら<code>shift()</code>、差額だけが必要なら<code>diff()</code>を選びます。</p>

</div>
</div>
<div id="faq-question-1787982600620" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc20">shift()は必ず前日の値を取得しますか？</span></h3>
<div class="rank-math-answer ">

<p>いいえ。取得するのは現在の並び順における前の行です。前日値として扱うには、日付順に並んでいることに加え、必要に応じて日付の欠けも確認します。</p>

</div>
</div>
<div id="faq-question-1787982606963" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc21">shift()で生じたNaNを0で埋めてもよいですか？</span></h3>
<div class="rank-math-answer ">

<p>前の行の値が実際に0だったと判断できる場合に限ります。<code>fill_value=0</code>でも同じで、比較元が存在しないという意味を消すため、根拠なく指定しないでください。</p>

</div>
</div>
<div id="faq-question-1787982625152" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc22">Series.shift()とDataFrame.shift()の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p>Seriesに使うと1列の値、DataFrameに使うと対象DataFrame全体がずれます。この記事では比較対象を明確にするため、<code>df['売上'].shift()</code>というSeriesの形を使っています。</p>

</div>
</div>
<div id="faq-question-1787982635679" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc23">日付インデックスを1日ずらす処理と同じですか？</span></h3>
<div class="rank-math-answer ">

<p>同じではありません。この記事では<code>freq</code>を指定せず、値を行単位でずらしています。<code>freq</code>を指定する使い方は日付インデックスを時間方向へ移動するため、別の目的として区別してください。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-shift/">pandas shift()の使い方｜前の行・次の行の値を取得して比較する方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-shift/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas pct_change()の使い方｜前日比・増減率の計算方法</title>
		<link>https://pythondatalab.com/pandas-pct-change/</link>
					<comments>https://pythondatalab.com/pandas-pct-change/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Tue, 25 Aug 2026 01:12:55 +0000</pubDate>
				<category><![CDATA[集計・変形]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2135</guid>

					<description><![CDATA[<p>pandasのpct_change()で前の行からの増減率や前日比を計算する方法を初心者向けに解説。0.1の読み方、パーセント表示、periods、NaN、比較元が0の場合、diff・shiftとの違いまで具体例で学べます。</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-pct-change/">pandas pct_change()の使い方｜前日比・増減率の計算方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<style>
.colab-article {
  max-width: 100%;
  overflow-wrap: anywhere;
}
.colab-article pre[class*="language-"] {
  box-sizing: border-box;
  max-width: 100%;
  margin: 0 !important;
  padding: 1em;
  overflow-x: auto;
}
.colab-article .colab-table-scroll {
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  margin: 1em 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.colab-article table.wp-block-table {
  width: auto;
  min-width: max-content;
  border-collapse: collapse;
}
.colab-article table.wp-block-table th,
.colab-article table.wp-block-table td {
  border: 1px solid #d0d7de;
}
.colab-article .colab-figure {
  margin: 1em 0;
  text-align: center;
}
.colab-article .colab-figure img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
}
.colab-article .colab-figure figcaption {
  margin-top: 0.4em;
  color: #555;
  font-size: 0.9em;
}
.colab-article .colab-formula {
  overflow-x: auto;
}
</style>
<div class="colab-article">

<p>日別売上を見て、「前日より100円増えた」ことは分かっても、「何％増えたか」の計算で迷うことはありませんか。</p>
<p>Pandasでは、前の行からの<strong>増減率</strong>を<code>pct_change()</code>で計算できます。</p>
<pre class="line-numbers"><code class="language-python">df["前日比"] = df["売上"].pct_change(fill_method=None)</code></pre>
<p>最初に覚えるポイントは3つです。</p>
<ol>
  <li>結果の<code>0.1</code>は<strong>10％増加</strong>を表す</li>
  <li>最初の行は比較元がないため<code>NaN</code>になる</li>
  <li>比較するのは暦上の前日ではなく<strong>データ上の前の行</strong></li>
</ol>
<p>したがって「前日比」と呼べるのは、日付が1日間隔で古い順に並んでいる場合です。この記事では日別売上を例に、基本的な使い方から結果の読み方、<code>periods</code>、0や欠損値の注意点まで解説します。</p>
<h2><span id="toc1">この記事でわかること</span></h2>
<ul>
  <li><code>pct_change()</code>で前の行からの増減率を求める方法</li>
  <li><code>0.1</code>や<code>-0.2</code>をパーセントで読む方法</li>
  <li>最初の行が<code>NaN</code>になる理由</li>
  <li><code>periods</code>で比較する行を変える方法</li>
  <li>日付の並び、欠損値、比較元が0の場合の注意点</li>
  <li><code>diff()</code>・<code>shift()</code>・<code>rolling()</code>との使い分け</li>
</ul>
<p>この記事のゴールは、日付と行順を確認してから<code>pct_change()</code>を使い、増減率を正しく計算・解釈できるようになることです。</p>
<h2><span id="toc2">先に結論：増減率を求めるならpct_change()を使う</span></h2>
<p>似た処理は、知りたい内容によって使い分けます。</p>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">機能</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">何を求めるか</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">選ぶ場面</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">主な注意点</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>pct_change()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行からの増減率</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">前日比・前月比を知りたい</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">結果は割合。<code>0.1</code>は10％</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>diff()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行との差</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">何円・何個増えたか知りたい</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">単位は元データと同じ</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>shift()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行の値</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">現在値と比較元を並べたい</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">それ自体は差や率を計算しない</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>rolling()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近数行の集計値</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">移動平均で変動を滑らかにしたい</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">増減率を求める処理ではない</td>
      </tr>
    </tbody>
  </table>
</div>
<p>たとえば、売上が1,000円から1,100円になった場合、<code>diff()</code>の結果は100円、<code>pct_change()</code>の結果は0.1、つまり10％です。</p>
<p><strong>増減した量なら<code>diff()</code>、増減した割合なら<code>pct_change()</code></strong>と判断すると迷いにくくなります。</p>
<h2><span id="toc3">pct_change()の計算式と結果の読み方</span></h2>
<p><code>pct_change()</code>は、現在の値を前の行と比べて、どれだけ増減したかを割合で返します。</p>
<p class="colab-formula"><code>増減率 = (現在の値 − 前の行の値) ÷ 前の行の値</code></p>
<p>結果を読むときは、<strong>符号</strong>と<strong>100倍した値</strong>に注目します。</p>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">結果</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">パーセントでの読み方</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">意味</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>0.10</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">10％</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">10％増加</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>-0.20</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-20％</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">20％減少</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>0.00</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0％</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">変化なし</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>1.00</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100％</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2倍になった</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>-1.00</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-100％</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0になった</td>
      </tr>
    </tbody>
  </table>
</div>
<p>たとえば<code>0.1</code>は0.1％ではなく、10％増加です。</p>
<h2><span id="toc4">日別売上のサンプルデータを用意する</span></h2>
<p>ここでは、5日分の日付と売上を持つDataFrameを使います。Google Colabで上から順番に実行できます。</p>
<pre class="line-numbers"><code class="language-python">import pandas as pd
import numpy as np

df = pd.DataFrame({
    "日付": ["2026-08-18", "2026-08-19", "2026-08-20", "2026-08-21", "2026-08-22"],
    "売上": [1000, 1100, 990, 990, 1188]
})

df</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-18</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-19</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-20</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-21</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-22</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1188</td>
      </tr>
    </tbody>
  </table>
</div>
<p>売上は1,000円、1,100円、990円、990円、1,188円と変化しています。この同じデータで、差額と増減率の違いを確認します。</p>
<h2><span id="toc5">pct_change()の前に日付型と並び順を確認する</span></h2>
<p><code>pct_change()</code>は、日付の意味を読み取って「前日」を探すのではなく、<strong>現在の行と前の行</strong>を比較します。そのため、計算前に日付型へ変換し、古い日付から並べることが重要です。</p>
<pre class="line-numbers"><code class="language-python">df["日付"] = pd.to_datetime(df["日付"])
df = df.sort_values("日付").reset_index(drop=True)

df.dtypes</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">0</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">datetime64[ns]</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">売上</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">int64</td>
      </tr>
    </tbody>
  </table>
</div>
<p><code>日付</code>が<code>datetime64[ns]</code>になっていることを確認します。そのうえで<code>sort_values()</code>を使い、日付の昇順に整えています。</p>
<p>日付変換の詳細は「pandas to_datetime()の使い方」、並び替えは「pandas 並び替え（sort）入門」で確認できます。</p>
<h2><span id="toc6">pct_change()で前の行からの増減率を計算する</span></h2>
<p>売上列に<code>pct_change()</code>を使います。<code>fill_method=None</code>を明示すると、欠損値を自動的に前の値で補わずに計算できます。</p>
<pre class="line-numbers"><code class="language-python">df["前日比"] = df["売上"].pct_change(fill_method=None)

df</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日比</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-18</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-19</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.1</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-20</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.1</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-21</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-22</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1188</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.2</td>
      </tr>
    </tbody>
  </table>
</div>
<p><code>前日比</code>列では、2行目が<code>0.1</code>、3行目が<code>-0.1</code>、4行目が<code>0.0</code>、5行目が<code>0.2</code>になります。</p>
<ul>
  <li>1,000円から1,100円：10％増加</li>
  <li>1,100円から990円：10％減少</li>
  <li>990円から990円：変化なし</li>
  <li>990円から1,188円：20％増加</li>
</ul>
<p>最初の行が<code>NaN</code>になるのは、比較する前の行が存在しないためです。エラーではありません。</p>
<h2><span id="toc7">どの値と比較したかを表で確認する</span></h2>
<p>結果だけでは計算の向きが分かりにくいため、<code>shift()</code>で比較元、<code>diff()</code>で増減額を表示します。現在値・比較元・結果を横に並べると、どの値を分母にしたか確認できます。</p>
<pre class="line-numbers"><code class="language-python">comparison = df[["日付", "売上"]].copy()
comparison["前の行の売上"] = comparison["売上"].shift(1)
comparison["増減額"] = comparison["売上"].diff()
comparison["増減率"] = comparison["売上"].pct_change(fill_method=None)
comparison["増減率（%）"] = comparison["増減率"] * 100

comparison</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前の行の売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減額</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減率</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減率（%）</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-18</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-19</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">10.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-20</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-110.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-10.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-21</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-22</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1188</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">198.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">20.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>2行目では、現在の売上1,100円から比較元の1,000円を引き、その100円を1,000円で割っています。</p>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">現在の売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前の行の売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減額</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">計算</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減率</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1,100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>(1100 - 1000) / 1000</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.10＝10％</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1,100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-110</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>(990 - 1100) / 1100</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.10＝-10％</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>(990 - 990) / 990</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.00＝0％</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1,188</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">198</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>(1188 - 990) / 990</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.20＝20％</td>
      </tr>
    </tbody>
  </table>
</div>
<p>役割は次のように整理できます。</p>
<ul>
  <li><code>shift()</code>：比較元の値を確認する</li>
  <li><code>diff()</code>：増減した量を求める</li>
  <li><code>pct_change()</code>：増減した割合を求める</li>
</ul>
<h2><span id="toc8">増減率をパーセントで表示する</span></h2>
<p><code>pct_change()</code>の結果を数値としてパーセントに直す場合は、100を掛けます。分析に使える数値のまま保持するため、<code>%</code>記号を含む文字列には変換しません。</p>
<pre class="line-numbers"><code class="language-python">df["前日比（%）"] = (df["前日比"] * 100).round(1)

df[["日付", "売上", "前日比", "前日比（%）"]]</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日比</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日比（%）</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-18</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-19</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">10.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-20</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-10.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-21</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-22</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1188</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">20.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p><code>前日比</code>の0.1と、<code>前日比（%）</code>の10.0は同じ変化を表します。前者は割合、後者は100倍したパーセント値です。</p>
<p>列を追加する基本については「pandasで新しい列を追加する方法」で詳しく確認できます。</p>
<h2><span id="toc9">periodsで2行前からの増減率を計算する</span></h2>
<p><code>periods</code>は、何行前と比較するかを指定する引数です。初期値は1です。<code>periods=2</code>にすると2行前と比較します。</p>
<pre class="line-numbers"><code class="language-python">df["2行前比"] = df["売上"].pct_change(periods=2, fill_method=None)
df["2行前比（%）"] = (df["2行前比"] * 100).round(1)

df[["日付", "売上", "2行前比", "2行前比（%）"]]</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">2行前比</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">2行前比（%）</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-18</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-19</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-20</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-1.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-21</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">990</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.10</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-10.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-22</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1188</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.20</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">20.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>最初の2行は、2行前の比較元がないため<code>NaN</code>になります。</p>
<p>3行目の売上990円は2行前の1,000円と比べて1％減少、4行目の990円は2行前の1,100円と比べて10％減少、5行目の1,188円は2行前の990円と比べて20％増加しています。</p>
<p><code>periods=2</code>は「2日前」ではなく<strong>2行前</strong>です。日付が1日間隔で並んでいるときだけ、2日前との比較と一致します。</p>
<h2><span id="toc10">正の値・負の値・0・NaNをどう読むか</span></h2>
<p>結果は次のように読みます。</p>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">結果</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">判断</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">正の値</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">比較元より増加</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">負の値</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">比較元より減少</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>0.0</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">比較元から変化なし</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>NaN</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">比較元がない、または計算に必要な値が欠けている</td>
      </tr>
    </tbody>
  </table>
</div>
<p>注意したいのは0です。100から0への変化は-100％ですが、0から100への増加率は計算できません。比較元の0を分母にできないため、増加と減少は単純に対称にはなりません。</p>
<h2><span id="toc11">コードは動くが結果を誤解しやすい場面</span></h2>
<h3><span id="toc12">前の行は必ずしも前日ではない</span></h3>
<p>次のデータでは、8月19日の次が8月22日です。<code>pct_change()</code>は8月22日を8月19日と比較します。</p>
<pre class="line-numbers"><code class="language-python">business_days = pd.DataFrame({
    "日付": pd.to_datetime(["2026-08-18", "2026-08-19", "2026-08-22"]),
    "売上": [1000, 1100, 1210]
})

business_days["前の行からの増減率"] = business_days["売上"].pct_change(fill_method=None)
business_days</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前の行からの増減率</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-18</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-19</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.1</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-22</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1210</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.1</td>
      </tr>
    </tbody>
  </table>
</div>
<p>8月22日の結果は10％ですが、これは8月21日との前日比ではなく、<strong>データ上の前の行である8月19日からの増減率</strong>です。</p>
<p>営業日データなら「前営業日比」と呼べます。暦上の前日比が必要な場合は、日付の間隔を確認し、必要に応じて日次の行をそろえてから計算します。月次データなら同じ考え方で前月比を計算できます。</p>
<h3><span id="toc13">比較元が0の場合は無限大になる</span></h3>
<p>比較元が0の場合、増減率の計算では0による割り算が発生します。</p>
<pre class="line-numbers"><code class="language-python">zero_example = pd.DataFrame({
    "売上": [100, 0, 50]
})

zero_example["増減率"] = zero_example["売上"].pct_change(fill_method=None)
zero_example</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減率</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-1.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">50</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">inf</td>
      </tr>
    </tbody>
  </table>
</div>
<p>100から0への変化は<code>-1.0</code>、つまり-100％です。一方、0から50への変化は<code>inf</code>（無限大）になります。</p>
<p>これはコードの失敗ではなく、比較元が0なので通常の増減率を定義できないためです。0を都合のよい別の値に置き換えるのではなく、元データで0が何を意味するか確認し、必要なら該当行を別扱いにします。</p>
<h3><span id="toc14">欠損値を安易に0で埋めない</span></h3>
<p>欠損値があるデータでは、比較に必要な値がそろわない行が<code>NaN</code>になります。</p>
<pre class="line-numbers"><code class="language-python">missing_example = pd.DataFrame({
    "売上": [100, np.nan, 120]
})

missing_example["増減率"] = missing_example["売上"].pct_change(fill_method=None)
missing_example</code></pre>
<div class="colab-table-scroll">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減率</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
    </tbody>
  </table>
</div>
<p>2行目は現在値が欠損し、3行目は比較元となる2行目が欠損しているため、どちらも増減率を計算できません。</p>
<p>欠損値を0で埋めてから計算すると、実際には観測されていない「売上0円」を作り、-100％や<code>inf</code>を発生させる可能性があります。補完する場合は、列の意味と欠損理由を確認してください。欠損値の扱いは「pandas fillna()の使い方」で詳しく解説しています。</p>
<p>Pandasのバージョンによる欠損値補完の挙動へ依存しないよう、この記事では<code>fill_method=None</code>を明示しています。</p>
<h3><span id="toc15">日付を並び替えないと計算結果が変わる</span></h3>
<p><code>pct_change()</code>は現在の行順を使います。日付が降順や不規則な順番のままでもコードは動きますが、前日比としては誤った結果になることがあります。</p>
<p>計算前に次の3点を確認します。</p>
<ol>
  <li>日付列がdatetime型になっている</li>
  <li>日付が古い順に並んでいる</li>
  <li>各行の日付間隔が目的に合っている</li>
</ol>
<p>CSVを読み込んだ直後は、<code>head()</code>・<code>dtypes</code>・日付の並びを確認してから計算すると安全です。</p>
<h2><span id="toc16">日別売上と前日比を折れ線グラフで確認する</span></h2>
<p>最後に、売上と前日比を同じ期間で可視化します。左軸が売上、右軸が前日比です。日本語をColabで表示するため、最初の実行時に<code>japanize-matplotlib</code>を読み込みます。</p>
<pre class="line-numbers"><code class="language-python">%pip -q install japanize-matplotlib

import matplotlib.pyplot as plt
import japanize_matplotlib

fig, ax1 = plt.subplots(figsize=(9, 5))

ax1.plot(df["日付"], df["売上"], marker="o", color="tab:blue", label="売上")
ax1.set_xlabel("日付")
ax1.set_ylabel("売上（円）", color="tab:blue")
ax1.tick_params(axis="y", labelcolor="tab:blue")
ax1.grid(alpha=0.3)

ax2 = ax1.twinx()
ax2.plot(df["日付"], df["前日比（%）"], marker="s", color="tab:red", label="前日比")
ax2.axhline(0, color="gray", linewidth=1)
ax2.set_ylabel("前日比（%）", color="tab:red")
ax2.tick_params(axis="y", labelcolor="tab:red")

lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(lines1 + lines2, labels1 + labels2, loc="upper left")

plt.title("日別売上と前日比の推移")
fig.autofmt_xdate()
plt.tight_layout()
plt.show()</code></pre>

<figure class="colab-figure">
  <img decoding="async" src="data:image/png;base64,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vr6iQ4cOIiIiQkRERIiDBw9KVrctY6aWwVzNj5laBnM1P2ZqfszUMpir+TFTsja7WXglIiICNWvWxLp162AymSCXF05Sfvnll9ixYwe+++47qNVqXLp0CYmJidDpdOjYsaPEVds2ZmoZzNX8mKllMFfzY6bmx0wtg7maHzMlq5K6yzSXn376SchkMrF//34hROHFi4UQYsOGDSI4OFjodDopyyuTmKllMFfzY6aWwVzNj5maHzO1DOZqfsyUrMkuzskDgOeeew6jRo3CiBEjsG/fvuJvRy5fvozBgwdzydnHwEwtg7maHzO1DOZqfszU/JipZTBX82OmZE12c7hmkaFDh+LQoUNo1qwZoqKiUFBQgJUrV6JevXpSl1ZmMVPLYK7mx0wtg7maHzM1P2ZqGczV/JgpWYPdNXkFBQW4dOkSzpw5AwAYNGiQxBWVfczUMpir+TFTy2Cu5sdMzY+ZWgZzNT9mStZgd00eERERERFReWY35+QRERERERERmzwiIiIiIiK7wiaPiIiIiIjIjrDJIyIiIiIisiNs8oiIiIiIiOwImzwiIiIiIiI7wiaPiIgIgNFolLoEIiIis2CTR0REdmXOnDnw9PR84H8///zzPY/r1q0bNm7ceM/t169fR0BAgDVKJyIiMgs2eUREZFc0Gg0GDx6MzMzMUv+rX78+9Hr9PY/Zu3cvWrRoIVHVRERE5sMmj4iIyr3NmzcjIiICQUFBUpdCRET0nymlLoCIiEhqX3zxBVq2bIlevXph586dJe4TQiA7Oxuenp6oXLkyzpw5I1GVREREj4ZNHhERlWt79uzB/v370bJlS/zwww/33J+ZmYmAgABkZmZavzgiIqLHwMM1iYjI7ixduvS+i678+eefxdvp9XqMGzcOTz31VPFte/fuxaJFi6Qom4iIyCzY5BERkd159dVX77vwyt2Lq+zbtw+NGjXCs88+W3xbzZo1MXfuXBw4cECK0omIiP4zNnlERFRutW/fHp999lmJ24KCgjB//nyMHDkSOp1OosqIiIgeH8/JIyKics3Z2fme2/r374+YmBgYDAYJKiIiIvpv2OQRERH9g0wmwwcffAAAnM0jIqIyh4drEhGR3XnUhVceJD4+HhkZGUhNTYVMJrNwxURERObDmTwiIrIro0ePxogRIxAcHFzq/VFRUfDz83vo8yxfvhyLFy9Gbm5uidU3iYiIbJ1MCCGkLoKIiIiIiIjMg4drEhERERER2RE2eURERERERHaETR4REREREZEdYZNHRERERERkR9jkERERERER2RE2eURERERERHaETR4REREREZEdYZNHRERERERkR9jkERERERER2RE2eURERERERHbk/1ECRHXW6IGPAAAAAElFTkSuQmCC
" alt="日別売上と前日比の推移を示す折れ線グラフ">
  <figcaption>日別売上と前日比の推移</figcaption>
</figure>
<p>売上が同じ990円だった8月21日は前日比が0％、1,188円へ増えた8月22日は20％になります。</p>
<p>グラフでは、売上の水準と増減率を混同しないことが重要です。売上が最も大きい日と、増加率が最も大きい日は必ずしも一致しません。折れ線グラフの基本設定は「Matplotlib 折れ線グラフ入門」で確認できます。</p>
<h2><span id="toc17">データ分析の流れでpct_change()を使う位置</span></h2>
<p><code>pct_change()</code>は、データを読み込んですぐ使うのではなく、日付と値を確認した後の「変化を計算する」段階で使用します。</p>
<ol>
  <li>CSVなどからDataFrameを読み込む</li>
  <li><code>head()</code>や<code>dtypes</code>で内容を確認する</li>
  <li><code>to_datetime()</code>で日付型へ変換する</li>
  <li><code>sort_values()</code>で日付順に並べる</li>
  <li><code>pct_change()</code>で増減率を計算する</li>
  <li><code>rolling()</code>や折れ線グラフで傾向を確認する</li>
</ol>
<p>期間ごとの合計値を作る場合は、先に<code>resample()</code>で月次などへ集計してから<code>pct_change()</code>を使います。移動平均で短期変動を滑らかにする場合は「pandas rolling()の使い方」、期間集計は「pandas resample()の使い方」を参照してください。</p>
<h2><span id="toc18">まとめ</span></h2>
<ul>
  <li><code>pct_change()</code>は前の行からの<strong>増減率</strong>を計算する</li>
  <li><code>0.1</code>は10％増加、<code>-0.2</code>は20％減少を表す</li>
  <li>最初の行は比較元がないため<code>NaN</code>になる</li>
  <li><code>periods=2</code>は2日前ではなく2行前との比較になる</li>
  <li>前日比として使う前に、日付型・並び順・日付間隔を確認する</li>
  <li>比較元が0の場合は<code>inf</code>、欠損値を含む比較は<code>NaN</code>になることがある</li>
  <li>増減量は<code>diff()</code>、比較元は<code>shift()</code>、平滑化は<code>rolling()</code>を使う</li>
</ul>
<p>まずは「割合なら<code>pct_change()</code>」「量なら<code>diff()</code>」と使い分けましょう。そのうえで、結果が前日比・前営業日比・前月比のどれに当たるかを確認することが大切です。</p>
<h2><span id="toc19">関連記事</span></h2>
<ul>
  <li><a href="https://pythondatalab.com/pandas-diff/">pandas diff()の使い方｜前の行との差分・前日からの増減を計算する方法</a></li>
  <li><a href="https://pythondatalab.com/pandas-rolling/">pandas rolling()の使い方｜移動平均・window・NaNを初心者向けに解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-resample/">pandas resample()の使い方｜日付データを月別・週別に集計する方法</a></li>
  <li><a href="https://pythondatalab.com/pandas-sort/">pandas 並び替え（sort）入門｜sort_values・sort_indexの違い</a></li>
  <li><a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方｜文字列の日付変換とNaT対処</a></li>
  <li><a href="https://pythondatalab.com/pandas-add-column/">pandasで新しい列を追加する方法</a></li>
  <li><a href="https://pythondatalab.com/pandas-fillna/">pandas fillna()の使い方｜欠損値を埋める方法</a></li>
  <li><a href="https://pythondatalab.com/matplotlib-line-legend-color/">Matplotlib 折れ線グラフ入門</a></li>
  <li><a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrame入門｜作り方と基本操作</a></li>
</ul>
<!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc20"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p></div>
<script>Prism.highlightAll();</script>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1787619593495" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc21">pct_change()の0.1は何％ですか？</span></h3>
<div class="rank-math-answer ">

<p>10％です。<code>pct_change()</code>は割合を返すため、パーセントで読むときは100を掛けます。<code>-0.2</code>なら20％減少です。</p>

</div>
</div>
<div id="faq-question-1787619623353" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc22">最初の行がNaNになるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>比較する前の行が存在しないためです。エラーではなく、計算に必要な比較元がないことを表しています。</p>

</div>
</div>
<div id="faq-question-1787619636868" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc23">前日比と前月比は計算できますか？</span></h3>
<div class="rank-math-answer ">

<p>計算できます。ただし、<code>pct_change()</code>は日付ではなく前の行と比較します。日次データを日付順に並べれば前日比、月次データを月順に並べれば前月比として使えます。日付が欠けている場合は、前営業日比などになる点に注意してください。</p>

</div>
</div>
<div id="faq-question-1787619643328" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc24">pct_change()とdiff()の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p><code>pct_change()</code>は増減率、<code>diff()</code>は増減量を求めます。1,000円から1,100円になった場合、<code>pct_change()</code>は0.1（10％）、<code>diff()</code>は100円です。</p>

</div>
</div>
<div id="faq-question-1787619655129" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc25">比較元が0の場合はどうなりますか？</span></h3>
<div class="rank-math-answer ">

<p>0で割ることになるため、増加時には<code>inf</code>が返ることがあります。通常の増減率を定義できない状態なので、0が何を意味するか確認し、別扱いを検討します。</p>

</div>
</div>
<div id="faq-question-1787619676916" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc26">欠損値がある場合はどうなりますか？</span></h3>
<div class="rank-math-answer ">

<p><code>fill_method=None</code>を指定した場合、現在値または比較元が欠損している行は<code>NaN</code>になります。欠損値を埋める場合は、データ上の意味を確認してから処理してください。</p>

</div>
</div>
<div id="faq-question-1787619688702" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc27">結果をパーセント表示できますか？</span></h3>
<div class="rank-math-answer ">

<p>結果に100を掛ければパーセント値になります。計算に使う場合は、<code>%</code>記号を付けた文字列ではなく数値のまま保存する方が扱いやすくなります。</p>

</div>
</div>
<div id="faq-question-1787619696618" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc28">前日比が合わないのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>日付の並び順、日付の欠け、重複日付、欠損値、比較元が0でないかを確認してください。<code>pct_change()</code>が比較するのは暦上の前日ではなく、現在の並びで1つ前にある行です。</p>

</div>
</div>
<div id="faq-question-1787619706498" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc29">DataFrameの複数列にも使えますか？</span></h3>
<div class="rank-math-answer ">

<p>使えます。<code>df[["売上", "客数"]].pct_change(fill_method=None)</code>のように指定すると、売上と客数を列ごとに計算します。最初は、この記事のように1列ずつ結果を確認する方が理解しやすいでしょう。</p>

</div>
</div>
<div id="faq-question-1787619717509" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc30">axisやfreqも覚える必要がありますか？</span></h3>
<div class="rank-math-answer ">

<p>通常の前日比・前月比では、まず初期設定の行方向だけ理解すれば十分です。列方向を比較する<code>axis</code>や、日時オフセットを使う<code>freq</code>は発展的な指定なので、必要になった段階で確認しましょう。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-pct-change/">pandas pct_change()の使い方｜前日比・増減率の計算方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-pct-change/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas diff()の使い方｜前の行との差分・前日からの増減を計算する方法</title>
		<link>https://pythondatalab.com/pandas-diff/</link>
					<comments>https://pythondatalab.com/pandas-diff/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Sat, 22 Aug 2026 13:33:35 +0000</pubDate>
				<category><![CDATA[集計・変形]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2127</guid>

					<description><![CDATA[<p>日別売上を見ながら、「前日よりいくら増えたのか」を1行ずつ計算するのは大変です。pandasのdiff()を使えば、現在の行から1つ前の行を引いた差分をまとめて計算できます。 先に結論を示すと、前の行からの増減「量」を求 [&#8230;]</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-diff/">pandas diff()の使い方｜前の行との差分・前日からの増減を計算する方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<div class="colab-article">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
  <style>
    .colab-article pre[class*="language-"] { margin: 0 !important; padding: 1em; }
    .colab-article table.wp-block-table th, .colab-article table.wp-block-table td { border: 1px solid #d0d0d0; }
    .colab-article .colab-figure { margin: 1em 0; }
    .colab-article .colab-figure img { max-width: 100%; height: auto; }
  </style>


<p>日別売上を見ながら、「前日よりいくら増えたのか」を1行ずつ計算するのは大変です。pandasの<code>diff()</code>を使えば、<strong>現在の行から1つ前の行を引いた差分</strong>をまとめて計算できます。</p>

<p>先に結論を示すと、前の行からの増減「量」を求める基本形は<code>df["売上"].diff()</code>です。ただし、<code>diff()</code>は日付そのものではなく、<strong>DataFrameの現在の行順</strong>に沿って計算します。時系列データでは、日付型への変換と日付順の並び替えを先に済ませることが重要です。</p>

<p>この記事では日別売上を例に、引き算の向き、先頭が<code>NaN</code>になる理由、<code>periods</code>の意味、<code>shift()</code>・<code>pct_change()</code>・<code>rolling()</code>との違いまで、Google Colabで実行しながら確認します。</p>
<h2 id="この記事でわかること"><span id="toc1">この記事でわかること</span></h2>

<ul>
<li><code>diff()</code>で前の行との差分を求める方法</li>
<li>差分が正・負・0になる意味</li>
<li>先頭行が<code>NaN</code>になる理由</li>
<li><code>periods</code>で比較する行を変える方法</li>
<li>日付順に並べてから計算する理由</li>
<li><code>diff()</code>・<code>shift()</code>・<code>pct_change()</code>・<code>rolling()</code>の使い分け</li>
<li>計算結果を「前日差」列としてDataFrameに追加する方法</li>
</ul>

<p>DataFrame自体がまだよく分からない場合は、先に<a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrame入門</a>を読むと理解しやすくなります。CSVから試したい場合は、<a href="https://pythondatalab.com/google-colab-csv/">Google ColabでCSVを読み込む方法</a>も参考にしてください。</p>
<h2 id="先に結論増減量を求めるならdiffを使う"><span id="toc2">先に結論：増減量を求めるならdiff()を使う</span></h2>

<p><code>diff()</code>の標準の計算は、次のとおりです。</p>

<p><strong>現在の行の値 − 1つ前の行の値</strong></p>

<p>たとえば、前日の売上が1,000円、当日の売上が1,300円なら、差分は<code>300</code>です。前日より200円減った場合は<code>-200</code>になります。</p>

<p>目的が似ているメソッドは、求めたい結果で使い分けます。</p>

<table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<colgroup>
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
</colgroup>
<thead>
<tr class="header">
<th style="white-space: nowrap; padding: 0.2em 0.4em;">メソッド</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">求められるもの</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">使う場面</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">結果のイメージ</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>diff()</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行との差（増減量）</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前日より何円増えたか</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>300</code></td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>pct_change()</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行からの変化率</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前日より何％増えたか</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>0.3</code>（30%）</td>
</tr>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>shift()</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行の値そのもの</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前日の値を別の列に置く</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>1000</code></td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>rolling()</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">直近数行の平均・合計など</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">日々の変動をならして傾向を見る</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均</td>
</tr>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>resample()</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">日・週・月などの期間別集計</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">日別データを月別にまとめる</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">月間売上</td>
</tr>
</tbody>
</table>

<p>この記事の中心は、増減「量」を求める<code>diff()</code>です。移動平均は<a href="https://pythondatalab.com/pandas-rolling/">pandas rolling()の使い方</a>、期間別集計は<a href="https://pythondatalab.com/pandas-resample/">pandas resample()の使い方</a>で詳しく解説しています。</p>
<h2 id="日別売上のサンプルデータを用意する"><span id="toc3">日別売上のサンプルデータを用意する</span></h2>

<p>Google Colabで次のセルを実行してください。増加・減少・変化なしをすべて確認できるように、日付の順番を一部入れ替えたデータを用意します。</p>
<pre class="line-numbers"><code class="language-python">import pandas as pd

df = pd.DataFrame({
    &quot;日付&quot;: [&quot;2026-08-01&quot;, &quot;2026-08-03&quot;, &quot;2026-08-02&quot;, &quot;2026-08-04&quot;, &quot;2026-08-05&quot;, &quot;2026-08-06&quot;],
    &quot;売上&quot;: [1000, 1300, 1200, 1300, 1300, 1100]
})

df
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
      </tr>
    </tbody>
  </table>
</div>
<p>このまま<code>diff()</code>を使うと、表示されている行順で計算されます。8月3日の次に8月2日があるため、その結果を「前日差」とは呼べません。先に日付型と並び順を整えます。</p>
<h2 id="diffの前に日付型と並び順を整える"><span id="toc4">diff()の前に日付型と並び順を整える</span></h2>

<p>まず<code>to_datetime()</code>で日付列を日付型に変換し、<code>sort_values()</code>で昇順に並べます。並び替え後のインデックスも<code>reset_index(drop=True)</code>で振り直しておくと、行順を確認しやすくなります。</p>
<pre class="line-numbers"><code class="language-python">df[&quot;日付&quot;] = pd.to_datetime(df[&quot;日付&quot;])
df = df.sort_values(&quot;日付&quot;).reset_index(drop=True)

df
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
      </tr>
    </tbody>
  </table>
</div>
<p>日付の変換方法は<a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方</a>、並び替えの詳細は<a href="https://pythondatalab.com/pandas-sort/">pandas 並び替え（sort）入門</a>で確認できます。</p>

<p>ここでは日付が1日刻みで連続しているため、1つ前の行との差を「前日差」として扱えます。</p>
<h2 id="diffで前の行との差を計算する"><span id="toc5">diff()で前の行との差を計算する</span></h2>

<p>売上列に<code>diff()</code>を使って、結果だけを確認します。</p>
<pre class="line-numbers"><code class="language-python">df[&quot;売上&quot;].diff()
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-200.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>結果は上から順に<code>NaN, 200, 100, 0, 0, -200</code>となります。<code>diff()</code>を実行しただけでは、元のDataFrameに列は追加されていません。</p>

<h3 id="処理前計算対象処理後を表で確認する"><span id="toc6">処理前・計算対象・処理後を表で確認する</span></h3>

<p>それぞれの行で行われている計算は次のとおりです。</p>

<table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr class="header">
<th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">1つ前の売上</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">引き算</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;"><code>diff()</code>の結果</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,000</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">なし</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">計算できない</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>NaN</code></td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,200</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,000</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,200 − 1,000</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">200</td>
</tr>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,200</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300 − 1,200</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300 − 1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
</tr>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300 − 1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,100</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,100 − 1,300</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">-200</td>
</tr>
</tbody>
</table>

<p><code>diff()</code>は逆向きではなく、<strong>現在行から前の行を引く</strong>処理です。したがって、結果の符号は次のように読みます。</p>

<table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr class="header">
<th style="white-space: nowrap; padding: 0.2em 0.4em;">結果</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">意味</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">正の値</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行より増加</td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">負の値</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行より減少</td>
</tr>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">0</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">前の行から変化なし</td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>NaN</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">比較相手がない、または計算に必要な値が欠けている</td>
</tr>
</tbody>
</table>
<h2 id="diffの結果を前日差列として追加する"><span id="toc7">diff()の結果を「前日差」列として追加する</span></h2>

<p>分析しやすいように、差分を新しい列へ代入します。</p>
<pre class="line-numbers"><code class="language-python">df[&quot;前日差&quot;] = df[&quot;売上&quot;].diff()

df
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日差</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-200.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>これで元の売上と前日差を横に並べて確認できます。先頭行の<code>NaN</code>はエラーではありません。1行目には比較する前日の行がないためです。</p>

<p>整数の売上列でも、先頭に<code>NaN</code>が入るため、結果は通常<code>200.0</code>のような小数で表示されます。計算が間違っているわけではありません。列追加の基本は、<a href="https://pythondatalab.com/pandas-add-column/">pandasで新しい列を追加する方法</a>で詳しく解説しています。</p>
<h2 id="periodsで何行前と比較するかを変更する"><span id="toc8">periodsで何行前と比較するかを変更する</span></h2>

<p><code>diff()</code>の<code>periods</code>は、何行ずらした値と比較するかを指定します。標準は<code>periods=1</code>です。</p>

<p>ここで重要なのは、<code>periods=2</code>が必ず「2日前」を意味するわけではなく、<strong>2行前</strong>を意味することです。日付が毎日連続している場合に限り、2行前と2日前が一致します。</p>
<pre class="line-numbers"><code class="language-python">df[&quot;1行前との差&quot;] = df[&quot;売上&quot;].diff(periods=1)
df[&quot;2行前との差&quot;] = df[&quot;売上&quot;].diff(periods=2)

df[[&quot;日付&quot;, &quot;売上&quot;, &quot;1行前との差&quot;, &quot;2行前との差&quot;]]
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">1行前との差</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">2行前との差</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">300.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-200.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-200.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>比較対象は次のように変わります。</p>

<table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr class="header">
<th style="white-space: nowrap; padding: 0.2em 0.4em;">設定</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">計算</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">最初に計算できる行</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>periods=1</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">現在行 − 1行前</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">2行目</td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>periods=2</code></td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">現在行 − 2行前</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">3行目</td>
</tr>
</tbody>
</table>

<p>たとえば8月3日の売上1,300円について、1行前との差は<code>1,300 − 1,200 = 100</code>、2行前との差は<code>1,300 − 1,000 = 300</code>です。</p>

<h3 id="periodsに負の値を指定するとどうなる"><span id="toc9">periodsに負の値を指定するとどうなる？</span></h3>

<p>負の値を指定すると、後ろの行と比較できます。たとえば<code>periods=-1</code>は「現在行 − 次の行」です。引き算の向きを混同しやすいため、初心者のうちは標準の<code>periods=1</code>を中心に使えば十分です。</p>
<pre class="line-numbers"><code class="language-python">df[[&quot;日付&quot;, &quot;売上&quot;]].assign(
    次の行との差=df[&quot;売上&quot;].diff(periods=-1)
)
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">次の行との差</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-200.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
    </tbody>
  </table>
</div>
<h2 id="並び順が違うとdiffの結果も変わる"><span id="toc10">並び順が違うとdiff()の結果も変わる</span></h2>

<p><code>diff()</code>は日付を見て自動的に前日を探すメソッドではありません。<strong>画面上の1つ前の行</strong>と比較します。</p>

<p>最初に用意した並び順のまま計算した場合と、日付順に整えてから計算した場合を比べます。</p>
<pre class="line-numbers"><code class="language-python">df_unsorted = pd.DataFrame({
    &quot;日付&quot;: pd.to_datetime([&quot;2026-08-01&quot;, &quot;2026-08-03&quot;, &quot;2026-08-02&quot;, &quot;2026-08-04&quot;]),
    &quot;売上&quot;: [1000, 1300, 1200, 1300]
})

変更前 = df_unsorted.assign(行間差=df_unsorted[&quot;売上&quot;].diff())

df_sorted = df_unsorted.sort_values(&quot;日付&quot;).reset_index(drop=True)
変更後 = df_sorted.assign(前日差=df_sorted[&quot;売上&quot;].diff())

print(&quot;変更前：日付順ではない状態&quot;)
display(変更前)
print(&quot;変更後：日付順に並べた状態&quot;)
display(変更後)
</code></pre>
<p>変更前：日付順ではない状態</p>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">行間差</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">300.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>変更後：日付順に並べた状態</p>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日差</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>変更前では8月2日の直前に8月3日があるため、8月2日の差は<code>1,200 − 1,300 = -100</code>です。これは前日差ではなく、単なる行間差です。変更後は8月1日、2日、3日、4日の順になるため、前日からの増減として解釈できます。</p>

<p>時系列データでは、<code>diff()</code>の直前に日付列と並び順を確認する習慣をつけましょう。</p>
<h2 id="前日差を正しく読むための2つの注意点"><span id="toc11">前日差を正しく読むための2つの注意点</span></h2>

<h3 id="日付が欠けていると前の行と前日は一致しない"><span id="toc12">日付が欠けていると「前の行」と「前日」は一致しない</span></h3>

<p>次は8月2日のデータがない例です。日付順には並んでいますが、8月3日の1つ前の行は8月1日です。</p>
<pre class="line-numbers"><code class="language-python">df_gap = pd.DataFrame({
    &quot;日付&quot;: pd.to_datetime([&quot;2026-08-01&quot;, &quot;2026-08-03&quot;, &quot;2026-08-04&quot;]),
    &quot;売上&quot;: [1000, 1300, 1200]
})

df_gap[&quot;前の行との差&quot;] = df_gap[&quot;売上&quot;].diff()
df_gap
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前の行との差</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">300.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-100.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>8月3日の結果<code>300</code>は、8月1日との比較です。8月2日の売上が存在しないため、厳密には「前日差」ではありません。</p>

<p>つまり、<code>diff(periods=1)</code>の<code>1</code>は1日ではなく1行です。「前日差」と表現する前に、日付が1日刻みで連続しているか確認してください。</p>
<h3 id="途中に欠損値があると差分もnanになる"><span id="toc13">途中に欠損値があると差分もNaNになる</span></h3>

<p>売上の途中に欠損値があると、その値を使う差分は計算できません。</p>
<pre class="line-numbers"><code class="language-python">df_missing = pd.DataFrame({
    &quot;日付&quot;: pd.date_range(&quot;2026-08-01&quot;, periods=5, freq=&quot;D&quot;),
    &quot;売上&quot;: [1000, 1200, None, 1500, 1600]
})

df_missing[&quot;前日差&quot;] = df_missing[&quot;売上&quot;].diff()
df_missing
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前日差</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1500.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1600.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
    </tbody>
  </table>
</div>
<p>8月3日は売上自体が欠損しているため<code>NaN</code>です。8月4日も、比較する1行前の8月3日が欠損しているため<code>NaN</code>になります。8月5日は8月4日の値があるため、再び計算できます。</p>

<p>欠損値を理由なく0で埋めると、「売上が本当に0だった」と解釈される恐れがあります。欠損が未記録なのか、売上0を意味するのかを確認してから処理してください。埋め方の判断は<a href="https://pythondatalab.com/pandas-fillna/">pandas fillna()の使い方</a>で解説しています。</p>
<h2 id="diffshiftpct_changerollingを同じデータで比較する"><span id="toc14">diff()・shift()・pct_change()・rolling()を同じデータで比較する</span></h2>

<p>似た処理の違いを、同じ売上データで確認します。<code>shift(1)</code>は前の行の売上、<code>pct_change()</code>は変化率、<code>rolling(3).mean()</code>は直近3行の移動平均を返します。</p>
<pre class="line-numbers"><code class="language-python">df_compare = df[[&quot;日付&quot;, &quot;売上&quot;]].copy()
df_compare[&quot;前の行の値_shift&quot;] = df_compare[&quot;売上&quot;].shift(1)
df_compare[&quot;増減量_diff&quot;] = df_compare[&quot;売上&quot;].diff()
df_compare[&quot;増減率_pct_change&quot;] = df_compare[&quot;売上&quot;].pct_change(fill_method=None)
df_compare[&quot;3行移動平均_rolling&quot;] = df_compare[&quot;売上&quot;].rolling(3).mean()

df_compare
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">前の行の値_shift</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減量_diff</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">増減率_pct_change</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3行移動平均_rolling</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1000.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.200000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1200.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.083333</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1166.666667</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.000000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1266.666667</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">0.000000</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300.000000</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1300.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-200.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-0.153846</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1233.333333</td>
      </tr>
    </tbody>
  </table>
</div>
<p>たとえば8月2日は、前の行の値が1,000円、増減量が200円、増減率が0.2（20%）です。3行移動平均は3行分の値が揃う8月3日から計算されます。</p>

<ul>
<li><strong>何円変わったか</strong>を知りたい：<code>diff()</code></li>
<li><strong>何％変わったか</strong>を知りたい：<code>pct_change()</code></li>
<li><strong>前の値そのもの</strong>を使いたい：<code>shift()</code></li>
<li><strong>短期的な変動をならしたい</strong>：<code>rolling()</code></li>
</ul>

<p>目的を先に言葉にすると、メソッドを選びやすくなります。</p>
<h3 id="補足dataframe全体や列方向にもdiffを使える"><span id="toc15">補足：DataFrame全体や列方向にもdiff()を使える</span></h3>

<p>ここまでは、日別売上の前日差を求めるため、売上のSeriesに<code>diff()</code>を使いました。<code>diff()</code>は数値列からなるDataFrame全体にも使用でき、標準では各列について1つ前の行との差を計算します。文字列列などが含まれる場合は、差分を求めたい数値列を選んで実行するのが安全です。</p>

<p>また、<code>axis=1</code>を指定すると、同じ行にある列同士の差を計算できます。たとえば「4月売上」と「5月売上」の差を横方向に求める場合です。</p>
<pre class="line-numbers"><code class="language-python">df_monthly = pd.DataFrame({
    &quot;4月売上&quot;: [1000, 1500],
    &quot;5月売上&quot;: [1200, 1400]
}, index=[&quot;商品A&quot;, &quot;商品B&quot;])

df_monthly.diff(axis=1)
</code></pre>
<div class="wp-table-scroll" style="overflow-x: auto;">
  <table class="wp-block-table" style="width: auto; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">4月売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">5月売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">商品A</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">200</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">商品B</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">-100</td>
      </tr>
    </tbody>
  </table>
</div>
<p><code>5月売上</code>列には「5月売上 − 4月売上」が表示されます。最初の<code>4月売上</code>列は左側に比較する列がないため<code>NaN</code>です。</p>

<table class="wp-block-table" style="width: auto; border-collapse: collapse;">
<thead>
<tr class="header">
<th style="white-space: nowrap; padding: 0.2em 0.4em;">商品</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">4月売上</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">5月売上</th>
<th style="white-space: nowrap; padding: 0.2em 0.4em;">5月 − 4月</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">商品A</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,000</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,200</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">200</td>
</tr>
<tr class="even">
<td style="white-space: nowrap; padding: 0.2em 0.4em;">商品B</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,500</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">1,400</td>
<td style="white-space: nowrap; padding: 0.2em 0.4em;">-100</td>
</tr>
</tbody>
</table>

<p>ただし、時系列データの前日差を求める目的なら、対象の売上列に行方向の<code>diff()</code>を使う基本形を優先してください。列方向の差分は、月別列などが横に並んだデータで必要になったときに使えば十分です。</p>
<h2 id="diffでよくあるミスと対処法"><span id="toc16">diff()でよくあるミスと対処法</span></h2>

<h3 id="日付順に並べず前日差と解釈する"><span id="toc17">1. 日付順に並べず「前日差」と解釈する</span></h3>

<p><code>diff()</code>は現在の行順で計算します。時系列データでは、日付型への変換と並び替えを先に済ませます。</p>

<h3 id="先頭のnanをエラーだと思う"><span id="toc18">2. 先頭のNaNをエラーだと思う</span></h3>

<p>先頭行には比較する前の行がないため、標準では<code>NaN</code>になります。正常な結果なので、理由なく0で埋めないようにします。</p>

<h3 id="periodsを日数だと思う"><span id="toc19">3. periodsを日数だと思う</span></h3>

<p><code>periods=2</code>は2日前ではなく2行前との比較です。</p>

<h3 id="diffを表示しただけで列が追加されたと思う"><span id="toc20">4. diff()を表示しただけで列が追加されたと思う</span></h3>

<p><code>df["売上"].diff()</code>は結果を返しますが、元のDataFrameを変更しません。「前日差」列として残す場合は、新しい列へ代入します。</p>

<h3 id="負の値を計算ミスだと思う"><span id="toc21">5. 負の値を計算ミスだと思う</span></h3>

<p>標準の<code>diff()</code>は現在行から前の行を引きます。負の値は、前の行より減少したことを示します。</p>

<h3 id="前日比率を求めたいのにdiffを使う"><span id="toc22">6. 前日比率を求めたいのにdiff()を使う</span></h3>

<p><code>diff()</code>が返すのは増減量です。「前日より何％増えたか」を求める場合は<code>pct_change()</code>を選びます。</p>
<h2 id="データ分析の流れでdiffを使う位置"><span id="toc23">データ分析の流れでdiff()を使う位置</span></h2>

<p><code>diff()</code>は、読み込んだデータを確認・整形したあとに、変化を表す列を作る処理として使えます。</p>

<ol type="1">
<li>CSVをDataFrameに読み込む</li>
<li><code>head()</code>や<code>info()</code>で列とデータ型を確認する</li>
<li>日付列を<code>to_datetime()</code>で日付型に変換する</li>
<li><code>sort_values()</code>で日付順に並べる</li>
<li><code>diff()</code>で前の行からの増減列を作る</li>
<li>増減が大きい日を確認する</li>
<li>必要に応じて<code>rolling()</code>や<code>resample()</code>で傾向を集計する</li>
<li>折れ線グラフなどで可視化する</li>
</ol>

<p>このように、<code>diff()</code>はデータの確認・前処理から時系列分析や可視化へ進む橋渡しになります。</p>
<h3 id="売上と前日差をグラフで確認する"><span id="toc24">売上と前日差をグラフで確認する</span></h3>

<p>最後に、売上と前日差を上下2つの折れ線グラフで確認します。尺度が異なるため、同じ軸へ無理に重ねず、グラフを分けます。</p>

<p>Google Colabで日本語のタイトルや軸ラベルを文字化けさせないため、最初に次のセルを1回実行して<code>japanize_matplotlib</code>を読み込みます。</p>
<pre class="line-numbers"><code class="language-python">%pip install -q japanize-matplotlib
import japanize_matplotlib

import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 1, figsize=(9, 6), sharex=True)

axes[0].plot(df[&quot;日付&quot;], df[&quot;売上&quot;], marker=&quot;o&quot;)
axes[0].set_ylabel(&quot;売上&quot;)
axes[0].set_title(&quot;日別売上&quot;)
axes[0].grid(alpha=0.3)

axes[1].plot(df[&quot;日付&quot;], df[&quot;前日差&quot;], marker=&quot;o&quot;, color=&quot;tab:orange&quot;)
axes[1].axhline(0, color=&quot;gray&quot;, linewidth=1)
axes[1].set_ylabel(&quot;前日差&quot;)
axes[1].set_xlabel(&quot;日付&quot;)
axes[1].set_title(&quot;前日からの増減&quot;)
axes[1].grid(alpha=0.3)

fig.autofmt_xdate()
plt.tight_layout()
plt.show()
</code></pre>
<figure class="colab-figure">
  <img decoding="async" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA3kAAAJOCAYAAAAK+M50AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAp1FJREFUeJzs3Xd809X+x/FX0kmhLS2klC7KngIyZDtQhsoSEVBUQFBEEe/FgXhV4DrwOnChqICtCnivCChLhqD+WGWLsmWUlpbSspoyOpPfH6HB2gIB0iZt38/H4zw03+9J+vm2H9J8es73HIPVarUiIiIiIiIiZYLR1QGIiIiIiIiI86jIExERERERKUNU5ImIiIiIiJQhKvJERERERETKEBV5IiIiIiIiZYiKPBERERERkTJERZ6IiIiIiEgZ4unqAEREREqT48ePc/z48SLP1a5dGy8vrwLHdu7cSVZWFi1atLjs66ampvLII4/wxRdfEBISck2xpaamEhgYiI+PzzU9X0REygYVeSIiUu4YDAaH+g0ePJjY2NgCx95//33effddAgMDCxw/duwYf/75J3Xq1CE+Pp7w8HC8vLyIiYnh+PHj9texWCycO3eu0Nc6fvw4ixcv5vjx4/j5+RU6X6FCBTw8PC4bb7169Zg+fTr9+vVz6PpERKRsUpEnIiLl0pdffkn79u0vef7ZZ5+95LkBAwYUKv7yC8fc3Fxq1qzJ7t27adCgQaHn7tq1ixtuuOGSr924ceMij69YsYI77rjjks8TERHJpyJPRETKpbCwMOrUqXPJ85UqVSqWr9ukSROsVmuh4/Hx8dSsWZNDhw4RHR1dLF9bRETKBxV5IiIiLnD27NkCxV7+FM5z585x5syZAn2Lq+AUEZGySUWeiIjIVfrhhx9o0qTJdb1GjRo1OHHiRKHjRU3XPH/+PL6+vg697n333Vfk8bS0NKpWrXp1QYqISKmkIk9ERMqlxMRE9uzZc8nzZrOZ4ODgQscff/xxevTowfTp0zl8+DCvvvqq/VxkZKRDXzsrK4sjR45cfdAO+OCDD+jatWuh40FBQcXy9URExP2oyBMRkXLpkUceuWKfwYMHFzoWERFBREQE8+bNIy8vj7Zt2xY4n5ube8XXrVGjBseOHXM8WCAnJwdPzyv/2g4LCytywRcRESk/tBm6iIiUSytWrMBqtV6yDRo06LLPP3nyJEuWLKFt27b2tmbNGoe//vz58+1fKz4+nszMTKxWK2fOnCExMdF+btOmTdd7qSIiUs6oyBMREbkGR44coV+/frz55pu8+eabHDp0qMj9764kNzeX6Ohodu7cCcDChQvp2LGjs8MVEZFyRNM1RURErsHvv//OP//5T2699VbAtsl5UZuYF2XBggX27RuOHz8OQEhISJF9mzVrRmJiokNTNUVEREBFnoiIyFXbsGEDZrPZvpm61WolPT0df39/PD09i9wH769uuukm+/9v3ryZqlWrEhERUWRfLy8vUlJSOHr0KK1bt3beRYiISJmlIk9ERMql5ORk9u/ff8nzZ86coXLlykWemzhxIgMGDMDf3x+A1NRUcnJyqFat2lXFkJWVxZtvvsnAgQMv22/hwoVs3LiRH3/8kZycHA4cOFBkP4vFQnJy8iVXDQ0NDb3kNYmISNmhIk9ERMqlolbOdKTP22+/zbp169i1axc///wzVapUYcGCBVSqVMle5G3atIndu3dTuXJlNmzYUGi1S6vVyi+//MLYsWM5ceIE33//vf2cp6cnp06dYu3atQQFBZGens78+fO57bbbAEhKSqJhw4aXjPnpp5++5LmPPvqIUaNGXfG6RUSkdFORJyIi5c6//vUvhg4dSu3atS/Z57vvvsNoLLg+2c6dOxk/fjxz5swhLCyMBx98kPXr11OhQgX+/e9/YzAYANsefM8//zwZGRn4+fnx/PPP21/j8OHDtGvXjuPHj/PQQw/x5ptvFtikvF27doSFhdG5c2dycnKoUKECdevWZcSIEQBER0dfcTqoiIiUbwarflOIiIg4LCUlhdDQ0Ot6jZUrV9K0aVNMJpOTohIREblIRZ6IiIiIiEgZon3yREREREREyhAVeSIiIiIiImWIijwREREREZEyREWeiIiIiIhIGaIiT0REREREpAzRPnkOsFgsJCcn4+/vb98DSUREREREpCRZrVYyMjIICwsrtJfrX6nIc0BycjKRkZGuDkNERERERITExEQiIiIueV5FngP8/f0B2zczICDAxdHYWCwW0tLSMJlMl63iRS5HeSTOolwSZ1AeibMol8QZ3DGPzGYzkZGR9vrkUlTkOSB/imZAQIBbFXmZmZkEBAS4TdJJ6aM8EmdRLokzKI/EWZRL4gzunEdXuoXMvaIVERERERGR66IiT0RE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O9fC899t5/vfkgF4tms9nrytjvbAExEREREppVTklWPmzBwe/3oL6w6cwNNo4M17m9KvZYSrwxIRERERkeugIq+cOpp+nqExm9iTkkFFbw+mPtiSm+uZXB2WiIiIiIhcJxV55dDelAyGxGzkaHomJn8fYoe2pnFYoKvDEhERERERJ1CRV86sP3CCx77eTEZmLnVCKhE7tDURQX6uDktERERERJxERV45smB7Ms9+u53sPAs3RQfz+cMtqezn7eqwRERERETEiVTklQNWq5Vpqw/yxpI9ANx1QyiT+zfH18vDxZGJiIiIiIizqcgr4/IsVl5dtIvYdfEAPNKhJi/d3RCjUVskiIiIiIiURSryyrDMnDz+8d/fWLozBYCX7m7I8E61XByViIiIiIgUJxV5ZdSps9k8+tVmNh8+hbeHkckDmtGjaZirwxIRERERkWKmIq8MSjx5jsExGzmYdpYAX0+mPdyKNrWquDosEREREREpASryypg/jqQzNHYTx89kEV65ArFDW1O3mr+rwxIRERERkRKiIq8M+WVvKk/M2sq57DwaVg8gdmhrqgX4ujosEREREREpQSryyohvNyUybv4f5FmsdKxTlakPtsDf18vVYYmIiIiISAkzuvKLWywW4uLieOaZZwgODiY2NrbA+aysLF544QXq1KlDWFgYvXv3Jjk5uUCfpKQkBgwYQHR0NOHh4YwZM4bs7OwCfeLi4ujUqRNRUVHUrVuXadOmFfelFas8i5W4gydYvuck6w8cZ/KKvTw/93fyLFb6tgjniyGtVeCJiIiIiJRTLi3yYmJiGD16NBUqVMDDo/DG3E8++SQbNmxgy5YtJCQkULduXe68807y8vIAyM7OpkuXLkRFRXHgwAF27tzJ1q1bGTNmjP019u7dS7du3fjnP/9JQkICCxYs4JVXXuG7774rset0pqU7jtLxP6t4YPpGXll6iEEzNvHhyv0APHlbbd69rxneni79sYqIiIiIiAu5tBoYNmwYGzdu5LXXXqNixYoFziUkJBATE8O7775LYGAgnp6evPHGGyQlJbFkyRIA5syZQ2pqKm+88QYeHh5UrlyZyZMnM336dI4fPw7AO++8wy233ELfvn0BaNiwIc899xyTJk0q2Yt1gqU7jjJy5laOpmcWef6G8EAMBm1yLiIiIiJSnrntkM+vv/5KtWrVaNGihf2Y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41tuuaXAqJyHhwd16tS55NdytDBKTEwkKSmJDh06FDj+7rvv8vHHH7Nt2zbCw8Mv+fwpU6YQERFBnz59GDRoED169GD16tX4+Pg49PVnzZrF8OHD6dGjBzExMcTGxpKVlcWUKVNYtGgREyZM4Ntvv2XBggUEBQXZn/f777/b75Xbu3cvvr6+nDx5knfeeYcHH3wQgCZNmjBlyhRuvfVWAO64444Co36enp7ExsYyYcIE8vLyMBgMRcbo5eVV4Hvfvn17atas6dD1iYhI8TBYrVarq4MQERHJl5WVxd9/NRmNRry9vQv1jY+Px9fXl9DQUPux2NhYXnrppQL3nf1dbm4uXl5e/Pzzz/YiB8BqtTJr1iz27t3L/v372blzJ3/88QdgG7W69957+eSTTzAajbRt2xY/Pz9++eUXPD2L/ptpixYt6NOnD6+88srVfAsAmDNnDg899BAzZ86kX79+AHTu3JlWrVrx1ltvAXDy5EluvvlmatSoweLFi+3PrV+/PllZWRw+fJiwsDA6depESkoKe/bssU91TUxMpGrVqlSoUAGA5ORkPvnkE4YMGcKZM2dYvnw5ffv2BeDIkSNERkYW+rnExsby1VdfsWrVqqu+PhERKT6arikiIm4lMDCQyMhIoqOjiY6OJjQ0lM6dOwOQnp5O27ZtOXPmDADPPvssU6ZMcdrXNhgMfPTRR2zbto26detiMBi47777OHjwIAsXLuSHH35g6tSpeHt787///Y/t27dfcsERi8XC7t27adGixVXHkZaWxvDhw/noo4/sBR7Azp07adiwof1xcHAw06dPZ8mSJaxbt85+fO/evcTHxwOwbNky/vvf/wLwzjvvsH//fvbv30/dunWZNWuW/XH79u3tz//zzz954oknePjhhwtMLf30009p3ry5vW3evNk+VXbJkiV8+eWXV32tIiLifCryRETE7axevdp+v92nn35qP56Tk8OGDRuuON0yNzeXPXv2XLLt3bv3ks/dsGEDixYt4uWXXyYxMZF+/fpRs2ZNbr75Zvr27cvKlSsBqFu3LuPGjeM///kPx44dK/Q6+/fvJzMzk6ZNmxY4bjabSUtLKzQq9ldTp04lMjKS4cOH248lJCSQmppKy5YtC/Rt27Yt4eHhLFu27LLfk6tx4403snnzZtauXcv06dPtx4cPH05cXJy9DRgwgNTUVABmzpxJQkKC02IQEZFrp3vyRETE7bz11lsEBwcDXLYgu5Rjx44VGPG6FsuXLyczM5O7777bfiw0NJTffvvN/nj06NG8//77vPLKK3z22WcFnv/nn3/i7e1NREQE8fHxvPvuu8yfP5+kpCTANmL5yCOP8Prrr9unTOZbsWIFvXv3LnAf3NKlS6latSpNmjQpFGtYWNgVt2gIDg7m2Wef5dlnn7UfGzhwYIE+f40jIiKCNWvWEBISwtGjRzEYDKxevZr777/f3ueTTz4hNTWVs2fPsmTJEsaNG3fZGEREpGRoJE9ERNyOyWQiNDSU0NBQAgMDr/r54eHhWK3WS7acnJwrvsbs2bPp1asXFStWtB/Lzs4ucG9gpUqVGDt2rH00668OHz5MZGQkb731Fo0aNeLcuXPMnj2bU6dOcfr0aWJiYvjyyy8ZOXJkoecmJycTFRVV4NjcuXO56667MBoL/+o+efIk/v7+l72eefPmFViRtKg2YMCAAs/J/35lZmbi4eFBVlYWbdu2JSUlhTp16lCtWjU8PDz44IMPMJlM3HDDDZeNQURESoZG8kRExO0MHTrUvoLmf//7X6fed+eIEydOMHfuXH744YdCx6tWrVrg2OjRoxkzZkyh10hISODAgQPMnDmTdevW0bx58wLn77nnHvbt28err75KbGxsgXOVKlUiLS3N/vjAgQOsWLGiyAVODh48yIEDBy5775/VaiUrK4sKFSoQEBBQaKXM7Oxs2rdvz08//VTg+AcffIDFYuHhhx/G19e30Ot6eHhQv359Xn/9df79739f8uuLiEjJ0kieiIi4nU6dOtlH8h5//PES//rTp08nIiKCLl26FDh+4MABateuXeCYl5dXkdsLtGjRgoceeoi1a9cWKvDynTlzpsiRyo4dO7JixQr74/Hjx9O8efMCK4GCrXj75z//SZUqVejdu3eRX2PSpEnUrl3bPnp54MABTp8+XaB98sknRT53/vz5REZGkpycfMkR1bZt22IwGBg2bFiR50VEpORpJE9ERNzOwoUL7fvczZ8/v0RXbTx//jyTJ0/mxRdfLDA1MjMzk82bNzNq1CiHXqd///7079//kud//vlnPvjgA/7xj38UOvfUU0/RrFkz3nvvPQwGA9988419wZd8SUlJjBo1ikWLFjFnzhz7tNIzZ87wwgsvsGjRImrVqkXDhg15++238fLyAqBp06aFpnyeO3eu0Ejg9u3b2b9/P/feey8LFiygevXqgO3ewPwtK06fPs3y5cuJioqicuXKjB8/nttvv52bb77Zoe+RiIgUDxV5IiLidipXrmyfFvnXe82qVq162VUp8+Xl5bF///7Lnr+Ud955B6vVyqOPPsqGDRv46quvGDlyJHPnzsVoNHLnnXdexZXY5ObmkpGRweHDh9m0aRNz585lxYoVjBgxgvHjxxfq36BBA6ZPn86wYcOwWq18+OGH3HrrraSmpvLdd9/x008/sWTJEoKCgvj+++/p2bOn/bmVKlWiVq1azJ07t8BKnJmZmYBto/S/TzmNjY1l5syZBY599NFHtGvXjvDwcNauXUuzZs1o3749O3fupHbt2mRnZ3PHHXfQq1cvFi9ezNy5c1mwYAFhYWEq8kREXExFnoiIuKXz58+zb98+kpKSCkyHTElJITExkdDQUFJSUmjUqFGh56akpFC3bt1r+rr79+/n5Zdfxs/Pj+rVq/Pnn3/SokULjEYjU6dOxc/P76pf84477uDXX3/FYDBQu3ZtunTpwubNm7nxxhsv+ZyHHnqInj17kpeXR5UqVQDbhuwzZsygSpUqfPDBBwwaNMi+uflfFXWPYL769esXml6alZVFmzZt7I+PHTvGzJkz+eKLLzh//jzLli1jypQpBAQEEBAQwLFjx+jbty+VKlXivffeo0WLFjz44INkZWXRvXv3q/32iIiIk6nIExERt5STk0OHDh3IzMzkySeftB/ft28fXbt2JSsrC29v70LL9jdr1oy33nqL55577pKvbbFYeOWVV6hRo0ahc3+dGhoVFcXy5cvJzc3FYrEUWFnzasyePZv09HSioqIKrNZ5JZUrVy7w2NfXly1btlxTDPn27t17xZG8o0ePUrNmTe677z62bNlChQoV6NOnj/38oEGDCAoKYs6cOXh4eDBkyBBWrlyJxWIp8nsqIiIly2B1ZN6LiIhICdm3bx/R0dFXLKgyMzPx9PTE01N/rywO586ds49aHjt2jGrVqtnPHTt2jCpVquh7LyLiplTkiYiIiIiIlCHaQkFERERERKQMUZEnIiIiIiJShqjIExERERERKUNU5ImIiIiIiJQhWhbLARaLheTkZPz9/QvtLSQiIiIiIlISrFYrGRkZhIWFYTReerxORZ4DkpOTiYyMdHUYIiIiIiIi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+OILDh065DMfquTyXCpL1apV48MPPyQjI4O+ffvStm1bT4NnjGHcuHHUrl2b+vXr2zkMsdmlclS9enVmzJhByZIlGT16NCVKlOBvf/sbBw4cANxLycPCwnzm1hx6Vy0ALpeLkiVL0rBhQz744AMAAgICAKhRowa33norp06dYuvWrQCeP3ZlypShZ8+ePPLII7qWSvKdoy1btgCQnp5OQkICU6ZMoXHjxpw5c4bvv/+esWPH2jYG8Q75zVLuNcHvv/8+HTp04PHHH6dmzZo4nU7eeOMNfTAv4vKTo99++429e/dyzz33cNddd5GYmMikSZMA99+648eP68sC+cufk/bu3UuzZs147LHHqFWrFtnZ2cyYMYNixbRArSi7VI7atGnD8ePH2bp1K40aNeKTTz7hl19+YeTIkdStW5fTp08zf/58z+qVwk5/oQtA7u5hcXFx7Nq1i23btuFwODyN2x133MGhQ4c83zYYYzzLNmNiYhg7dixBQUG21S/eIb85+uMXAkFBQSxZsoR58+Yxe/ZswsLC7CpfvEh+s5S7w1j9+vV57rnnqF69OgsXLmTu3LmUKlXKziGIF8hPjuLj40lKSiI2Npb58+cTHh6O0+n0/I3L3QVYira/+jkpMjKSiRMncv3117Nw4ULmz59PaGionUMQL5CfHP3888+kp6cD7r9t8+bN47333mPlypUsWLCA0qVL2zgCa6nJs0BCQgIrV65kz549njegXE6nE3Bv29qyZUvq1KnDxIkTAfe3C+np6ZQtW5bQ0FB2797tOTd3a3JtUV50WJWjnTt3AlCpUiUWLlzI+vXrad68ecEORmxlVZZydxiLjo6mR48eDBs2jCZNmhTsYMQ2VuVoz549nue5XC78/f31t62Isfo9KTQ0lI4dOzJ48GAaN25coGMR+1j9eRvcjWH58uWpXr16gY2joKjJu0KjRo0iJiaGWbNmER0dzbPPPsuxY8c8x3OvsXvppZeoX78+999/P9999x0TJkwAICQkhGPHjhEWFkbXrl3tGobYzMocde/e3fPY9ddfb8t4xD5XI0tS9Fytv21a4lv0WJmlbt262TQKsZs+b18Gm3b1LPScTqd55JFHTPfu3c2xY8eMMcZMmzbNNG3a1Gzbts1z3uzZs811111nbrvtNpOZmWmysrLMokWLTPny5U1sbKwZN26cqVq1qhky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KEe+x+ubPBEREREREck/r91dU0RERERERP46NXkiIiIiIiI+RE2eiIiIiIiID1GTJyIiIiIi4kPU5ImIiNjA6XTaXYKIiPgoNXkiIiJX4NVXX6V06dIX/bds2bJznte1a1cWLFhwzuOHDx+mQoUKBVG6iIj4KDV5IiIiVyAjI4P77ruPU6dOnfdf48aNyc7OPuc5a9eupWXLljZVLSIivkxNnoiISAFbtGgRN910E5GRkXaXIiIiPqiY3QWIiIgUNdOnT6dVq1b07NmT1atX5zlmjOH06dOULl2aqlWrsnPnTpuqFBGRwkpNnoiISAFas2YNX3/9Na1ateLTTz895/ipU6eoUKECp06dKvjiRETEJ2i5poiIyBWaNm3aBTdd2bBhg+e87OxsRowYQYsWLTyPrV27ljfffNOOskVExEepyRMREblCQ4YMueDGK3/cXGXdunU0bdqUDh06eB6rXbs2EyZMYP369XaULiIiPkhNnoiISAFp164dU6ZMyfNYZGQkr732Gg8++CBZWVk2VSYiIr5E1+SJiIgUoOLFi5/z2L333suhQ4fIycmxoSIREfE1avJERERs5nA4GDt2LIBm80RE5IppuaaIiMgVyu/GKxeTkJDAiRMnOHbsGA6H4ypXLCIivkwzeSIiIlfg4Ycf5oEHHqBSpUrnPf7f//6XiIiIS77OjBkz+Mc//kFaWlqe3TdFRET+KocxxthdhIiIiIiIiFhDyzVFRERERER8iJo8ERERERERH6ImT0RERERExIeoyRMREREREfEhavJERERERER8iJo8ERERERERH6ImT0RERERExIeoyRMREREREfEhavJERERERER8iJo8ERERERERH6ImT0RERERExIf8P1XveqlOmzQSAAAAAElFTkSuQmCC" alt="売上と前日差を示す折れ線グラフ">
  <figcaption>売上水準と前日からの増減を上下に分けて示したグラフ</figcaption>
</figure>
<p>上段では売上水準、下段では前日からの増減を確認できます。0より上なら増加、下なら減少です。グラフの色・線種・凡例などを整えたい場合は、<a href="https://pythondatalab.com/matplotlib-line-legend-color/">Matplotlib折れ線グラフの描き方</a>を参考にしてください。</p>
<h2 id="まとめ"><span id="toc25">まとめ</span></h2>

<p><code>diff()</code>を使うと、DataFrameやSeriesで前の行との差分を簡単に計算できます。</p>

<ul>
<li>標準の<code>diff()</code>は「現在行 − 1つ前の行」を計算する</li>
<li>正の値は増加、負の値は減少、0は変化なしを表す</li>
<li>先頭行の<code>NaN</code>は比較相手がないためで、エラーではない</li>
<li><code>periods</code>で比較する行を変更でき、<code>periods=2</code>は原則として2行前を意味する</li>
<li>時系列データは、日付型と並び順を確認してから計算する</li>
<li>日付が欠けている場合、前の行との差を前日差とは限らない</li>
<li>増減率には<code>pct_change()</code>、前の値には<code>shift()</code>、移動平均には<code>rolling()</code>を使う</li>
</ul>

<p>まずは、<strong>日付変換→日付順に並び替え→<code>diff()</code>で差分列を追加</strong>という順番を覚えましょう。これで日別売上やアクセス数について、前回からの増減を正しく確認できるようになります。</p>
<h2 id="関連記事"><span id="toc26">関連記事</span></h2>

<ul>
<li><a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrame入門｜作り方・基本操作をわかりやすく解説</a></li>
<li><a href="https://pythondatalab.com/google-colab-csv/">Google ColabでCSVを読み込む方法｜アップロード・Drive・read_csv</a></li>
<li><a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方｜文字列の日付変換とformat・NaT対処</a></li>
<li><a href="https://pythondatalab.com/pandas-sort/">pandas 並び替え（sort）入門｜sort_values・sort_indexの違い</a></li>
<li><a href="https://pythondatalab.com/pandas-rolling/">pandas rolling()の使い方｜移動平均・window・NaNを解説</a></li>
<li><a href="https://pythondatalab.com/pandas-resample/">pandas resample()の使い方｜月別・週別に集計する方法</a></li>
<li><a href="https://pythondatalab.com/matplotlib-line-legend-color/">Matplotlib折れ線グラフの描き方</a></li>
<li><a href="https://pythondatalab.com/pandas-roadmap/">Pandasロードマップ</a></li>
</ul>

<p>仕様を確認したい場合は、<a rel="noopener" href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.diff.html" target="_blank">pandas公式ドキュメント：DataFrame.diff</a>も参考になります。</p>
<!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc27"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p></div>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1787404742488" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc28">pandasで前の行との差を求めるにはどうすればよいですか？</span></h3>
<div class="rank-math-answer ">

<p>対象のSeriesに<code>diff()</code>を使います。売上列なら<code>df["売上"].diff()</code>で、現在行から1つ前の行を引いた差分を求められます。</p>

</div>
</div>
<div id="faq-question-1787404769003" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc29">diff()の先頭行がNaNになるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>先頭行には比較する1つ前の行がないためです。計算エラーではなく、正常な結果です。</p>

</div>
</div>
<div id="faq-question-1787404779156" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc30">diff()で前日差や前日比率を計算できますか？</span></h3>
<div class="rank-math-answer ">

<p>日付が1日刻みで連続し、日付順に並んでいれば、<code>diff()</code>で前日からの増減量（前日差）を計算できます。割合としての前日比率には<code>pct_change()</code>を使います。</p>

</div>
</div>
<div id="faq-question-1787404792094" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc31">diff()のperiods=2は何を意味しますか？</span></h3>
<div class="rank-math-answer ">

<p>現在行と2行前の値との差を意味します。日付が連続している場合は2日前と一致しますが、日付に欠けがあれば2日前とは限りません。</p>

</div>
</div>
<div id="faq-question-1787404806166" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc32">diff()とshift()の違いは何ですか？</span></h3>
<div class="rank-math-answer ">

<p><code>diff()</code>は前の行との引き算を行い、増減量を返します。<code>shift()</code>は値を指定行数だけずらし、前の行の値そのものを返します。</p>

</div>
</div>
<div id="faq-question-1787404814127" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc33">日付が連続していなくても前日差になりますか？</span></h3>
<div class="rank-math-answer ">

<p>なりません。<code>diff()</code>が比較するのは基本的に1つ前の行です。前日の行が存在しなければ、結果は前回観測値との差になります。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-diff/">pandas diff()の使い方｜前の行との差分・前日からの増減を計算する方法</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-diff/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>pandas rolling()の使い方｜移動平均・window・NaNを初心者向けに解説</title>
		<link>https://pythondatalab.com/pandas-rolling/</link>
					<comments>https://pythondatalab.com/pandas-rolling/#respond</comments>
		
		<dc:creator><![CDATA[coin_collector]]></dc:creator>
		<pubDate>Wed, 19 Aug 2026 13:21:30 +0000</pubDate>
				<category><![CDATA[集計・変形]]></category>
		<guid isPermaLink="false">https://pythondatalab.com/?p=2121</guid>

					<description><![CDATA[<p>日別売上やアクセス数を折れ線グラフにしても、値が大きく上下していると「増えているのか、単にばらついているだけなのか」が分かりにくいことがあります。 このようなときに使えるのが、pandasのrolling()です。直近の [&#8230;]</p>
<p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-rolling/">pandas rolling()の使い方｜移動平均・window・NaNを初心者向けに解説</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></description>
										<content:encoded><![CDATA[
<div class="colab-article">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.css">
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-clike.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<style>
  .colab-article pre[class*="language-"] { margin: 0 !important; padding: 1em; }
  .colab-article .colab-table-wrap { overflow-x: auto; margin: 1em 0; }
  .colab-article table.wp-block-table { width: auto; border-collapse: collapse; }
  .colab-article table.wp-block-table th,
  .colab-article table.wp-block-table td { border: 1px solid #dcdcdc; }
  .colab-article .colab-figure img { max-width: 100%; height: auto; }
  .colab-article .colab-output { overflow-x: auto; white-space: pre-wrap; }
</style>


<p>日別売上やアクセス数を折れ線グラフにしても、値が大きく上下していると「増えているのか、単にばらついているだけなのか」が分かりにくいことがあります。</p>
<p>このようなときに使えるのが、pandasの<code>rolling()</code>です。<strong>直近の複数行を少しずつずらしながら平均を計算し、短期的な変動をならして傾向を見やすくできます。</strong></p>
<p>先に結論を示すと、<code>rolling(window=3).mean()</code>は、原則として<strong>現在行を含む直近3行の平均</strong>を求めます。データが1日1行で日付も連続していれば、「3日移動平均」として読めます。ただし、<code>window=3</code>自体が自動的に3日間を意味するわけではありません。</p>
<p>また、結果の先頭に出る<code>NaN</code>はエラーではありません。3行分のデータがまだそろっていないためです。</p>
<p><strong>最初に覚える手順は、「日付順に並べる → rolling()で計算する → 元の値と比べる」の3つだけです。</strong></p>
<p>この記事では、Google Colabで実行できる日別売上データを使い、3日・7日移動平均、<code>min_periods</code>、<code>resample()</code>との違い、折れ線グラフでの確認までを順番に解説します。</p>

<h2><span id="toc1">この記事でわかること</span></h2>
<ul>
  <li><code>rolling()</code>を使う場面と基本的な書き方</li>
  <li><code>rolling(window=3).mean()</code>のwindowが表す範囲</li>
  <li>3日移動平均と7日移動平均の計算方法</li>
  <li>先頭に<code>NaN</code>が出る理由と<code>min_periods</code>の役割</li>
  <li><code>rolling()</code>・<code>resample()</code>・通常の<code>mean()</code>の違い</li>
  <li><code>center=True</code>で結果を置く位置を変える方法</li>
  <li>行数指定と<code>rolling("3D")</code>による期間指定の違い</li>
  <li>元の値と移動平均を折れ線グラフで比較する方法</li>
</ul>
<p>この記事のゴールは、目的に合ったwindowを選び、移動平均列を作って、元の値と比較しながら傾向を説明できるようになることです。</p>

<h2><span id="toc2">rolling()は直近の複数行をずらしながら計算する</span></h2>
<p><code>rolling()</code>の「rolling window」は、日本語では「移動窓」と考えると分かりやすいでしょう。</p>
<p>たとえば<code>window=3</code>なら、対象範囲を次のように1行ずつ移動させます。</p>
<p>1. 1〜3行目を使って計算する 2. 2〜4行目を使って計算する 3. 3〜5行目を使って計算する</p>
<p>平均を求める場合の基本形は次のとおりです。</p>
<p><code>df["売上"].rolling(window=3).mean()</code></p>
<p>列を1つ選ぶとSeriesになるため、これは<strong>Seriesにrolling()を適用して平均を求める書き方</strong>です。複数の数値列を選んだDataFrameにもrolling()を使えますが、この記事では1列に絞って仕組みを確認します。</p>

<h2><span id="toc3">rolling()・resample()・通常のmean()の違い</span></h2>
<p>似て見える処理でも目的が異なります。最初に次の基準で選びましょう。</p>
<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">方法</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">目的</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">計算対象</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">行数の変化</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">使用場面</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">代表的な書き方</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>rolling()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近の値をならす・合計する</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">現在行を含む直近n行</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">原則として元と同じ</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均、直近7件の平均</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>s.rolling(3).mean()</code></td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>resample()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">時間単位を変えて再集計する</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">日・週・月などの期間</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">通常は変わる</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">日別データを月別合計にする</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>df.resample("MS").sum()</code></td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">通常の<code>mean()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">列全体の平均を1つ求める</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">列全体</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1つの値になる</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">全期間の平均売上を知る</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;"><code>s.mean()</code></td>
      </tr>
    </tbody>
  </table>
</div>
<p><strong>迷ったときは、出力後も1日ごとの行を残したいかで判断します。</strong> 1日ごとの行を残して傾向をならすなら<code>rolling()</code>、月別・週別などに行をまとめるなら<code>resample()</code>です。列全体を代表する平均値が1つだけ必要なら、通常の<code>mean()</code>を使います。</p>
<p>月別・週別集計は、<a href="https://pythondatalab.com/pandas-resample/">pandas resample()の使い方</a>で詳しく解説しています。</p>

<h2><span id="toc4">日別売上のサンプルデータを用意する</span></h2>
<p>Google Colabで次のコードを実行してください。2026年8月1日から14日まで、1日1行で日付が連続するデータです。</p>
<p>売上は日ごとに上下しますが、全体として少しずつ増える値にしています。このデータなら、移動平均によって短期的な上下がならされる様子を確認できます。</p>

<pre class="line-numbers"><code class="language-python">import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({
    "日付": [
        "2026-08-01", "2026-08-02", "2026-08-03", "2026-08-04",
        "2026-08-05", "2026-08-06", "2026-08-07", "2026-08-08",
        "2026-08-09", "2026-08-10", "2026-08-11", "2026-08-12",
        "2026-08-13", "2026-08-14"
    ],
    "売上": [100, 160, 120, 190, 150, 220, 180, 250, 210, 280, 230, 310, 270, 340]
})

df</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">220</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">6</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-07</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">180</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">7</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-08</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">250</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">8</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-09</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">210</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">9</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-10</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">280</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">10</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-11</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">230</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">11</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-12</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">310</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">12</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-13</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">270</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">13</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-14</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">340</td>
      </tr>
    </tbody>
  </table>
</div>

<p>自分のCSVをGoogle Colabへ読み込む手順は、<a href="https://pythondatalab.com/google-colab-csv/">Google ColabでCSVを読み込む方法</a>を参照してください。DataFrame自体の基本操作を確認したい場合は、<a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrame入門</a>が役立ちます。</p>

<h2><span id="toc5">rolling()の前に日付型と並び順を確認する</span></h2>
<p>移動平均は「直前の行」を使うため、行の順番が重要です。日付が文字列のままならdatetime型に変換し、古い日付から新しい日付の順へ並べます。</p>
<p>今回は日付が連続する1日1行のデータなので、<code>window=3</code>を3日移動平均として説明できます。欠損日があるデータでは、同じコードは「直近3日」ではなく<strong>直近3行</strong>の平均です。</p>

<pre class="line-numbers"><code class="language-python">df["日付"] = pd.to_datetime(df["日付"])
df = df.sort_values("日付").reset_index(drop=True)

df.dtypes</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;"></th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">datetime64[ns]</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">売上</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">int64</td>
      </tr>
    </tbody>
  </table>
</div>

<p><code>日付</code>が<code>datetime64[ns]</code>になっていれば変換できています。</p>
<ul>
  <li>日付変換の詳しい方法：<a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方</a></li>
  <li>並び替えの詳しい方法：<a href="https://pythondatalab.com/pandas-sort/">pandas 並び替え（sort）入門</a></li>
  <li>日付をインデックスにする方法：<a href="https://pythondatalab.com/pandas-set-index/">pandas set_index()の使い方</a></li>
</ul>

<h2><span id="toc6">rolling(window=3).mean()で3日移動平均を計算する</span></h2>
<p>売上列に<code>rolling(window=3).mean()</code>を適用し、結果を「3日移動平均」という新しい列へ追加します。</p>

<pre class="line-numbers"><code class="language-python">df["3日移動平均"] = df["売上"].rolling(window=3).mean()

df[["日付", "売上", "3日移動平均"]]</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">220</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">186.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">6</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-07</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">180</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">183.33</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">7</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-08</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">250</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">216.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">8</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-09</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">210</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">213.33</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">9</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-10</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">280</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">246.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">10</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-11</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">230</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">240.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">11</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-12</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">310</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">273.33</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">12</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-13</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">270</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">270.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">13</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-14</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">340</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">306.67</td>
      </tr>
    </tbody>
  </table>
</div>

<h3><span id="toc7">window=3が対象にする値を処理前後表で確認する</span></h3>
<p>最初の5行は次のように計算されます。</p>
<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">元の売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">平均対象となる値</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">3行未満</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">3行未満</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100・160・120</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160・120・190</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120・190・150</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
      </tr>
    </tbody>
  </table>
</div>
<p>8月3日の値は、<code>(100 + 160 + 120) ÷ 3 = 126.67</code>です。次の行では対象が1行ずれ、8月2日〜4日の売上を平均します。</p>
<p>この表で重要なのは、<strong>各行の結果が、その行と直前2行から作られていること</strong>です。移動平均は元の行数を保ちながら各行に対応する平均を返し、列全体の平均を1つだけ返す<code>df["売上"].mean()</code>とは異なります。</p>

<h2><span id="toc8">先頭2行がNaNになる理由</span></h2>
<p>初期設定では、windowに指定した数の有効な値がそろうまで結果を計算しません。<code>window=3</code>の場合は次の状態になります。</p>
<ul>
  <li>1行目：利用できる値が1個だけなのでNaN</li>
  <li>2行目：利用できる値が2個だけなのでNaN</li>
  <li>3行目：3個そろうので移動平均を計算</li>
</ul>
<p>したがって、先頭のNaNはエラーではなく、<strong>同じ条件の3行平均をまだ計算できない</strong>ことを示す正常な結果です。単純に<code>fillna(0)</code>で0へ置き換えると、「平均売上が0だった」と誤解されるので避けましょう。</p>

<h3><span id="toc9">min_periods=1で途中から計算する場合</span></h3>
<p><code>min_periods</code>は、結果を計算するために最低限必要な有効値の数です。<code>min_periods=1</code>を指定すると、最初の行から結果が出ます。</p>

<pre class="line-numbers"><code class="language-python">df["3日移動平均_min1"] = (
    df["売上"]
    .rolling(window=3, min_periods=1)
    .mean()
)

df[["日付", "売上", "3日移動平均", "3日移動平均_min1"]].head(5)</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均_min1</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">130.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
      </tr>
    </tbody>
  </table>
</div>

<p>初期設定と<code>min_periods=1</code>の違いを整理します。</p>
<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">利用できる値の数</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">初期設定の結果</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">min_periods=1</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">比較時の注意点</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.00</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">1個だけの平均</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">130.00</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2個の平均</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">3個の平均</td>
      </tr>
    </tbody>
  </table>
</div>
<p><code>min_periods=1</code>はNaNを減らせますが、先頭の値は3個ではなく1個または2個の平均です。すべての行を同じ条件で比較したい場合は、初期設定のNaNを残すほうが分かりやすいことがあります。</p>

<h2><span id="toc10">center=Trueは結果を中央の行に置く</span></h2>
<p>初期設定の<code>center=False</code>では、計算結果をwindowの末尾、つまり現在行に置きます。<code>center=True</code>を指定すると、結果をwindowの中央に置きます。</p>
<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">指定</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3行の計算結果を置く位置</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">向いている場面</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>center=False</code>（初期設定）</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">3行目（末尾）</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">現在までの値から傾向を確認する</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>center=True</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2行目（中央）</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">前後の値を使って中央時点をならす</td>
      </tr>
    </tbody>
  </table>
</div>
<p>同じ3つの値を平均しても、結果が表示される行が変わります。</p>

<pre class="line-numbers"><code class="language-python">center比較 = pd.DataFrame({
    "日付": df["日付"],
    "売上": df["売上"],
    "center=False": df["売上"].rolling(window=3).mean(),
    "center=True": df["売上"].rolling(window=3, center=True).mean()
})

center比較.head(6)</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">center=False</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">center=True</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">186.67</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">220</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">186.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">183.33</td>
      </tr>
    </tbody>
  </table>
</div>

<p>たとえば100・160・120の平均126.67は、初期設定では3行目の8月3日、<code>center=True</code>では中央に当たる2行目の8月2日に表示されます。</p>
<p>この記事の移動平均は「現在までの直近値から傾向を見る」ことが目的なので、以降は初期設定の<code>center=False</code>を使います。</p>

<h2><span id="toc11">3日移動平均と7日移動平均を使い分ける</span></h2>
<p>次に、同じ売上データへ7行の移動平均も追加します。サンプルは1日1行で日付が連続しているため、ここでは7日移動平均として扱えます。</p>

<pre class="line-numbers"><code class="language-python">df["7日移動平均"] = df["売上"].rolling(window=7).mean()

df[["日付", "売上", "3日移動平均", "7日移動平均"]]</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">7日移動平均</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">220</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">186.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">6</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-07</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">180</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">183.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">7</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-08</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">250</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">216.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">181.43</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">8</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-09</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">210</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">213.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">188.57</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">9</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-10</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">280</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">246.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">211.43</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">10</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-11</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">230</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">240.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">217.14</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">11</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-12</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">310</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">273.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">240.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">12</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-13</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">270</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">270.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">247.14</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">13</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-14</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">340</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">306.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">270.0</td>
      </tr>
    </tbody>
  </table>
</div>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">比較項目</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">window=3</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">window=7</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">使うデータ数</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近3行</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近7行</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">滑らかさ</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">小さい</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">大きい</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">急な変化への反応</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">比較的速い</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">比較的遅い</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">向いている目的</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">短期的な動きの確認</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">やや長い傾向の確認</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">先頭のNaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2行</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">6行</td>
      </tr>
    </tbody>
  </table>
</div>
<p>windowを大きくすると線は滑らかになりますが、急な上昇や下降が遅れて表れます。3日と7日のどちらが常に優れているわけではなく、<strong>どの程度の短期変動をならしたいか</strong>で選びます。</p>
<p>なお、移動平均は過去の値をならして見せる方法であり、将来を予測する機能ではありません。</p>

<h2><span id="toc12">rolling().mean()とrolling().sum()の違い</span></h2>
<p><code>rolling()</code>の後ろには、目的に合った集計メソッドを続けます。</p>
<ul>
  <li><code>mean()</code>：直近の平均を求め、変動をならす</li>
  <li><code>sum()</code>：直近の合計を求める</li>
</ul>
<p>たとえば「直近3日間の売上合計」を求める場合は、<code>sum()</code>を使います。</p>

<pre class="line-numbers"><code class="language-python">df["直近3日売上合計"] = df["売上"].rolling(window=3).sum()

df[["日付", "売上", "3日移動平均", "直近3日売上合計"]].head(7)</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">日付</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">3日移動平均</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">直近3日売上合計</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">1</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-03</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">380.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">3</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-04</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">470.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">4</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">150</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">153.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">460.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">5</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">220</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">186.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">560.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">6</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">2026-08-07</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">180</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">183.33</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">550.0</td>
      </tr>
    </tbody>
  </table>
</div>

<p>同じwindowでも、<code>mean()</code>は傾向をならす用途、<code>sum()</code>は直近期間の累計を確認する用途に向いています。</p>

<h3><span id="toc13">rolling()の後ろで使える主な集計メソッド</span></h3>
<p>rolling()は対象範囲を決める処理です。その後ろに、目的に合った集計メソッドを続けます。</p>
<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">メソッド</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">求める値</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">使用例</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>mean()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">平均</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">売上の短期変動をならす</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>sum()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">合計</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近3日分の売上合計を求める</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>min()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">最小値</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近期間の最低売上を確認する</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>max()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">最大値</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近期間の最高売上を確認する</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>median()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">中央値</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">極端な値の影響を抑えて中心を見る</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>std()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">標準偏差</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">直近期間のばらつきを確認する</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>count()</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">有効値の個数</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">window内のデータ数を確認する</td>
      </tr>
    </tbody>
  </table>
</div>
<p>初心者は、まず<code>mean()</code>と<code>sum()</code>を使い分けられれば十分です。ほかのメソッドも書き方は同じで、必要になったときに選べます。</p>

<h2><span id="toc14">元の売上と移動平均を折れ線グラフで比較する</span></h2>
<p>数値表だけでなく、元の売上、3日移動平均、7日移動平均を同じグラフへ描くと、windowによる滑らかさの違いが分かります。</p>
<p>ここではグラフの装飾ではなく、<strong>元の値の上下が移動平均でどのようにならされるか</strong>に注目してください。</p>

<pre class="line-numbers"><code class="language-python">plt.figure(figsize=(10, 5))
plt.plot(df["日付"], df["売上"], marker="o", alpha=0.55, label="Daily sales")
plt.plot(df["日付"], df["3日移動平均"], linewidth=2.5, label="3-row moving average")
plt.plot(df["日付"], df["7日移動平均"], linewidth=2.5, label="7-row moving average")

plt.xlabel("Date")
plt.ylabel("Sales")
plt.title("Daily sales and moving averages")
plt.grid(alpha=0.3)
plt.legend()
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()</code></pre>

<figure class="colab-figure">
  <img decoding="async" src="images/figure1.png" alt="日別売上と3日移動平均・7日移動平均を比較した折れ線グラフ">
  <figcaption>日別売上と3日移動平均・7日移動平均の比較</figcaption>
</figure>

<p>3日移動平均は元の売上の変化に比較的早く反応し、7日移動平均はさらに滑らかになります。一方で、windowが大きいほど直近の変化が遅れて見える点には注意が必要です。</p>
<p>グラフの色・線種・凡例などを詳しく設定したい場合は、<a href="https://pythondatalab.com/matplotlib-line-legend-color/">Matplotlib折れ線グラフの描き方</a>を参照してください。</p>

<h2><span id="toc15">rolling(3)とrolling(&#8220;3D&#8221;)は対象範囲が違う</span></h2>
<p>ここまで使った<code>rolling(3)</code>は直近3行を対象にします。一方、日付をインデックスにした時系列データでは、<code>rolling("3D")</code>のように実際の期間を指定できます。</p>
<p>違いが分かるように、8月3日と4日が欠けたデータで比較します。</p>

<pre class="line-numbers"><code class="language-python">df_gap = pd.DataFrame({
    "日付": pd.to_datetime(["2026-08-01", "2026-08-02", "2026-08-05", "2026-08-06"]),
    "売上": [100, 160, 120, 190]
}).set_index("日付")

df_gap["直近3行平均"] = df_gap["売上"].rolling(3).mean()
df_gap["直近3日平均"] = df_gap["売上"].rolling("3D").mean()

df_gap</code></pre>

<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"></th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">売上</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">直近3行平均</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">直近3日平均</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-01</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">100.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-02</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">160.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">NaN</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">130.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-05</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">126.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">120.0</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">2026-08-06</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">190.0</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">156.67</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">155.0</td>
      </tr>
    </tbody>
  </table>
</div>

<p>8月5日の「直近3行平均」は8月1日・2日・5日の3行を使います。一方、「直近3日平均」は実際の日付間隔を見るため、8月5日時点の直近3日内にある値だけが対象です。</p>
<div class="colab-table-wrap">
  <table class="wp-block-table">
    <thead>
      <tr>
        <th style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;">書き方</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">windowの基準</th>
        <th style="white-space: nowrap; padding: 0.2em 0.4em;">欠損日がある場合</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>rolling(3)</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">行数</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">日付が離れていても直近3行を使う</td>
      </tr>
      <tr>
        <td style="min-width: 3em; white-space: nowrap; padding: 0.2em 0.4em;"><code>rolling("3D")</code></td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">実際の3日間</td>
        <td style="white-space: nowrap; padding: 0.2em 0.4em;">その期間内にある行だけを使う</td>
      </tr>
    </tbody>
  </table>
</div>
<p>1日1行で日付が連続していれば両者は似た結果になりますが、欠損日や不規則な時刻があるデータでは一致しません。期間指定にはDatetimeIndexが必要です。この記事の中心は行数ベースの移動平均なので、期間指定はこの違いだけ押さえれば十分です。</p>

<h2><span id="toc16">rolling()でよくあるミスと注意点</span></h2>
<h3><span id="toc17">window=3を必ず3日間だと思ってしまう</span></h3>
<p>数値の<code>window=3</code>は基本的に3行です。1日に複数行がある場合や、日付が抜けている場合は3日間と一致しません。期間ベースでは<code>rolling("7D")</code>のような指定もできますが、日付インデックスなどの前提が増えるため、この記事では詳しく扱いません。</p>
<h3><span id="toc18">日付順に並べず計算する</span></h3>
<p>rolling()は現在の行順を使います。日付が前後したままでは、時間の流れに沿った移動平均になりません。先にdatetime型へ変換し、<code>sort_values()</code>で並べ替えましょう。</p>
<h3><span id="toc19">先頭のNaNをエラーだと思う</span></h3>
<p>必要な値がwindowの数に達していないためです。0埋めで隠すのではなく、NaNが生じる理由を確認します。</p>
<h3><span id="toc20">rolling()だけで元のDataFrameが変わると思う</span></h3>
<p>rolling()の計算結果は自動的に元のDataFrameへ追加されません。残したい場合は、この記事の例のように新しい列へ代入します。列追加の基本は、<a href="https://pythondatalab.com/pandas-add-column/">pandasで新しい列を追加する方法</a>で確認できます。</p>
<h3><span id="toc21">欠損値があっても同じように計算できると思う</span></h3>
<p>元データに欠損値があると、window内の有効値の数と<code>min_periods</code>によって結果が変わります。まず欠損の場所と意味を確認し、必要な件数を満たしているか判断してください。</p>

<h2><span id="toc22">データ分析の流れでrolling()を使う位置</span></h2>
<p>rolling()は、データを読み込んだ直後ではなく、日付や並び順を整えた後に使います。</p>
<p>1. CSVやExcelを読み込む 2. <code>head()</code>や<code>dtypes</code>で内容と型を確認する 3. 日付列を<code>to_datetime()</code>で変換する 4. 日付順に並べ替える 5. 必要に応じて<code>resample()</code>で時間単位を整える 6. <code>rolling()</code>で短期変動をならす 7. 折れ線グラフで元の値と比較する</p>
<p>年・月・曜日を取り出して別の切り口で集計したい場合は、<a href="https://pythondatalab.com/pandas-dt/">pandas dtの使い方</a>へ進んでください。</p>
<p>発展的な機能には、開始行から対象範囲を広げる<code>expanding()</code>、新しい値へ大きな重みを付ける<code>ewm()</code>、グループ別に計算する<code>groupby().rolling()</code>などがあります。<code>center=True</code>による結果位置の変更や欠損日の補間も含め、これらは基本を理解してから学べば十分です。</p>

<h2><span id="toc23">まとめ</span></h2>
<ul>
  <li><code>rolling()</code>は、直近の複数行を1行ずつずらしながら計算する</li>
  <li><code>rolling(window=3).mean()</code>は、原則として現在行を含む直近3行の平均を求める</li>
  <li>数値のwindowは基本的に行数であり、自動的に日数を意味するわけではない</li>
  <li>3行そろう前のNaNはエラーではなく、同じ条件で計算できないことを示す</li>
  <li><code>min_periods=1</code>なら先頭から計算できるが、利用する値の数が行ごとに異なる</li>
  <li><code>center=True</code>を指定すると、計算結果をwindowの中央に置ける</li>
  <li><code>rolling(3)</code>は直近3行、<code>rolling("3D")</code>は実際の直近3日間を対象にする</li>
  <li>window=3は変化へ比較的早く反応し、window=7は滑らかだが反応が遅くなる</li>
  <li>傾向を見るなら<code>mean()</code>、直近の合計を見るなら<code>sum()</code>を使う</li>
  <li>集計単位を変える<code>resample()</code>と、値をならす<code>rolling()</code>は目的が異なる</li>
  <li>計算前に日付型と並び順を確認し、計算後は元の値とグラフで比較する</li>
</ul>
<p>まずはこの記事のサンプルで3日移動平均を実行し、windowを7へ変えたときに結果がどのように変化するか確認してみてください。</p>

<h2><span id="toc24">次に読みたい関連記事</span></h2>
<ul>
  <li><a href="https://pythondatalab.com/google-colab-csv/">Google ColabでCSVを読み込む方法｜アップロード・Drive・read_csv</a></li>
  <li><a href="https://pythondatalab.com/pandas-dataframe/">Pandas DataFrame入門｜作り方・基本操作をわかりやすく解説</a></li>
  <li><a href="https://pythondatalab.com/pandas-to-datetime/">pandas to_datetime()の使い方｜文字列の日付変換とformat・NaT対処</a></li>
  <li><a href="https://pythondatalab.com/pandas-sort/">pandas 並び替え（sort）入門｜sort_values・sort_indexの違い</a></li>
  <li><a href="https://pythondatalab.com/pandas-set-index/">pandas set_index()の使い方｜列をインデックスにする方法</a></li>
  <li><a href="https://pythondatalab.com/pandas-dt/">pandas dtの使い方｜日付から年・月・曜日を取り出す方法</a></li>
  <li><a href="https://pythondatalab.com/pandas-resample/">pandas resample()の使い方｜日付データを月別・週別に集計</a></li>
  <li><a href="https://pythondatalab.com/pandas-add-column/">pandasで新しい列を追加する方法</a></li>
  <li><a href="https://pythondatalab.com/matplotlib-line-legend-color/">Matplotlib折れ線グラフの描き方</a></li>
</ul>


<!-- ▼▼▼ カテゴリから探す　 共通スタイル（カテゴリ）▼▼▼ -->
<style> .related-box { border: 2px solid #0073aa; border-radius: 10px; padding: 1em 1.2em; margin-top: 2em; background: #f8faff; } .related-box h3 { margin-top: 0; color: #0073aa; } .related-box ul { list-style-type: none; margin: 0; padding: 0; } .related-box li { margin: 0.4em 0; } .related-box a { text-decoration: none; color: #333; } .related-box a:hover { text-decoration: underline; color: #0073aa; } </style> <div class="related-box"> <h3><span id="toc25"> カテゴリから探す</span></h3> <ul>
<ul>
<li><a href="https://pythondatalab.com/category/pandas/basic/">◀ Pandas 基礎</a></li>
<li><a href="https://pythondatalab.com/category/pandas/preprocessing/">◀ Pandas 抽出・前処理</a></li>
<li><a href="https://pythondatalab.com/category/pandas/aggregation/">◀ Pandas 集計・変形</a></li>
<li><a href="https://pythondatalab.com/category/pandas/visualization/">▶ Matplotlib　可視化</a></li> </ul> </ul></div>
<!-- ▼▼▼ カテゴリから探す　共通スタイル（カテゴリ）終了▼▼▼ -->
<p style="text-align: center; margin-top: 2em;"><a href="#top">▲ ページトップへ戻る</a></p></div>
</div>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1787145577821" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc26">pandasのrolling()は何をするメソッドですか？</span></h3>
<div class="rank-math-answer ">

<p>現在行を含む直近の複数行を対象に、平均・合計などを繰り返し計算するメソッドです。日別売上の短期的な変動をならし、傾向を見やすくする場面などで使います。</p>

</div>
</div>
<div id="faq-question-1787145589543" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc27">rolling(3)の3は3日という意味ですか？</span></h3>
<div class="rank-math-answer ">

<p>基本的には3行という意味です。データが1日1行で日付も連続している場合に限り、3日移動平均として読めます。実際の期間を基準にする方法には<code>rolling("3D")</code>などがありますが、日付インデックスなどの前提が必要です。</p>

</div>
</div>
<div id="faq-question-1787145600876" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc28">rolling()の結果で最初の行がNaNになるのはなぜですか？</span></h3>
<div class="rank-math-answer ">

<p>windowで指定した数の有効な値がまだそろっていないためです。<code>window=3</code>の初期設定では、最初の2行がNaNになり、3行目から結果が出ます。</p>

</div>
</div>
<div id="faq-question-1787145615895" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc29">min_periods=1を指定すればNaNを消してもよいですか？</span></h3>
<div class="rank-math-answer ">

<p>目的によります。先頭から値を表示できますが、最初は1個、次は2個、その後は3個の平均となり、計算条件がそろいません。元データに欠損値がある場合も、有効値の数が<code>min_periods</code>以上かで結果が決まるため、NaNを消す前に利用件数を確認してください。</p>

</div>
</div>
<div id="faq-question-1787145626826" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc30">rolling()とresample()は何が違いますか？</span></h3>
<div class="rank-math-answer ">

<p>rolling()は直近数行をずらしながら計算し、原則として元の行数を保ちます。resample()は日別を月別にするように時間単位を変えて再集計するため、通常は行数も変わります。1日ごとの行を残すか、期間ごとにまとめるかで判断してください。</p>

</div>
</div>
<div id="faq-question-1787145638388" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc31">center=Trueはどんなときに使いますか？</span></h3>
<div class="rank-math-answer ">

<p>計算結果をwindowの中央に置きたいときに使います。過去から現在までの傾向を見る通常の移動平均では初期設定のまま、前後の値で中央時点をならしたい場合は<code>center=True</code>が候補です。</p>

</div>
</div>
<div id="faq-question-1787145648723" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc32">DataFrame全体にrolling()を使えますか？</span></h3>
<div class="rank-math-answer ">

<p>使えます。複数の数値列を持つDataFrameに適用すると、各数値列へ同じwindowの計算が行われます。ただし、初心者は分析対象の列を選んでから適用すると、結果を理解しやすくなります。</p>

</div>
</div>
<div id="faq-question-1787145654142" class="rank-math-list-item">
<h3 class="rank-math-question "><span id="toc33">expanding()やewm()とは何が違いますか？</span></h3>
<div class="rank-math-answer ">

<p><code>expanding()</code>は開始点から現在行まで計算範囲を広げます。<code>ewm()</code>は一般に新しい値へ大きな重みを付けて計算します。まずは一定数の直近行を扱うrolling()から覚えると分かりやすいでしょう。</p>

</div>
</div>
</div>
</div><p>&lt;p&gt;The post <a rel="nofollow" href="https://pythondatalab.com/pandas-rolling/">pandas rolling()の使い方｜移動平均・window・NaNを初心者向けに解説</a> first appeared on <a rel="nofollow" href="https://pythondatalab.com">Python Data Lab（Pythonデータラボ）</a>.&lt;/p&gt;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pythondatalab.com/pandas-rolling/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
