<?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>「groupby」タグの記事一覧Python Tech</title>
	<atom:link href="https://tech.nkhn37.net/tag/groupby/feed" rel="self" type="application/rss+xml" />
	<link>https://tech.nkhn37.net</link>
	<description>Python学習サイト</description>
	<lastBuildDate>Sun, 11 Jan 2026 08:43:19 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://tech.nkhn37.net/wp-content/uploads/2021/01/cropped-lion-normal-clear-1-32x32.png</url>
	<title>「groupby」タグの記事一覧Python Tech</title>
	<link>https://tech.nkhn37.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【PySpark】DataFrameの行・列の基本的な操作方法</title>
		<link>https://tech.nkhn37.net/pyspark-dataframe-row-column/</link>
					<comments>https://tech.nkhn37.net/pyspark-dataframe-row-column/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 11 Nov 2023 20:00:00 +0000</pubDate>
				<category><![CDATA[PySpark]]></category>
		<category><![CDATA[columns]]></category>
		<category><![CDATA[DataFrame]]></category>
		<category><![CDATA[drop]]></category>
		<category><![CDATA[dropduplicates]]></category>
		<category><![CDATA[expr]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[groupby]]></category>
		<category><![CDATA[orderBy]]></category>
		<category><![CDATA[rows]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[sort]]></category>
		<category><![CDATA[union]]></category>
		<category><![CDATA[where]]></category>
		<category><![CDATA[withcolumn]]></category>
		<category><![CDATA[withcolumnrenamed]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=9705</guid>

					<description><![CDATA[PySpark で DataFrame の行や列を操作する方法について解説します。 DataFrame の行・列の基本操作 PySpark は、分散処理フレームワーク Apache Spark の Python 用 AP [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>PySpark で <span class="jinr-d--text-color d--marker1 d--bold">DataFrame の行や列を操作する方法</span>について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">DataFrame の行・列の基本操作</h2>



<p>PySpark は、分散処理フレームワーク Apache Spark の Python 用 API です。PySpark では、<span class="jinr-d--text-color d--marker1 d--bold">DataFrame</span> というデータ構造を使用します。</p>



<p>この記事では <span class="jinr-d--text-color d--marker1 d--bold">PySpark で DataFrame の行や列を操作する方法</span>を紹介します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>実行環境は、Docker で構築した Spark 環境の Jupyter Notebook を使用します。環境構築方法は「<a href="https://tech.nkhn37.net/docker-pyspark-notebook/" data-type="link" data-id="https://tech.nkhn37.net/docker-pyspark-notebook/" target="_blank" rel="noreferrer noopener">PySparkの実行環境をDockerで用意する方法</a>」を参考にしてください。</p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>Spark と PySpark 概要や Spark アプリケーションの概念は「<a href="https://tech.nkhn37.net/apache-spark-pyspark-overview/" data-type="link" data-id="https://tech.nkhn37.net/apache-spark-pyspark-overview/" target="_blank" rel="noreferrer noopener">Apache SparkとPySparkの概要</a>」や「<a href="https://tech.nkhn37.net/spark-application-concept/" data-type="link" data-id="https://tech.nkhn37.net/spark-application-concept/" target="_blank" rel="noreferrer noopener">Sparkアプリケーションの概念を理解する</a>」を参考にしてください。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">行 (Rows) の操作</h3>



<h4 class="wp-block-heading jinr-heading d--bold">DataFrame の作成</h4>



<p>操作の説明するための DataFrame を以下のように作成します。以降の操作は、この DataFrame をベースにして説明します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, StringType, IntegerType, FloatType

# SparkSessionの初期化
spark = SparkSession.builder.appName("ColumnsOperation").getOrCreate()

# スキーマを定義
schema = StructType([
    StructField("Firstname", StringType(), True),
    StructField("Lastname", StringType(), True),
    StructField("Gender", StringType(), True),
    StructField("Age", IntegerType(), True),
    StructField("Department", StringType(), True),
    StructField("Salary", IntegerType(), True),    
])
# データを作成
data = [
    ("James", "Smith", "M", 30, "Sales", 3000),
    ("Anna", "Rose", "F", 41, "Engineering", 4000),
    ("Robert", "Williams", "M", 62, "Logistics", 5000),
]
# データフレームの作成
df = spark.createDataFrame(data, schema=schema)
df.printSchema()
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
root
 |-- Firstname: string (nullable = true)
 |-- Lastname: string (nullable = true)
 |-- Gender: string (nullable = true)
 |-- Age: integer (nullable = true)
 |-- Department: string (nullable = true)
 |-- Salary: integer (nullable = true)

+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    James|   Smith|     M| 30|      Sales|  3000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
+---------+--------+------+---+-----------+------+</pre>



<p>なお、処理完了後には <code>SparkSession</code> を終了しますが説明では省略します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># SparkSessionを終了
spark.stop()</pre>



<p>以降では、上記で作成した DataFrame を使って行の基本操作を説明します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>DataFrame の作成やスキーマに関する説明は省略しています。「<a href="https://tech.nkhn37.net/pyspark-dataframe-create-and-schema/" target="_blank" rel="noreferrer noopener">DataFrameの作成方法とスキーマ</a>」を参考にしてください。</p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold">行の追加 <code>union</code></h4>



<p>DataFrame に行を追加する際は <span class="jinr-d--text-color d--marker1 d--bold"><code>union</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 行の追加 union
# 追加する行を作成
new_data = [
    ("Michael", "Brown", "M", 34, "Sales", 3500),
    ("Maria", "Garcia", "F", 20, "Engineering", 2000),
    ("Mary", "Smith", "F", 25, "Accounting", 2500),
]
new_row = spark.createDataFrame(new_data, schema)
# データフレームに追加
df = df.union(new_row)
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    James|   Smith|     M| 30|      Sales|  3000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Mary|   Smith|     F| 25| Accounting|  2500|
+---------+--------+------+---+-----------+------+</pre>



<p>例では、まず <code>new_data</code> をもとにして <code>new_row</code> という DataFrame を作成しています。データフレームに行を追加するには <code>union</code> メソッドに作成した DataFrame を渡します。</p>



<p>注意点として <code>union</code> は「<span class="jinr-d--text-color d--marker1 d--bold">結合する 2 つのDataFrameのスキーマが完全に一致していること</span>」が必要です。スキーマが異なる場合は、エラーとなるので注意しましょう。</p>



<h4 class="wp-block-heading jinr-heading d--bold">条件をもとに行を抽出 <code>filter</code> / <code>where</code></h4>



<p>条件をもとに行を抽出する場合には、<span class="jinr-d--text-color d--marker1 d--bold"><code>filter</code></span> または <span class="jinr-d--text-color d--marker1 d--bold"><code>where</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 条件をもとに行を抽出 filter/where
# filterで式で抽出
df_filter = df.filter(df.Age > 30)
df_filter.show()
# filterで文字列条件で抽出
df_filter = df.filter("Age > 30")
df_filter.show()

# --- whereはfilterのエイリアスとなっている
# whereで式で抽出
df_where = df.where(df.Age > 30)
df_where.show()

# whereで文字列条件で抽出
df_where = df.where("Age > 30")
df_where.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】複数回出力しているがいずれも出力結果は同じ
+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
|  Michael|   Brown|     M| 34|      Sales|  3500|
+---------+--------+------+---+-----------+------+</pre>



<p>抽出されている実行結果はいずれも同じです。<code>filter</code> と <code>where</code> は同じものになるためどちらを使うかは開発者次第です。実際に、公式ドキュメントにも「<code>where()</code> is an alias for <code>filter()</code>.」というように、<code>where</code> は <code>filter</code> の別名（エイリアス）と記載されていますので、いずれを使っても構いません。</p>



<p>条件指定の方法は「<code>df.Age > 30</code>」のように条件式を指定する方法と「<code>"Age > 30"</code>」のように SQL の条件文字列として指定する方法が使用できます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">行の削除 <code>filter</code></h4>



<p>行の削除をしたい場合には、<code>filter</code> で削除対象の行を除いた DataFrame を作ることで実現します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 行の削除 filter
# 行を削除
df = df.filter(df.Firstname != "Michael")
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    James|   Smith|     M| 30|      Sales|  3000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Mary|   Smith|     F| 25| Accounting|  2500|
+---------+--------+------+---+-----------+------+</pre>



<p>上記例では <code>Firstname</code> が <code>"Micahel"</code> でない行のみを抽出しています。これは、<code>Firstname</code> が <code>"Micahel"</code> である行を削除していることと同じです。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><strong>【なぜ削除を filter で行うのか】</strong></p>



<p>Spark では DataFrame の元になっている RDD（Resilient Distributed Dataset）が不変（immutable）で内容を書き換えることができない仕組みになっています。そのため、行を「削除する」というよりは、不要な行を除いた新しい DataFrame を作り直す形で処理します。</p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold">行の並べ替え <code>sort</code> / <code>orderBy</code>　</h4>



<p>DataFrame の行を並べ替えたい場合には <span class="jinr-d--text-color d--marker1 d--bold"><code>sort</code></span> または <span class="jinr-d--text-color d--marker1 d--bold"><code>orderBy</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 行の並び替え sort/orderBy
# === sortで並び替え
print("===== sort")
# 昇順
df_sort = df.sort(df.Age)
df_sort.show()

# 降順
df_sort = df.sort(df.Age.desc())
df_sort.show()

# 複数列による並び替え
df_sort = df.sort(df.Age, df.Salary.desc())
df_sort.show()

# === orderByで並び替え
print("===== orderBy")
# 昇順
df_orderby = df.orderBy(df.Age)
df_orderby.show()

# 降順
df_orderby = df.orderBy(df.Age.desc())
df_orderby.show()

# 複数条件を指定
df_orderby = df.orderBy(df.Age, df.Salary.desc())
df_orderby.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】sortもorderByも出力結果は同じ
+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Mary|   Smith|     F| 30| Accounting|  2500|
|    James|   Smith|     M| 30|      Sales|  3000|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
+---------+--------+------+---+-----------+------+

+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|   Robert|Williams|     M| 62|  Logistics|  5000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|     Mary|   Smith|     F| 30| Accounting|  2500|
|    James|   Smith|     M| 30|      Sales|  3000|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
+---------+--------+------+---+-----------+------+

+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|    James|   Smith|     M| 30|      Sales|  3000|
|     Mary|   Smith|     F| 30| Accounting|  2500|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
+---------+--------+------+---+-----------+------+</pre>



<p><code>sort</code> と <code>orderBy</code> の使い方は同じです。上記例のように <code>sort</code> や <code>orderBy</code> の引数に <code>df.Age</code> といった並び替えのキーとなる列を指定することで並び替えができます。デフォルトは昇順となります。</p>



<p>降順にしたい場合には、指定する際に <code>df.Age.desc()</code> のように降順にする <code>desc</code> メソッドを指定します。また、複数列により並び替えを行う場合には、引数に <code>(df.Age, df.Salary.desc())</code> のように指定することで実現できます。例では、第 1 キーとして <code>Age</code> 列で昇順に並び替え、第 2 キーとして <code>Salary</code> 列で降順に並び替えます。</p>



<p>なお、以下のように文字列で列名を指定することも可能です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from pyspark.sql.functions import col

# 昇順
df_sort = df.sort("Age")

# 降順
df_sort = df.sort(col("Age").desc())

# 複数列による並び替え
df_sort = df.sort("Age", col("Salary").desc())</pre>



<p>文字列で指定する場合で、降順に指定する際には <code>pyspark.sql.functions</code> から <code>col</code> をインポートして指定することでメソッドを使用することが可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">行のグループ化 <code>groupBy</code></h4>



<p>行のグループ化して集約するには、<span class="jinr-d--text-color d--marker1 d--bold"><code>groupBy</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 行のグループ化 groupBy
# グループ化して行をカウント
df_groupby_count = df.groupBy("Department").count()
df_groupby_count.show()

# グループ化して最大値を計算
df_groupby_max = df.groupBy("Department").max()
df_groupby_max.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
+-----------+-----+
| Department|count|
+-----------+-----+
|      Sales|    2|
|Engineering|    2|
|  Logistics|    1|
| Accounting|    1|
+-----------+-----+

+-----------+--------+-----------+
| Department|max(Age)|max(Salary)|
+-----------+--------+-----------+
|      Sales|      34|       3500|
|Engineering|      41|       4000|
|  Logistics|      62|       5000|
| Accounting|      30|       2500|
+-----------+--------+-----------+</pre>



<p>例のように <code>groupBy</code> の引数にグループ化する列名を指定します。その後、<code>count()</code> や <code>max()</code> のような集約関数を適用することで、グループごとの集約が可能です。なお、<code>groupBy()</code> の別名（エイリアス）として <code>groupby()</code> を使うことも可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">行の重複削除 <code>dropDuplicates</code></h4>



<p>重複する行を削除したい場合には、<span class="jinr-d--text-color d--marker1 d--bold"><code>dropDuplicates</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 行の重複削除 dropDuplicates
# 重複行を追加
new_row = spark.createDataFrame([
    ("Michael", "Brown", "M", 34, "Sales", 3500),
    ("Maria", "Garcia", "F", 20, "Engineering", 2000),
    ("Mary", "Smith", "F", 30, "Accounting", 2500),
], schema)
# データフレームに追加
df_temp = df.union(new_row)
df_temp.show()

# ==== 重複行を削除
print("===== dropDuplicates")
# すべての列が重複するものを削除
df_drop = df_temp.dropDuplicates()
df_drop.show()

# 指定の列で重複する行を削除
df_drop = df_temp.dropDuplicates(["Lastname"])
df_drop.show()

# 複数列で重複する行を削除
df_drop = df_temp.dropDuplicates(["Firstname", "Lastname"])
df_drop.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    James|   Smith|     M| 30|      Sales|  3000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Mary|   Smith|     F| 30| Accounting|  2500|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Mary|   Smith|     F| 30| Accounting|  2500|
+---------+--------+------+---+-----------+------+

===== dropDuplicates
+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    James|   Smith|     M| 30|      Sales|  3000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Mary|   Smith|     F| 30| Accounting|  2500|
+---------+--------+------+---+-----------+------+

+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|  Michael|   Brown|     M| 34|      Sales|  3500|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|    James|   Smith|     M| 30|      Sales|  3000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
+---------+--------+------+---+-----------+------+

+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|     Anna|    Rose|     F| 41|Engineering|  4000|
|    James|   Smith|     M| 30|      Sales|  3000|
|    Maria|  Garcia|     F| 20|Engineering|  2000|
|     Mary|   Smith|     F| 30| Accounting|  2500|
|  Michael|   Brown|     M| 34|      Sales|  3500|
|   Robert|Williams|     M| 62|  Logistics|  5000|
+---------+--------+------+---+-----------+------+</pre>



<p>例では、重複する行を <code>union</code> で追加して、その後 <code>dropDuplicates</code> で重複行を削除しています。引数を指定しないで <code>dropDuplicates</code> を指定する場合、すべての列が重複するような行が削除されます。</p>



<p>特定の列で重複削除したい場合は <code>["Lastname"]</code> のように列を指定できます。複数列で重複を確認したい場合は <code>["Firstname", "Lastname"]</code> のように列名を列挙します。</p>



<p>なお、<code>dropDuplicates()</code> の別名（エイリアス）として <code>drop_duplicates()</code> を使うことも可能です。</p>



<h3 class="wp-block-heading jinr-heading d--bold">列 (Columns) の基本操作</h3>



<h4 class="wp-block-heading jinr-heading d--bold">DataFrame の作成</h4>



<p>列の操作を説明するための DataFrame を以下のように作成します。以降の列操作は、この DataFrame をベースにして説明します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, StringType, IntegerType, FloatType

# SparkSessionの初期化
spark = SparkSession.builder.appName("ColumnsOperation").getOrCreate()

# スキーマを定義
schema = StructType([
    StructField("Firstname", StringType(), True),
    StructField("Lastname", StringType(), True),
    StructField("Gender", StringType(), True),
    StructField("Age", IntegerType(), True),
    StructField("Department", StringType(), True),
    StructField("Salary", IntegerType(), True),    
])
# データを作成
data = [
    ("James", "Smith", "M", 30, "Sales", 3000),
    ("Anna", "Rose", "F", 41, "Engineering", 4000),
    ("Robert", "Williams", "M", 62, "Logistics", 5000),
]
# データフレームの作成
df = spark.createDataFrame(data, schema=schema)
df.printSchema()
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
root
 |-- Firstname: string (nullable = true)
 |-- Lastname: string (nullable = true)
 |-- Gender: string (nullable = true)
 |-- Age: integer (nullable = true)
 |-- Department: string (nullable = true)
 |-- Salary: integer (nullable = true)

+---------+--------+------+---+-----------+------+
|Firstname|Lastname|Gender|Age| Department|Salary|
+---------+--------+------+---+-----------+------+
|    James|   Smith|     M| 30|      Sales|  3000|
|     Anna|    Rose|     F| 41|Engineering|  4000|
|   Robert|Williams|     M| 62|  Logistics|  5000|
+---------+--------+------+---+-----------+------+</pre>



<p>以降では、上記で作成したデータフレームを使って列の基本操作を説明します。</p>



<h4 class="wp-block-heading jinr-heading d--bold">列の追加 <code>withColumn</code></h4>



<p>列を追加したい場合は、<span class="jinr-d--text-color d--marker1 d--bold"><code>withColumn</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from pyspark.sql.functions import lit

#===== 列の追加 withColumn
# 定数列を追加
df = df.withColumn("Country", lit("USA"))
df = df.withColumn("Rate", lit(1.1).cast(FloatType()))
df.printSchema()
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
root
 |-- Firstname: string (nullable = true)
 |-- Lastname: string (nullable = true)
 |-- Gender: string (nullable = true)
 |-- Age: integer (nullable = true)
 |-- Department: string (nullable = true)
 |-- Salary: integer (nullable = true)
 |-- Country: string (nullable = false)
 |-- Rate: float (nullable = false)

+---------+--------+------+---+-----------+------+-------+----+
|Firstname|Lastname|Gender|Age| Department|Salary|Country|Rate|
+---------+--------+------+---+-----------+------+-------+----+
|    James|   Smith|     M| 30|      Sales|  3000|    USA| 1.1|
|     Anna|    Rose|     F| 41|Engineering|  4000|    USA| 1.1|
|   Robert|Williams|     M| 62|  Logistics|  5000|    USA| 1.1|
+---------+--------+------+---+-----------+------+-------+----+</pre>



<p>例のように <code>withColumn</code> には、列名と値を渡します。<code>pyspark.sql.functions</code> からインポートできる <code>lit</code> を使うと定数値列を作成できます。<code>lit</code> はリテラルの意味です。</p>



<p>また、指定した型で作成したい場合は <code>cast</code> を使って型指定できます。上記例では <code>1.1</code> という数値を <code>FloatType()</code> として作成しています。</p>



<h4 class="wp-block-heading jinr-heading d--bold">列の名称変更 <code>withColumnRenamed</code></h4>



<p>列の名称変更をしたい場合は、<span class="jinr-d--text-color d--marker1 d--bold"><code>withColumnRenamed</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 列の名称変更 withColumnRenamed
df = df.withColumnRenamed("Department", "Dept")
df.printSchema()
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
root
 |-- Firstname: string (nullable = true)
 |-- Lastname: string (nullable = true)
 |-- Gender: string (nullable = true)
 |-- Age: integer (nullable = true)
 |-- Dept: string (nullable = true)
 |-- Salary: integer (nullable = true)
 |-- Country: string (nullable = false)
 |-- Rate: float (nullable = false)

+---------+--------+------+---+-----------+------+-------+----+
|Firstname|Lastname|Gender|Age|       Dept|Salary|Country|Rate|
+---------+--------+------+---+-----------+------+-------+----+
|    James|   Smith|     M| 30|      Sales|  3000|    USA| 1.1|
|     Anna|    Rose|     F| 41|Engineering|  4000|    USA| 1.1|
|   Robert|Williams|     M| 62|  Logistics|  5000|    USA| 1.1|
+---------+--------+------+---+-----------+------+-------+----+</pre>



<p><code>withColumnRenamed</code> の引数として、変更前の列名と変更後の列名を指定することで列名を変更できます。例では、<code>Department</code> 列を <code>Dept</code> という省略形に変更しています。</p>



<h4 class="wp-block-heading jinr-heading d--bold">列の削除 <code>drop</code></h4>



<p>列自体を削除したい場合は、<span class="jinr-d--text-color d--marker1 d--bold"><code>drop</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 列の削除 drop
df = df.drop("Country")
df.printSchema()
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
root
 |-- Firstname: string (nullable = true)
 |-- Lastname: string (nullable = true)
 |-- Gender: string (nullable = true)
 |-- Age: integer (nullable = true)
 |-- Dept: string (nullable = true)
 |-- Salary: integer (nullable = true)
 |-- Rate: float (nullable = false)

+---------+--------+------+---+-----------+------+----+
|Firstname|Lastname|Gender|Age|       Dept|Salary|Rate|
+---------+--------+------+---+-----------+------+----+
|    James|   Smith|     M| 30|      Sales|  3000| 1.1|
|     Anna|    Rose|     F| 41|Engineering|  4000| 1.1|
|   Robert|Williams|     M| 62|  Logistics|  5000| 1.1|
+---------+--------+------+---+-----------+------+----+</pre>



<p><code>drop</code> で対象列を指定することで列情報を削除できます。例では、<code>Country</code> 列を削除しています。</p>



<h4 class="wp-block-heading jinr-heading d--bold">列の選択 <code>select</code></h4>



<p>特定列だけを選択したい場合には、<span class="jinr-d--text-color d--marker1 d--bold"><code>select</code></span> を使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== 列の選択 select
df_selected = df.select(["Firstname", "Age"])
df_selected.printSchema()
df_selected.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
root
 |-- Firstname: string (nullable = true)
 |-- Age: integer (nullable = true)

+---------+---+
|Firstname|Age|
+---------+---+
|    James| 30|
|     Anna| 41|
|   Robert| 62|
+---------+---+</pre>



<p>例のように <code>select</code> に抽出したい特定の列を列挙したリストを渡すことで、列選択をすることが可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">式の適用 <code>expr</code></h4>



<p>列の操作をする際には、いくつかの列を使って計算をしたくなることがよくあります。このような場合には、<span class="jinr-d--text-color d--marker1 d--bold"><code>expr</code></span> を使用すると便利です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from pyspark.sql.functions import expr

# ===== 式の適用 expr
df = df.withColumn("Increased Salary", expr("Salary * Rate"))
df.printSchema()
df.show()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
root
 |-- Firstname: string (nullable = true)
 |-- Lastname: string (nullable = true)
 |-- Gender: string (nullable = true)
 |-- Age: integer (nullable = true)
 |-- Dept: string (nullable = true)
 |-- Salary: integer (nullable = true)
 |-- Rate: float (nullable = false)
 |-- Increased Salary: float (nullable = true)

+---------+--------+------+---+-----------+------+----+----------------+
|Firstname|Lastname|Gender|Age|       Dept|Salary|Rate|Increased Salary|
+---------+--------+------+---+-----------+------+----+----------------+
|    James|   Smith|     M| 30|      Sales|  3000| 1.1|          3300.0|
|     Anna|    Rose|     F| 41|Engineering|  4000| 1.1|          4400.0|
|   Robert|Williams|     M| 62|  Logistics|  5000| 1.1|          5500.0|
+---------+--------+------+---+-----------+------+----+----------------+</pre>



<p><code>expr</code> では、文字列を用いて SQL の式を指定できます。上記で紹介した <code>withColumn</code> と一緒に使うことで、計算式を適用した列を簡単に作成可能です。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>PySpark において <span class="jinr-d--text-color d--marker1 d--bold">DataFrame の行や列を操作する方法</span>について解説しました。</p>



<p>PySpark では、分散処理環境を使ってデータ分析を効率的に実行することが可能です。DataFrame の行や列の操作は、各種分析などを進めていくにあたっての基本となります。この記事では、行や列に対する基本操作について各種紹介しました。</p>



<p>各種使い方をしっかり覚えて、効率的なデータ分析に活用してもらいたいと思います。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/pyspark/dataframe-rows-and-columns" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://tech.nkhn37.net/python-tech-summary-page/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://tech.nkhn37.net/wp-content/uploads/2024/08/Python-Tech-Pythonプログラミングガイド_new1-640x360.jpg" alt="【Python Tech】プログラミングガイド" /></div><div class="a--blogcard-title d--bold">【Python Tech】プログラミングガイド</div></a></section>


<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.nkhn37.net/pyspark-dataframe-row-column/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【pandas】DataFrameのpivot_tableでピボットテーブルを扱う</title>
		<link>https://tech.nkhn37.net/pandas-dataframe-pivot-table/</link>
					<comments>https://tech.nkhn37.net/pandas-dataframe-pivot-table/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Wed, 16 Mar 2022 20:00:00 +0000</pubDate>
				<category><![CDATA[pandas]]></category>
		<category><![CDATA[aggfunc]]></category>
		<category><![CDATA[columns]]></category>
		<category><![CDATA[groupby]]></category>
		<category><![CDATA[index]]></category>
		<category><![CDATA[pivot_table]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=3114</guid>

					<description><![CDATA[pandasのDataFrameでpivot_tableを使ってピボットテーブルを扱う方法について解説します。 pivot_tableによるピボットテーブルの作成 表形式のデータを扱う際に良く行われる操作としてピボットテ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>pandasの<span class="marker"><strong>DataFrameで<code>pivot_table</code>を使ってピボットテーブルを扱う方法</strong></span>について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">pivot_tableによるピボットテーブルの作成</h2>



<p>表形式のデータを扱う際に良く行われる操作として<span class="marker"><strong>ピボットテーブル</strong></span>があります。ピボットテーブルは主にExcel等の表計算やDB管理で使用される視覚化ツールです。データの分類や整理、集約といったことが効率的にできるとともに、視覚的にデータの構造を理解しやすくなります。</p>



<p>pandasのDataFrameではピボットテーブルを作成するために<span class="marker"><strong><code>pivot_table</code></strong></span>という便利な関数が用意されています。本記事ではpivot_tableの基本的な使用方法を紹介します。</p>



<p>以降でpivot_tableの使い方を紹介するために、以下の簡単なcsvデータを用います。想定するのは企業での売上一覧データで、各製品がいつ、どこに、いくらで売られたかをまとめているものをイメージしてください。このデータを使って、製品ごと、顧客ごと等で整理したピボットテーブルを作る例を紹介していきます。</p>


<div class="wp-block-image is-resized">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="742" height="848" src="https://tech.nkhn37.net/wp-content/uploads/2022/10/image-3.png" alt="pandas pivot_table サンプルデータ" class="wp-image-5377" style="width:380px;height:auto" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/10/image-3.png 742w, https://tech.nkhn37.net/wp-content/uploads/2022/10/image-3-263x300.png 263w" sizes="(max-width: 742px) 100vw, 742px" /></figure>
</div>


<h3 class="wp-block-heading jinr-heading d--bold">基本的なpivot_tableの使い方</h3>



<p>上記で説明したサンプルデータ(<code>sample.csv</code>)を読み込み、各製品ごとの各月売上合計となる以下のようなピボットテーブルを作ってみることを考えてみます。</p>


<div class="wp-block-image is-resized">
<figure class="aligncenter size-full"><img decoding="async" width="632" height="260" src="https://tech.nkhn37.net/wp-content/uploads/2022/10/image-4.png" alt="ピボットテーブル (pivot_table) 例" class="wp-image-5379" style="width:352px;height:auto" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/10/image-4.png 632w, https://tech.nkhn37.net/wp-content/uploads/2022/10/image-4-300x123.png 300w" sizes="(max-width: 632px) 100vw, 632px" /></figure>
</div>


<p>DataFrameのデータに対して<span class="marker"><strong><code>pivot_table</code></strong></span>を使ってピボットテーブルを作るには以下のようにします。</p>



<p><strong>【sample.csv】</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">no,product_code,client,date,price
1,A,顧客1,2022/03/01,1000
2,A,顧客2,2022/03/01,1000
3,B,顧客1,2022/03/01,500
4,B,顧客1,2022/03/01,500
5,C,顧客1,2022/03/01,2000
6,A,顧客2,2022/03/15,1000
7,A,顧客2,2022/03/15,1000
8,C,顧客3,2022/03/15,2000
9,B,顧客2,2022/03/31,500
10,B,顧客2,2022/03/31,500
11,B,顧客2,2022/03/31,500
12,A,顧客1,2022/04/01,1000
13,A,顧客1,2022/04/01,1000
14,B,顧客1,2022/04/01,500
15,C,顧客1,2022/04/10,2000
16,C,顧客3,2022/04/10,2000
17,C,顧客3,2022/04/10,2000
18,A,顧客1,2022/04/30,1000
19,A,顧客2,2022/04/30,1000
20,B,顧客1,2022/04/30,500</pre>



<p><strong>【pivot_tableの使用方法】</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

# ===== サンプルデータの読み込み
df = pd.read_csv('sample.csv')
# print(df)
# print(df.dtypes)

# ===== データ加工
# 日付列をdatetimeに変更
df['date'] = pd.to_datetime(df['date'])
# 年・月・日の列を作成
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day'] = df['date'].dt.day

# ===== pivot_table
pt = df.pivot_table('price',
                    index='product_code',
                    columns='month',
                    aggfunc='sum')
print(pt)</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
month            3     4
product_code            
A             4000  4000
B             2500  1000
C             4000  6000</pre>



<p>サンプルデータ読込ではpandasの<code>read_csv</code>関数を使用しています。データの内容を確認したい場合は、コメントアウトしているprintのコメントを外して確認してみてください。</p>



<p>年月日の情報を使用したいため、日付列を<code>to_datetime</code>関数で変換した後に「年(<code>"year"</code>)」「月(<code>"month"</code>)」「日(<code>"day"</code>)」に該当する列情報を事前に作成しています。</p>



<p>ピボットテーブルを作るために<code>pivot_table</code>を使用している部分は以下の部分です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== pivot_table
pt = df.pivot_table('price',
                    index='product_code',
                    columns='month',
                    aggfunc='sum')</pre>



<p>まずは集約する価格(<code>"price"</code>）を指定します。次にインデックス(<code>index=</code>)で製品コード(<code>"product_code"</code>)、列(<code>columns=</code>)で月(<code>"month"</code>)を順に指定しています。これによりピボットテーブルにおける行方向と列方向の種類が決まります。</p>



<p>次に指定している集約関数(<code>aggfunc=</code>)では、集約するときに使用する関数を指定します。今回は合計するための<code>"sum"</code>を指定しています。<code>aggfunc</code>のデフォルト設定は平均(<code>"mean"</code>)になっていますので<code>aggfunc</code>を指定しない場合には平均が計算されます。<code>aggfunc</code>には他にも<code>"count"</code>、<code>"min"</code>、<code>"max"</code>などが指定できます。</p>



<p>上記のように<code>pivot_table</code>を使用することで簡単にピボットテーブルを作成することが可能です。</p>



<h3 class="wp-block-heading jinr-heading d--bold">多重ピボットテーブル（複数レベルの指定）</h3>



<p>上記ではシンプルなピボットテーブルの例を見てきました。今度は、複数レベルを指定して多重のピボットテーブルを作る例を見てみましょう。</p>



<p>具体的には、以下のように行方向は「製品コード(<code>"product_code"</code>)」「顧客(<code>"client"</code>)」の順の階層で、列方向は「年(<code>"year"</code>)」「月(<code>"month"</code>)」「日(<code>"day"</code>)」の順の階層で価格の合計を整理してみます。</p>


<div class="wp-block-image is-resized">
<figure class="aligncenter size-full"><img decoding="async" width="952" height="442" src="https://tech.nkhn37.net/wp-content/uploads/2022/10/image-5.png" alt="ピボットテーブル (pivot_table) 例" class="wp-image-5380" style="width:496px;height:auto" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/10/image-5.png 952w, https://tech.nkhn37.net/wp-content/uploads/2022/10/image-5-300x139.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/10/image-5-768x357.png 768w" sizes="(max-width: 952px) 100vw, 952px" /></figure>
</div>


<p>複数レベルを指定して<code>pivot_table</code>を使った多重ピボットテーブルを作るには以下のようにします。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

# ===== サンプルデータの読み込み
df = pd.read_csv('sample.csv')
# print(df)
# print(df.dtypes)

# ===== データ加工
# 日付列をdatetimeに変更
df['date'] = pd.to_datetime(df['date'])
# 年・月・日の列を作成
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day'] = df['date'].dt.day

# ===== pivot_table（複数レベルでの指定）
pt = df.pivot_table('price',
                    index=['product_code', 'client'],
                    columns=['year', 'month', 'day'],
                    aggfunc='sum')
# NaN部分を0で埋めて表示
print(pt.fillna(0))</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
year                   2022                                        
month                     3                       4                
day                      1       15      31      1       10      30
product_code client                                                
A            顧客1     1000.0     0.0     0.0  2000.0     0.0  1000.0
             顧客2     1000.0  2000.0     0.0     0.0     0.0  1000.0
B            顧客1     1000.0     0.0     0.0   500.0     0.0   500.0
             顧客2        0.0     0.0  1500.0     0.0     0.0     0.0
C            顧客1     2000.0     0.0     0.0     0.0  2000.0     0.0
             顧客3        0.0  2000.0     0.0     0.0  4000.0     0.0</pre>



<p>データ加工で年・月・日等の列を事前に用意しているところは、先ほど紹介の例と同様です。ピボットテーブルを作るために<code>pivot_table</code>を使用している部分は以下の部分になります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># ===== pivot_table（複数レベルでの指定）
pt = df.pivot_table('price',
                    index=['product_code', 'client'],
                    columns=['year', 'month', 'day'],
                    aggfunc='sum')</pre>



<p>基本的な使い方は先ほどの例と同様ですが、異なるのは<code>index=</code>と<code>columns=</code>で各階層になる列名をリストで順に指定している部分です。</p>



<p>このように<code>pivot_table</code>の引数の指定方法を少し変えるだけで、複数レベルの階層で集約したピボットテーブルも簡単に作ることが可能です。</p>



<h2 class="wp-block-heading jinr-heading d--bold">[参考] groupbyでピボットテーブルを作成する方法</h2>



<p><code>pivot_table</code>の使用方法について紹介しました。ピボットテーブルは集約の考え方を使っているため<span class="marker"><strong><code>groupby</code></strong></span>を使用してピボットテーブルを実現することももちろん可能です。</p>



<p><code>groupby</code>の基本的な使い方については「<a href="https://tech.nkhn37.net/pandas-groupby-aggregation/" target="_blank" rel="noreferrer noopener">DataFrameをgroupbyでグループ化して集約する方法</a>」でまとめていますので参考にしてください。</p>



<p>ピボットテーブルは、<code>groupby</code>での集計の多次元集計版ともいえる方法なので<code>groupby</code>で実現できます。これまでに<code>pivot_table</code>にて実現した処理と同じ動作をする<code>groupby</code>での実装例は以下のようになります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

# ===== サンプルデータの読み込み
df = pd.read_csv('sample.csv')
# print(df)
# print(df.dtypes)

# ===== データ加工
# 日付列をdatetimeに変更
df['date'] = pd.to_datetime(df['date'])
# 年・月・日の列を作成
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day'] = df['date'].dt.day

# マニュアルでpivot_tableを作成
print(df.groupby(['product_code', 'month'])['price'].sum().unstack())</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
month            3     4
product_code            
A             4000  4000
B             2500  1000
C             4000  6000</pre>



<p>ピボットテーブルを作るために<code>groupby</code>を使った加工をしているのは以下の部分になります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># マニュアルでpivot_tableを作成
print(df.groupby(['product_code', 'month'])['price'].sum().unstack())</pre>



<p>この部分では、<code>groupby</code>でまず製品コード(<code>"product_code"</code>)と月(<code>"month"</code>)を指定してグループを作成し、グループの中から価格(<code>"price"</code>)列に対して<code>sum()</code>による合計を出しています。<code>sum()</code>までのコードでは以下のDataFrameが出来上がっています。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">product_code  month
A             3        4000
              4        4000
B             3        2500
              4        1000
C             3        4000
              4        6000</pre>



<p>このDataFrameに対して<code>unstack()</code>により<code>month</code>列の部分を列方向に展開することでピボットテーブルの結果と同じような結果を取得しています。1行で書いてしまうと途中の処理が分からないという方は途中までで<code>print</code>表示しつつ確認してみると分かりやすいでしょう。</p>



<p>このように<code>groupby</code>を使ってもピボットテーブルは作成可能です。ただし、コードは少し読みにくく、直感的には何をしているか分かりにくいと感じられるかなと思います。<code>pivot_table</code>を使用する方が簡潔に処理を記載できるので<code>pivot_table</code>の使い方は是非覚えていただけるとよいかと思います。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>pandasの<span class="marker"><strong>DataFrameで<code>pivot_table</code>を使ってピボットテーブルを扱う方法</strong></span>について解説しました。</p>



<p>表形式のデータを扱う際に良く行われる操作としてピボットテーブルを使うとで他の分類や集約した状況を視覚的に確認することができます。pandasでは、<code>pivot_table</code>で簡単に作成できますので、例を使って紹介しました。</p>



<p>また、groupbyを使ってもピボットテーブルを作成できるものの、pivot_tableの方がより簡単にピボットテーブルが作成できることを見ていただきました。</p>



<p>ピボットテーブルはデータの状況を確認、分析する際によく使用するツールです。pandasでも簡単に作成できますので、是非使い方を覚えてもらえればと思います。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>pivot_table</code> の公式ドキュメントは<a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.pivot_table.html" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。</p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/pandas/dataframe-pivot-table" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://tech.nkhn37.net/python-tech-summary-page/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://tech.nkhn37.net/wp-content/uploads/2024/08/Python-Tech-Pythonプログラミングガイド_new1-640x360.jpg" alt="【Python Tech】プログラミングガイド" /></div><div class="a--blogcard-title d--bold">【Python Tech】プログラミングガイド</div></a></section>

]]></content:encoded>
					
					<wfw:commentRss>https://tech.nkhn37.net/pandas-dataframe-pivot-table/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【pandas】DataFrameをgroupbyでグループ化して集約する方法</title>
		<link>https://tech.nkhn37.net/pandas-groupby-aggregation/</link>
					<comments>https://tech.nkhn37.net/pandas-groupby-aggregation/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Mon, 14 Mar 2022 08:00:00 +0000</pubDate>
				<category><![CDATA[pandas]]></category>
		<category><![CDATA[DataFrameGroupBy]]></category>
		<category><![CDATA[describe]]></category>
		<category><![CDATA[groupby]]></category>
		<category><![CDATA[pivot_table]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=3091</guid>

					<description><![CDATA[pandasのDataFrameでgroupbyを使うことでグループ化して集約する方法について解説します。 groupbyによる集約 pandasのDataFrameでデータ分析をする際には、合計や平均等の集約処理をする [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>pandasのDataFrameで<span class="marker"><strong><code>groupby</code></strong></span>を使うことでグループ化して集約する方法について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">groupbyによる集約</h2>



<p>pandasのDataFrameでデータ分析をする際には、合計や平均等の集約処理をすることがよくあります。データの集約の際には、単純にDataFrame全体に対して集約処理をするだけでなく、ある意味を持ったグループ単位で集約処理をすることでデータに対する有益な情報を得ることができます。</p>



<p>SQLを少し学んだことがある人であれば「<span class="marker"><strong><code>groupby</code></strong></span>」がすぐに頭に浮かぶと思いますが、pandasのDataFrameでも同様に<code>groupby</code>による集約処理が可能です。本記事では、pandasのDataFrameを<code>groupby</code>でグループ化して集約する方法について基本的な方法を紹介します。</p>



<p>以降では、以下の簡単なデータを用いてpandasのDataFrameでどのように<code>groupby</code>による集約ができるのかを説明していきます。</p>


<div class="wp-block-image is-resized">
<figure class="aligncenter size-medium"><img decoding="async" width="300" height="217" src="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-21-300x217.png" alt="pandas DataFrame groupby サンプルデータ" class="wp-image-3097" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-21-300x217.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-21-768x554.png 768w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-21.png 877w" sizes="(max-width: 300px) 100vw, 300px" /></figure>
</div>


<p>上記データのイメージは、製造業で各シリアルナンバーごとに蓄積されている品質データです。データとしては、各シリアル(<code>serial_no</code>)に対して、品質項目１(<code>quality_val1</code>)と品質項目２(<code>quality_val2</code>)の値を持っているような表です。</p>



<p>品目(<code>item_code</code>)は各製品の種類を表すような区分になりますが、今回はこの品目(<code>item_code</code>)をキーにしてグループ化し、各品質データを集約をするということを考えてみようと思います。</p>



<h3 class="wp-block-heading jinr-heading d--bold">groupbyの集約の考え方<br>「分割(split) &#8211; 適用(apply) &#8211; 結合(combine)」</h3>



<p><code>groupby</code>による集約では「<span class="marker"><strong>分割(split) &#8211; 適用(apply) &#8211; 結合(combine)</strong></span>」に分けて処理がされているということを理解してほしいと思います。以下の図を見てみてください。</p>



<p>この例は今回のサンプルデータに対して<code>item_code</code>をキーとして<code>groupby</code>する際の処理の適用イメージです。</p>


<div class="wp-block-image is-resized">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="608" src="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-22-1024x608.png" alt="pandas DataFrame groupby 分割(split) - 適用(apply) - 結合(combine) 考え方" class="wp-image-3099" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-22-1024x608.png 1024w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-22-300x178.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-22-768x456.png 768w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-22.png 1472w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p><code>groupby</code>での処理は大きく以下のような手順で実行されています。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ol class="wp-block-list jinr-list">
<li>分割(split)：指定したキー(上記例では<code>item_code</code>)に応じてDataFrameを分割してグループを作ります。</li>



<li>適用(apply)：各グループのデータ(上記例では<code>quality_val1</code>)に対して集約処理を実施します。この例では合計(<code>sum</code>)の例を示していますが、他の集約処理でも同様です。</li>



<li>結合(combine)：各グループの処理結果を結合して、集約結果を完成させます。</li>
</ol>
</div></div></section>



<p>上記のような図をイメージしてもらいつつ、以降の具体例を見ていくと、データ処理をイメージしやすいかと思います。では、pandasの<code>groupby</code>を使って集約処理を具体的にどのようにコーディングするか、例を使って見ていきましょう。</p>



<h2 class="wp-block-heading jinr-heading d--bold">groupbyによるDataFrameの集約</h2>



<h3 class="wp-block-heading jinr-heading d--bold">groupbyによるDataFrameの集約の基本的な使い方</h3>



<p><span class="marker"><strong><code>groupby</code></strong></span>によるDataFrameの集約の基本的な使い方は以下のようになります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

quality_result = pd.DataFrame(
    {'serial_no': ['S001', 'S002', 'S003', 'S004', 'S005',
                   'S006', 'S007', 'S008', 'S009', 'S010'],
     'item_code': ['A', 'A', 'B', 'B', 'C', 'A', 'A', 'B', 'C', 'C'],
     'quality_val1': [100, 150, 20, 10, 50, 120, 80, 5, 55, 40],
     'quality_val2': [1, 2, 100, 120, 20, 5, 7, 90, 10, 10]}
)
print(quality_result, '\n')

# item_codeでグループ化
gr = quality_result.groupby('item_code')
print(gr, '\n')

# グループごとに集約を計算
# print(quality_result.groupby('item_code').sum())
print(gr.sum())</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
  serial_no item_code  quality_val1  quality_val2
0      S001         A           100             1
1      S002         A           150             2
2      S003         B            20           100
3      S004         B            10           120
4      S005         C            50            20
5      S006         A           120             5
6      S007         A            80             7
7      S008         B             5            90
8      S009         C            55            10
9      S010         C            40            10 

&lt;pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001A31B0E3EE0> 

           quality_val1  quality_val2
item_code                            
A                   450            15
B                    35           310
C                   145            40</pre>



<p>対象となるDataFrameの<code>groupby</code>メソッドにキーとなる列名を与えることで、<span class="marker"><strong><code>DataFrameGroupBy</code></strong></span>オブジェクト(<code>pandas.core.groupby.generic.DataFrameGroupBy</code>)が生成されます。今回の例では、<code>item_code</code>を集約のキーとして与えています。</p>



<p>この<code>DataFrameGroupBy</code>オブジェクトは分割(split)の処理までがされているものになっているので、当該<code>DataFrameGroupBy</code>オブジェクトに対して集約メソッドを実行することで後続の適用(apply)、結合(coｍbine)が処理され、グループ単位の集約処理が実行できます。</p>



<p>上記例では一度分割までされている情報を<code>gr</code>という変数に入れ、合計の<code>sum</code>を呼び出しています。もちろん、<code>quality_result.groupby('item_code').sum()</code>というように一行で書いても問題ありませんが、<code>DataFrameGroupBy</code>をオブジェクト化して用意しておけば、<code>sum()</code>以外にも<code>max()</code>等のような他の集約関数を必要に応じて呼び出すことが可能です。</p>



<h3 class="wp-block-heading jinr-heading d--bold">列名を指定して集約する方法</h3>



<p>上記例では、対象となるDataFrame全体に対して処理をしたため、集約メソッドが適用できる列が複数ある場合にはすべての列に対して処理が行われます。今回の例でいうと「<code>quality_val1</code>」「<code>quality_val2</code>」の両方に<code>sum</code>が適用されました。</p>



<p>しかし、実際には<code>quality_val1</code>の結果のみ必要な場合もあると思います。そのような時に<code>groupby</code>オブジェクトは、列インデックスの要領で対象を絞り込んで集約することができます。以下の例で見てみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

quality_result = pd.DataFrame(
    {'serial_no': ['S001', 'S002', 'S003', 'S004', 'S005',
                   'S006', 'S007', 'S008', 'S009', 'S010'],
     'item_code': ['A', 'A', 'B', 'B', 'C', 'A', 'A', 'B', 'C', 'C'],
     'quality_val1': [100, 150, 20, 10, 50, 120, 80, 5, 55, 40],
     'quality_val2': [1, 2, 100, 120, 20, 5, 7, 90, 10, 10]}
)
print(quality_result, '\n')

# 列を指定して集約する
print(quality_result.groupby('item_code')['quality_val1'].sum())</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
  serial_no item_code  quality_val1  quality_val2
0      S001         A           100             1
1      S002         A           150             2
2      S003         B            20           100
3      S004         B            10           120
4      S005         C            50            20
5      S006         A           120             5
6      S007         A            80             7
7      S008         B             5            90
8      S009         C            55            10
9      S010         C            40            10 

item_code
A    450
B     35
C    145
Name: quality_val1, dtype: int64</pre>



<p>上記のように<code>[]</code>で対象となる列名を指定することで対象列を絞って集約メソッドの実行ができます。上記例では、<code>quarlity_val1</code>を指定することで結果としては<code>quality_val1</code>のみの<code>sum()</code>による集約結果が得られています。</p>



<p>上記結果では、1列だけ取得してきているのでpandasのSeriesオブジェクトになっています。</p>



<h3 class="wp-block-heading jinr-heading d--bold">グループごとに繰り返し処理をする方法</h3>



<p><code>DataFrameGroupBy</code>オブジェクトはグループに対する反復をサポートしているため、以下のように<code>for</code>文でグループごとに繰り返し処理をすることができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

quality_result = pd.DataFrame(
    {'serial_no': ['S001', 'S002', 'S003', 'S004', 'S005',
                   'S006', 'S007', 'S008', 'S009', 'S010'],
     'item_code': ['A', 'A', 'B', 'B', 'C', 'A', 'A', 'B', 'C', 'C'],
     'quality_val1': [100, 150, 20, 10, 50, 120, 80, 5, 55, 40],
     'quality_val2': [1, 2, 100, 120, 20, 5, 7, 90, 10, 10]}
)
print(quality_result, '\n')

# グループごとに取り出して処理をする
for (item_code, group) in quality_result.groupby('item_code'):
    print(f'item_code: {item_code}')
    print(f'group_data:\n{group}')
    print(f"group['quality_val1'].sum() = {group['quality_val1'].sum()}", '\n')</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
  serial_no item_code  quality_val1  quality_val2
0      S001         A           100             1
1      S002         A           150             2
2      S003         B            20           100
3      S004         B            10           120
4      S005         C            50            20
5      S006         A           120             5
6      S007         A            80             7
7      S008         B             5            90
8      S009         C            55            10
9      S010         C            40            10 

item_code: A
group_data:
  serial_no item_code  quality_val1  quality_val2
0      S001         A           100             1
1      S002         A           150             2
5      S006         A           120             5
6      S007         A            80             7
group['quality_val1'].sum() = 450 

item_code: B
group_data:
  serial_no item_code  quality_val1  quality_val2
2      S003         B            20           100
3      S004         B            10           120
7      S008         B             5            90
group['quality_val1'].sum() = 35 

item_code: C
group_data:
  serial_no item_code  quality_val1  quality_val2
4      S005         C            50            20
8      S009         C            55            10
9      S010         C            40            10
group['quality_val1'].sum() = 145 </pre>



<p><code>for</code>文の<code>in</code>に<code>DataFrameGroupBy</code>オブジェクトを渡すと「キー」と「グループに該当するDataFrame」が返却されます。for文内当該繰り返しのグループに対するキーがitem_codeに、グループのDataFrameが<code>group</code>に入ります。</p>



<p>上記の例では、返却されてきたグループのDataFrameに対して、集約関数の<code>sum()</code>を適用することで合計をとっています。このようにグループごとに処理をしたい場合にも<code>groupby</code>は便利に扱うことができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">集約メソッド</h3>



<h4 class="wp-block-heading jinr-heading d--bold">いろいろな集約メソッド</h4>



<p>上記の例では、集約処理のメソッドとして<code>sum()</code>を使った例で<code>groupby</code>の使い方を紹介してきました。pandasでは、多くの便利な集約メソッドが用意されています。集約メソッドの中には以下のようなものがあります。必要に応じて選択して使用してください。</p>



<figure class="wp-block-table"><table><thead><tr><th>集約メソッド</th><th>概要説明</th></tr></thead><tbody><tr><td><code>describe()</code></td><td>データの統計情報をまとめて計算する。<br>（<code>count</code>, <code>mean</code>, <code>std</code>, <code>min</code>, <code>25%</code>, <code>50%</code>, <code>75%</code>, <code>max</code>）</td></tr><tr><td><code>sum()</code></td><td>合計を計算する。</td></tr><tr><td><code>count()</code></td><td>要素数を計算する。</td></tr><tr><td><code>mean()</code></td><td>平均値を計算する。</td></tr><tr><td><code>median()</code></td><td>中央値を計算する。</td></tr><tr><td><code>std()</code></td><td>標準偏差を計算する。</td></tr><tr><td><code>var()</code></td><td>分散を計算する。</td></tr><tr><td><code>min()</code></td><td>最小値を計算する。</td></tr><tr><td><code>max()</code></td><td>最大値を計算する。</td></tr><tr><td><code>first()</code></td><td>最初の要素を計算する。</td></tr><tr><td><code>last()</code></td><td>最後の要素を計算する。</td></tr></tbody></table></figure>



<h4 class="wp-block-heading jinr-heading d--bold">便利な集約メソッド describe</h4>



<p>いろいろな集約メソッドということで表で紹介しましたが、その中でも便利な集約メソッドとして<span class="marker"><strong><code>describe</code></strong></span>メソッドを実際の例で紹介します。<code>describe</code>メソッドは他の集約メソッドと使い方は同様で以下のように使用することができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

quality_result = pd.DataFrame(
    {'serial_no': ['S001', 'S002', 'S003', 'S004', 'S005',
                   'S006', 'S007', 'S008', 'S009', 'S010'],
     'item_code': ['A', 'A', 'B', 'B', 'C', 'A', 'A', 'B', 'C', 'C'],
     'quality_val1': [100, 150, 20, 10, 50, 120, 80, 5, 55, 40],
     'quality_val2': [1, 2, 100, 120, 20, 5, 7, 90, 10, 10]}
)
print(quality_result, '\n')

# describeメソッド
print(quality_result.groupby('item_code')['quality_val1'].describe())</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
  serial_no item_code  quality_val1  quality_val2
0      S001         A           100             1
1      S002         A           150             2
2      S003         B            20           100
3      S004         B            10           120
4      S005         C            50            20
5      S006         A           120             5
6      S007         A            80             7
7      S008         B             5            90
8      S009         C            55            10
9      S010         C            40            10 

           count        mean        std   min   25%    50%    75%    max
item_code                                                               
A            4.0  112.500000  29.860788  80.0  95.0  110.0  127.5  150.0
B            3.0   11.666667   7.637626   5.0   7.5   10.0   15.0   20.0
C            3.0   48.333333   7.637626  40.0  45.0   50.0   52.5   55.0</pre>



<p>上記例で見ると分かるように、<code>describ</code>eメソッドは<code>count</code>, <code>mean</code>, <code>std</code>, <code>min</code>, <code>25%</code>, <code>50%</code>, <code>75%</code>, <code>max</code>というようにデータの特徴を見る際によく確認する項目をまとめて集計してくれます。</p>



<p>まずは、<code>describe</code>を対象データに対して使ってみるだけで、手軽にデータの特徴を確認することができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">ピボットテーブルの作成</h3>



<p>データをグループ化した使う方法としては、ピボットテーブルもあります。ピボットテーブルは、<code>groupby</code>を用いることで作成可能ですが、pandasでは、<code>pivot_table</code>メソッドが用意されていて簡単に作成できます。</p>



<p>ピボットテーブルについては「<a href="https://tech.nkhn37.net/pandas-dataframe-pivot-table/" target="_blank" rel="noreferrer noopener">DataFrameのpivot_tableでピボットテーブルを扱う</a>」でまとめていますので参考にしてください。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>pandasのDataFrameで<span class="marker"><strong><code>groupby</code></strong></span>を使うことでグループ化して集約する方法について解説しました。</p>



<p>集約処理（合計、平均等）の際には、ある区分ごとのグループ単位で集約処理をしたくなりますが、<code>groupby</code>を使うことで簡単に実現が可能です。本記事では、まず集約処理の考え方を説明して、基本的な<code>groupby</code>の使い方を紹介しました。</p>



<p>集約処理は、データ分析で非常に重要な処理の一つです。是非<code>groupby</code>をうまく使いこなしてほしいと思います。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>pandas.DataFrame.groupby</code> の公式ドキュメントは<a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html#pandas-dataframe-groupby" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。</p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/pandas/dataframe-groupby" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://tech.nkhn37.net/python-tech-summary-page/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://tech.nkhn37.net/wp-content/uploads/2024/08/Python-Tech-Pythonプログラミングガイド_new1-640x360.jpg" alt="【Python Tech】プログラミングガイド" /></div><div class="a--blogcard-title d--bold">【Python Tech】プログラミングガイド</div></a></section>

]]></content:encoded>
					
					<wfw:commentRss>https://tech.nkhn37.net/pandas-groupby-aggregation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【pandas】DataFrameのデータ選択方法 ~loc, iloc, at, iat 等~</title>
		<link>https://tech.nkhn37.net/pandas-dataframe-data-selection/</link>
					<comments>https://tech.nkhn37.net/pandas-dataframe-data-selection/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Wed, 16 Feb 2022 20:00:00 +0000</pubDate>
				<category><![CDATA[pandas]]></category>
		<category><![CDATA[at]]></category>
		<category><![CDATA[groupby]]></category>
		<category><![CDATA[iat]]></category>
		<category><![CDATA[iloc]]></category>
		<category><![CDATA[loc]]></category>
		<category><![CDATA[pivot_table]]></category>
		<category><![CDATA[query]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=2770</guid>

					<description><![CDATA[pandasのDataFrameのデータ選択方法について解説します。 DataFrameのデータ選択方法 pandasを利用する際にとても重要になってくるのがDataFrameの扱いです。本記事ではDataFrameから [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>pandasの<span class="marker"><strong>DataFrameのデータ選択方法</strong></span>について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold" id="dataframeのデータ選択方法">DataFrameのデータ選択方法</h2>



<p>pandasを利用する際にとても重要になってくるのがDataFrameの扱いです。本記事ではDataFrameから必要なデータを選択する方法の基本について説明します。</p>



<p>DataFrameのデータ選択方法として是非覚えておいて欲しいのは後述する<span class="marker"><strong><code>loc</code></strong></span>, <span class="marker"><strong><code>iloc</code></strong></span>, <span class="marker"><strong><code>at</code></strong></span>, <span class="marker"><strong><code>iat</code></strong></span>といったデータ選択方法です。しかし、それらメソッドを使用しないデータアクセス方法も色々とあります。</p>



<p>本記事では、まずはDataFrameとしてのデータ選択方法を概観します。その後に<code>loc</code>, <code>iloc</code>, <code>at</code>, <code>iat</code>といった重要なメソッドを使ったDataFrameのデータ選択方法を紹介していきます。<code>loc</code>, <code>iloc</code>, <code>at</code>, <code>iat</code>の使い方を確認したい場合は、その他の方法は読み飛ばしていただいても構いません。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="列名を指定して特定の列を取得する方法">列名を指定して特定の列を取得する方法</h3>



<h4 class="wp-block-heading jinr-heading d--bold" id="基本的な使用方法">基本的な使用方法</h4>



<p>DataFrameで、列名を指定して特定の列を取得する場合には以下のように使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2})
print(df, "\n")

# 列名を指定して特定の列情報を取得する（辞書のようにアクセス）
print(df["attr1"], "\n")
# 列名を変数のようにして読み込むことも可能
print(df.attr1)</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2
A     10     60
B     20     70
C     30     80
D     40     90
E     50    100 

A    10
B    20
C    30
D    40
E    50
Name: attr1, dtype: int64 

A    10
B    20
C    30
D    40
E    50
Name: attr1, dtype: int64</pre>



<p>使い方は、Python辞書のキーを指定してアクセスする方法と同様で<code>df['列名']</code>とすることで特定列を取得できます。また、列名を変数名のように「<code>df.列名</code>」としてアクセスすることも可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold" id="注意事項-列名とメソッド名の重複に注意">注意事項：列名とメソッド名が同じ場合に注意</h4>



<p>列名を変数名のように「<code>df.列名</code>」としてアクセスする場合には注意事項があります。<span class="marker"><strong>DataFrameのメソッド名と同じ列名を使ってしまうと取得できるデータは想定のものになりません。</strong></span>メソッド名と列名が同じになっているような列がないか注意しましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "pop": attr2})
print(df, "\n")

# メソッド名と重なる場合、辞書形式の取得と属性名での取得は一致しない
print(f"df.pop: \n{df.pop}\n")
print(f"df['pop']: \n{df['pop']}\n")
print(df.pop is df["pop"])</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  pop
A     10   60
B     20   70
C     30   80
D     40   90
E     50  100 

df.pop: 
&lt;bound method DataFrame.pop of    attr1  pop
A     10   60
B     20   70
C     30   80
D     40   90
E     50  100>

df['pop']: 
A     60
B     70
C     80
D     90
E    100
Name: pop, dtype: int64

False</pre>



<p>上記例では、データが「<code>pop</code>」という列を持っています。しかし、DataFrameのメソッドに<code>pop</code>メソッドがあるため、<code>df.pop</code>として取得できるものは<code>df['pop']</code>として取得できるものとは異なります。<code>is</code>を使って確認を取っていますが<code>False</code>で一致しません。</p>



<p>このように、DataFrameのメソッドと列名が同じ場合だと想定外の結果となることもあるので注意して使用するようにしてください。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="特定の列情報を任意の順序に並べたデータを取得する方法">特定の列情報を任意順序に並べたデータを取得する方法</h3>



<p>DataFrameの列の順序を任意に並べ替えたい場合には、以下のように列名を並べて取得します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2})
print(df, "\n")

# 特定の列名を指定し、任意順序で並べ替えてデータを取得する（同じ列の複製も可能）
print(df[["attr2", "attr1", "attr1", "attr2"]])</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2
A     10     60
B     20     70
C     30     80
D     40     90
E     50    100 

   attr2  attr1  attr1  attr2
A     60     10     10     60
B     70     20     20     70
C     80     30     30     80
D     90     40     40     90
E    100     50     50    100</pre>



<p>上記例では、列の順序を表すようなリストを<code>[]</code>の中に渡すことで、指定した列順序で並び替えています。また、<code>attr1</code>, <code>attr2</code>を複数回指定していますが、列が複製されていることが分かるかと思います。このように、同一の列名を複数回リストに指定すれば、列データを複製するようなことが可能になります。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="既存の列を用いて計算した結果の列を作成する方法">既存の列を用いて計算した結果列を作成する方法</h3>



<p>DataFrameの既存の列を用いて計算した結果で新しい列を作成したくなる場合がよくあります。以下例のように、既存の列を用いて計算したうえで新しく結果列を作ることができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2})
print(df, "\n")

# 既存の列から計算して新しい列を作成する
df["sum"] = df["attr1"] + df["attr2"]
print(df)</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2
A     10     60
B     20     70
C     30     80
D     40     90
E     50    100 

   attr1  attr2  sum
A     10     60   70
B     20     70   90
C     30     80  110
D     40     90  130
E     50    100  150</pre>



<p><code>df['sum']</code>は元々のデータには存在していないですが、上記例のように足し算の計算式を指定することで新しい<code>'sum'</code>という列を作成することができます。上記例は、足し算「<code>+</code>」ですが、その他の演算や関数等を使って新しい列を作ることももちろん可能です。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="スライスで特定のキーを持つ行を選択する方法-1">スライスで特定のキーを持つ行を選択する方法</h3>



<p>DataFrameの特定のキーを持つ行を選択する場合にはスライスが使用できます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2})
print(df, "\n")

# ===== スライスで特定のキーを持つ行を選択する
# 明示的なインデックスを使用する場合
print(df["B":"D"], "\n")
# 暗黙的なインデックスを使用する場合
print(df[1:3])</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2
A     10     60
B     20     70
C     30     80
D     40     90
E     50    100 

   attr1  attr2
B     20     70
C     30     80
D     40     90 

   attr1  attr2
B     20     70
C     30     80</pre>



<p><code>[]</code>の中にキーとなるインデックスをスライスで指定すると該当する行を選択できます。pandasのDataFrameやSeriesでは、インデックスには明示的なインデックスと暗黙的なインデックスがあります。</p>



<p>明示的なインデックスは「<code>index=</code>」で指定しているインデックスです。一方、暗黙的なインデックスは表面上は見えていませんが<code>0～</code>の数値で振られているインデックスです。例えば上記の例でいえば、明示的なインデックス「<code>'A'</code>」に相当する暗黙的なインデックスは「<code>0</code>」となります。</p>



<p>注意が必要なのは、明示的なインデックスのスライスでは終わりを含みますが、暗黙的なインデックスのスライスでは終わりを含まないことです。上記例でいうと、<code>['B':'D']</code>という指定であれば<code>'D'</code>に該当する行を含みますが、<code>[1:3]</code>とすると<code>3</code>に該当する行は含まれません。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="マスキングで特定の条件に一致する行を選択する方法">特定条件に一致する行を選択する方法</h3>



<h4 class="wp-block-heading jinr-heading d--bold">マスキングによるデータ選択</h4>



<p>DataFrameの中から特定条件に一致する行を選択するには、以下の例のようにマスキングすることができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2})
print(df, "\n")

# 特定の条件に一致する行を選択する
print(df[(df["attr1"] > 10) &amp; (df["attr2"] &lt; 100)])</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2
A     10     60
B     20     70
C     30     80
D     40     90
E     50    100 

   attr1  attr2
B     20     70
C     30     80
D     40     90</pre>



<p>上記例では「<code>attr1</code>列の値が<code>10</code>より大きい」かつ「<code>attr2</code>列の値が<code>100</code>より小さい」に該当する行が選択されます。<code>df['attr1'] &gt; 10</code>といった部分は該当する行が<code>True</code>となるような<code>bool</code>型になります。<code>df['attr2'] &lt; 100</code>についても同様の考え方です。</p>



<p>選択対象とする行が<code>True</code>となる<code>bool</code>値をDataFrameの<code>[]</code>内に指定することで該当する行だけマスキングすることができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">queryを用いた条件指定によるデータ選択</h4>



<p>特定条件に一致する行を選択する方法として、<span class="marker"><strong><code>query</code></strong></span>メソッドを使用した方法もあります。<code>query</code>は、以下の例のように使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2})
print(df, "\n")

# queryを用いて条件に一致する行を選択する
# ※ 内部的に文字列評価を行うためパフォーマンスに影響ある場合があることに注意
print(df.query("attr1 > 10 and attr2 &lt; 100"), "\n")

# 変数を使ったクエリの記載も可能
threshold1 = 20
threshold2 = 90
print(df.query("attr1 >= @threshold1 and attr2 &lt; @threshold2"))</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2
A     10     60
B     20     70
C     30     80
D     40     90
E     50    100 

   attr1  attr2
B     20     70
C     30     80
D     40     90 

   attr1  attr2
B     20     70
C     30     80</pre>



<p><code>query</code>を使用する場合には、上記例のようにデータを取得するための条件となるクエリ文字列で指定します。また、<code>threshold1</code>や<code>threshold2</code>のようにプログラム中で作成した変数をクエリに含めたい場合には、<code>@</code>を文字列内で使用することで該当箇所に埋め込んでデータ選択をすることも可能です。</p>



<p><code>query</code>は、条件式を文字列で直接記載するので複雑な条件を直感的に読みやすいというメリットがあります。ただし、<code>query</code>では内部的に文字列を評価して処理を実行するため、巨大なデータフレームを扱う場合などではパフォーマンス上で影響があるかもしれないので注意が必要です。</p>



<p>また、すべての状況で<code>query</code>が使用できるとは限りませんので実行したいクエリを実行できるかはよく確認してもらえればと思います。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="任意の行-列の値を選択する方法-loc-iloc-at-iat">任意の行、列の値を選択する方法 ~loc, iloc, at, iat~</h3>



<p>DataFrameで任意の行や列の値を選択する方法は、<span class="marker"><strong><code>loc</code></strong></span>, <span class="marker"><strong><code>iloc</code></strong></span>, <span class="marker"><strong><code>at</code></strong></span>, <span class="marker"><strong><code>iat</code></strong></span>を使用することができます。これらのメソッドの使い方は是非覚えてください。</p>



<p>pandasのDataFrameやSeriesでは、インデックスには明示的なインデックスと暗黙的なインデックスがあります。明示的なインデックスは「<code>index=</code>」等で指定しているインデックスで、一方の暗黙的なインデックスは表面上は見えていませんが<code>0～</code>の数値で振られているインデックスです。</p>



<p>以降で説明する<code>loc</code>, <code>iloc</code>, <code>at</code>, <code>iat</code>に関して<span class="marker"><strong>「<code>i</code>」がついているものは暗黙的なインデックス</strong></span>を対象に、<span class="marker"><strong>「<code>i</code>」がついていないものは明示的なインデックス</strong></span>を対象にしてデータ選択するメソッドです。また、<code>iloc</code>は「integer-location」、<code>iat</code>は「integer-position」を意味します。</p>



<h4 class="wp-block-heading jinr-heading d--bold" id="特定位置の情報を選択する方法">特定位置の情報を選択する方法</h4>



<p>DataFrameにおける特定位置の値（例えば「2行1列の値」等）を選択する場合は、<code>loc</code>, <code>iloc</code>, <code>at</code>, <code>iat</code>を使用して以下の例のようにデータを選択ができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
attr3 = pd.Series([110, 120, 130, 140, 150], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2, "attr3": attr3})
print(df, "\n")

# 特定の位置を選択する
# 明示的なインデックスを使用する場合
print(df.loc["C", "attr2"], "\n")
# atを使っても同様のことができる
print(df.at["C", "attr2"], "\n")

# 暗黙的なインデックスを使用する場合
print(df.iloc[2, 1], "\n")
# iatを使っても同様のことができる
print(df.iat[2, 1])</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2  attr3
A     10     60    110
B     20     70    120
C     30     80    130
D     40     90    140
E     50    100    150 

80 

80 

80 

80</pre>



<p>上記例のように<code>[]</code>内に、<code>[行のインデックス, 列のインデックス]</code>という形で指定することで該当する特定位置の値を取得することができます。</p>



<p><code>loc</code>や<code>at</code>は明示的なインデックスを対象にし、<code>iloc</code>や<code>iat</code>は暗黙的なインデックスを対象にします。特定位置の値を選択する場合には、<code>loc</code>と<code>at</code>、<code>iloc</code>と<code>iat</code>については結果は同じです。<code>loc</code>や<code>iloc</code>は以降で説明するようなスライスでのデータ選択にも対応しているという点で<code>at</code>や<code>iat</code>とは異なります。</p>



<h4 class="wp-block-heading jinr-heading d--bold" id="スライスで任意の行-列を選択する方法">スライスで任意の行、列を選択する方法</h4>



<p>DataFrameにおける任意の行、列をスライスで選択する場合は、<code>loc</code>, <code>iloc</code>を使用して以下例のようにデータ選択ができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd

attr1 = pd.Series([10, 20, 30, 40, 50], index=["A", "B", "C", "D", "E"])
attr2 = pd.Series([60, 70, 80, 90, 100], index=["A", "B", "C", "D", "E"])
attr3 = pd.Series([110, 120, 130, 140, 150], index=["A", "B", "C", "D", "E"])
df = pd.DataFrame({"attr1": attr1, "attr2": attr2, "attr3": attr3})
print(df, "\n")

# 任意の行、列を選択する（スライスを使用する例）
# 明示的なインデックスを使用する場合
print(df.loc["B":"D", "attr2":"attr3"], "\n")
# 暗黙的なインデックスを使用する場合
print(df.iloc[1:3, 1:2])</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
   attr1  attr2  attr3
A     10     60    110
B     20     70    120
C     30     80    130
D     40     90    140
E     50    100    150 

   attr2  attr3
B     70    120
C     80    130
D     90    140 

   attr2
B     70
C     80</pre>



<p>上記例のように<code>[]</code>内に、<code>[行のスライス, 列のスライス]</code>という形で指定することで、指定した行の範囲、列の範囲に該当するデータを選択することができます。</p>



<p>ここで注意が必要なのは、明示的なインデックスでは終わりを含みますが、暗黙的なインデックスでは終わりを含まないことです。上記例の行スライスでいうと、例えば「<code>'B':'D'</code>」という指定であれば「<code>'D'</code>」は含みますが、「<code>1:3</code>」とすると<code>3</code>は含まれません。列スライスについても同様です。</p>



<h3 class="wp-block-heading jinr-heading d--bold">データ集約やピボットテーブル</h3>



<p>上記までは、対象DataFrameから対象の行を抽出する例を中心に様々な方法を紹介してきました。データ分析を行う際には、データをグループ化して集約処理したり、ピボットテーブルを作成したくなることがよくあります。</p>



<p>集約処理は、あるグループに対して合計や平均などを計算する処理で、単純にDataFrame全体を集約をすればよいわけではなく、ある区分ごとのグループ単位で集約処理を実施することでデータ分析に非常に有益な情報が得られます。pandasでは<code>groupby</code>メソッドが用意されていて簡単に処理が可能です。<code>groupby</code>については「<a href="https://tech.nkhn37.net/pandas-groupby-aggregation/" target="_blank" rel="noreferrer noopener">DataFrameをgroupbyでグループ化して集約する方法</a>」でまとめていますので参考にしてください。</p>



<p>また、ピボットテーブルもグループごとの情報を確認するためによく使われるものです。ピボットテーブルは<code>groupby</code>を用いても実現できますが、pandasでは<code>pivot_table</code>メソッドが用意されていて簡単に対処できます。<code>pivot_table</code>については「<a href="https://tech.nkhn37.net/pandas-dataframe-pivot-table/" target="_blank" rel="noreferrer noopener">DataFrameのpivot_tableでピボットテーブルを扱う</a>」でまとめていますので参考にしてください。</p>



<p>まずは本記事で紹介したような基本的なデータ選択方法を理解してもらい、<code>groupby</code>や<code>pivot_table</code>といった少し高度なデータ処理ができるようになると良いかと思います。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>pandasの<span class="marker"><strong>DataFrameのデータ選択方法</strong></span>について解説しました。</p>



<p>DataFrameのデータ選択方法として是非覚えておいて欲しいのは<span class="marker"><strong><code>loc</code></strong></span>, <span class="marker"><strong><code>iloc</code></strong></span>, <span class="marker"><strong><code>at</code></strong></span>, <span class="marker"><strong><code>iat</code></strong></span>といったデータ選択方法です。しかし、それらメソッドを使用しないデータアクセス方法も色々とあります。列名を指定しての取得やスライス、マスキング等の方法を紹介しています。</p>



<p>pandasを利用する際にとても重要になってくるのがDataFrameの扱いになってきます。是非、各種方法について扱えるようにしてほしいと思います。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/pandas/dataframe-data-selection" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://tech.nkhn37.net/python-tech-summary-page/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://tech.nkhn37.net/wp-content/uploads/2024/08/Python-Tech-Pythonプログラミングガイド_new1-640x360.jpg" alt="【Python Tech】プログラミングガイド" /></div><div class="a--blogcard-title d--bold">【Python Tech】プログラミングガイド</div></a></section>

]]></content:encoded>
					
					<wfw:commentRss>https://tech.nkhn37.net/pandas-dataframe-data-selection/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Disk: Enhanced  を使用したページ キャッシュ

Served from: tech.nkhn37.net @ 2026-04-08 07:40:51 by W3 Total Cache
-->