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

<image>
	<url>https://tech.nkhn37.net/wp-content/uploads/2021/01/cropped-lion-normal-clear-1-32x32.png</url>
	<title>「join」タグの記事一覧Python Tech</title>
	<link>https://tech.nkhn37.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【PySpark】DataFrameを結合する方法 join</title>
		<link>https://tech.nkhn37.net/pyspark-dataframe-join/</link>
					<comments>https://tech.nkhn37.net/pyspark-dataframe-join/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Mon, 20 Nov 2023 20:00:00 +0000</pubDate>
				<category><![CDATA[PySpark]]></category>
		<category><![CDATA[broadcast hash join]]></category>
		<category><![CDATA[broadcast nested loop join]]></category>
		<category><![CDATA[cartesian join]]></category>
		<category><![CDATA[inner join]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[left outer join]]></category>
		<category><![CDATA[outer join]]></category>
		<category><![CDATA[right outer join]]></category>
		<category><![CDATA[shuffle hash join]]></category>
		<category><![CDATA[sort merge join]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=9744</guid>

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



<h2 class="wp-block-heading jinr-heading d--bold">PySpark での DataFrame 結合</h2>



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



<p class="wp-block-paragraph">データを分析する際にはデータソースとして DB、Parquet、CSV などいろいろなデータソースからデータを取得して分析します。この際に、各データソースのデータを同じ意味を表すキー列をもとに結合してから分析することがほとんどです。これにより、より多角的な分析が可能になります。データ結合は、データ活用において非常に重要なデータ操作となります。</p>



<p class="wp-block-paragraph">PySpark では、DataFrame の結合方法として <span class="jinr-d--text-color d--marker1 d--bold"><code>join</code></span> メソッドが用意されています。この記事では、<code>join</code> メソッドの使い方の基本を紹介します。</p>



<p class="wp-block-paragraph">また、Spark は分散処理環境であるため結合アルゴリズムも複数あり、Spark が適切なアルゴリズムを選択します。どのアルゴリズムが選択されるかは Spark が決定しますが、どのような結合アルゴリズムがあるかを理解しておくことはパフォーマンスチューニングに役立ちます。後半では、Spark の結合アルゴリズムの種類についても概要を説明したいと思います。</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 class="wp-block-paragraph">実行環境は、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 class="wp-block-paragraph">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>



<h2 class="wp-block-heading jinr-heading d--bold"><code>join</code> を用いた DataFrame の結合</h2>



<p class="wp-block-paragraph">PySpark では、DataFrame の結合方法として <span class="jinr-d--text-color d--marker1 d--bold"><code>join</code></span> メソッドを使用します。以降では、<code>join</code> メソッドの使い方を例を使って紹介していきます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">使用する DataFrame の作成</h3>



<p class="wp-block-paragraph">結合操作の説明のための簡単な 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

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

data_a = [
    ("A001", 100),
    ("B001", 200),
    ("C001", 300),
    ("C002", 400),
    ("E001", 500),
]
df_a = spark.createDataFrame(data_a, ["id", "value1"])
df_a.printSchema()
df_a.show()

data_b = [
    ("B001", "aaa"),
    ("C001", "bbb"),
    ("D001", "ccc"),
    ("E002", "ddd"),
]
df_b = spark.createDataFrame(data_b, ["id", "value2"])
df_b.printSchema()
df_b.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
 |-- id: string (nullable = true)
 |-- value1: long (nullable = true)

+----+------+
|  id|value1|
+----+------+
|A001|   100|
|B001|   200|
|C001|   300|
|C002|   400|
|E001|   500|
+----+------+

root
 |-- id: string (nullable = true)
 |-- value2: string (nullable = true)

+----+------+
|  id|value2|
+----+------+
|B001|   aaa|
|C001|   bbb|
|D001|   ccc|
|E002|   ddd|
+----+------+</pre>



<p class="wp-block-paragraph">上記例では、<code>df_a</code>と<code>df_b</code>という2つのDataFrameを作成しています。共に<code>id</code>という列を持っているため、<code>id</code>列を使った結合をすることを以降で考えていきます。</p>



<p class="wp-block-paragraph">なお、処理を完了した後は <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 class="wp-block-paragraph">以降では、結合で代表的な内部結合 (Inner Join)、外部結合 (Outer Join) の各方法について上記データを用いた例で説明していきます。</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 class="wp-block-paragraph">DataFrameの作成に関する説明は省略しています。「<a href="https://tech.nkhn37.net/pyspark-dataframe-create-and-schema/" target="_blank" rel="noreferrer noopener">DataFrameの作成方法とスキーマ</a>」を参考にしてください。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">内部結合 (Inner Join)</h3>



<p class="wp-block-paragraph">内部結合 (Inner Join) は、結合対象テーブルで指定した列で両テーブルの行を比較し、共に指定列の値が一致する行のみを使ってテーブルを結合します。つまり、片方のテーブルに存在しても、もう一方には存在しないデータは結合結果に含まれません。</p>



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



<p class="wp-block-paragraph">PySpark の DataFrame での内部結合 (Inner Join) は以下のようにします。</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=""># 内部結合 (inner join)
df_inner = df_a.join(df_b, on=["id"], how="inner")
df_inner.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="">【実行結果】
+----+------+------+
|  id|value1|value2|
+----+------+------+
|B001|   200|   aaa|
|C001|   300|   bbb|
+----+------+------+</pre>



<p class="wp-block-paragraph">例では、<code>df_a</code> に対して <code>df_b</code> のテーブルを <code>join</code> メソッドで結合しています。</p>



<p class="wp-block-paragraph">結合条件に指定する列は <span class="jinr-d--text-color d--marker1 d--bold"><code>on</code></span> 引数で指定します。例では、<code>id</code> 列を指定しています。また、結合方法は <span class="jinr-d--text-color d--marker1 d--bold"><code>how</code></span> 引数で指定します。内部結合のため <span class="jinr-d--text-color d--marker1 d--bold"><code>how="inner"</code></span> とします。</p>



<p class="wp-block-paragraph">結果を見てみると <code>df_a</code> と <code>df_b</code> でともに現れる <code>id</code> の行のみが抽出されて結合されていることが分かります。</p>



<h3 class="wp-block-heading jinr-heading d--bold">外部結合 (Outer Join)</h3>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">外部結合 (Outer Join)</span> は、結合対象テーブルで指定した列において両テーブルの行を比較したときに、一致しない行も結合結果に含めて結合します。この時、片方のテーブルに存在し、もう一方には存在しないデータの場合には <code>NULL</code> で埋められます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">外部結合 (Outer Join)</h4>



<p class="wp-block-paragraph">PySpark の DataFrame での外部結合 (Outer Join) は以下のようにします。</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=""># 外部結合 (outer join)
df_outer = df_a.join(df_b, on=["id"], how="outer")
df_outer.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="">【実行結果】
+----+------+------+
|  id|value1|value2|
+----+------+------+
|A001|   100|  NULL|
|B001|   200|   aaa|
|C001|   300|   bbb|
|C002|   400|  NULL|
|D001|  NULL|   ccc|
|E001|   500|  NULL|
|E002|  NULL|   ddd|
+----+------+------+</pre>



<p class="wp-block-paragraph">外部結合を使用する場合は、 <code>how</code> 引数で <span class="jinr-d--text-color d--marker1 d--bold"><code>how="outer"</code></span> を指定します。</p>



<p class="wp-block-paragraph">結果を見てみると <code>df_a</code> と <code>df_b</code> において <code>id</code> が一致していない行についても含めて結合されていることが分かります。例のように片方のテーブルには存在し、もう一方には存在しないデータは <code>NULL</code> で埋められます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">左外部結合 (Left Outer Join)</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">左外部結合(Left Outer Join)</span> は、外部結合のうち、左側のテーブルを基準にして結合します。具体的には、左側のテーブルのすべての行を含み、指定した列において一致する行が右側のテーブルにない場合は <code>NULL</code>で埋めます。Left Join と単純に言う場合は左外部結合のことを指していると思ってください。</p>



<p class="wp-block-paragraph">PySpark の DataFrame で左外部結合 (Left Outer Join) は以下のようにします。</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=""># 左外部結合 (left Outer join)
df_left_outer = df_a.join(df_b, on=["id"], how="left")
df_left_outer.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="">【実行結果】
+----+------+------+
|  id|value1|value2|
+----+------+------+
|A001|   100|  NULL|
|B001|   200|   aaa|
|C001|   300|   bbb|
|C002|   400|  NULL|
|E001|   500|  NULL|
+----+------+------+</pre>



<p class="wp-block-paragraph">左外部結合を使用する場合は、<code>how</code> 引数で <span class="jinr-d--text-color d--marker1 d--bold"><code>how="left"</code></span> を指定します。</p>



<p class="wp-block-paragraph">ここでいう左とは <code>df_a</code> のことです。結果を見ると <code>df_a</code> のすべて行を含み <code>df_b</code> を結合しています。左側のテーブルである <code>df_a</code> に存在し、もう一方の <code>df_b</code> には存在しないデータは <code>NULL</code> で埋められます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">右外部結合 (Right Outer Join)</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">右外部結合 (Right Outer Join)</span> は、外部結合のうち、右側のテーブルを基準にして結合します。具体的には、右側のテーブルのすべての行を含み、指定した列において一致する行が左側のテーブルにない場合は <code>NULL</code> で埋めます。Right Join と単純に言う場合は右外部結合のことを指していると思ってください。</p>



<p class="wp-block-paragraph">結合するテーブル順を逆にすれば、右外部結合は左外部結合でも表現できます。実際の使用においては左外部結合がより一般的です。これは、左から右へという自然な流れにあっているからです。とはいえ、右外部結合の使い方も知っておきましょう。</p>



<p class="wp-block-paragraph">PySpark の DataFrame で右外部結合 (Right Outer Join) は以下のようにします。</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=""># 右外部結合 (Right Outer Join)
df_right_outer = df_a.join(df_b, on=["id"], how="right")
df_right_outer.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="">【実行結果】
+----+------+------+
|  id|value1|value2|
+----+------+------+
|B001|   200|   aaa|
|C001|   300|   bbb|
|D001|  NULL|   ccc|
|E002|  NULL|   ddd|
+----+------+------+</pre>



<p class="wp-block-paragraph">右外部結合を使用する場合は、<code>how</code> 引数で <span class="jinr-d--text-color d--marker1 d--bold"><code>how="right"</code></span> を指定します。</p>



<p class="wp-block-paragraph">ここでいう右とは <code>df_b</code> のことです。結果を見ると <code>df_b</code> のすべての行を含み <code>df_a</code> を結合しています。右側のテーブルである <code>df_b</code> に存在し、もう一方の <code>df_a</code> には存在しないデータは <code>NULL</code> で埋められます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">複数列をキーに使用した結合</h3>



<p class="wp-block-paragraph">DataFrame を結合する場合には、複数列をキーにして結合したくなることがほとんどです。複数キーでの結合するために <code>df_c</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="">data_c = [
    ("A001", 1, "num1"),
    ("B001", 200, "num2"),
    ("C001", 300, "num3"),
    ("C001", 4, "num4"),
    ("E001", 500, "num5"),
]
df_c = spark.createDataFrame(data_c, ["id", "value1", "value3"])
df_c.printSchema()
df_c.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
 |-- id: string (nullable = true)
 |-- value1: long (nullable = true)
 |-- value3: string (nullable = true)

+----+------+------+
|  id|value1|value3|
+----+------+------+
|A001|     1|  num1|
|B001|   200|  num2|
|C001|   300|  num3|
|C001|     4|  num4|
|E001|   500|  num5|
+----+------+------+
</pre>



<p class="wp-block-paragraph"><code>id</code> 列と <code>value1</code> 列は、<code>df_a</code> と共通したものとなっています。このデータを用いて <code>df_a</code> と <code>df_c</code> を <code>id</code>、<code>value1</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=""># 複数条件での結合
df_inner_multi = df_a.join(df_c, on=["id", "value1"], how="inner")
df_inner_multi.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="">【実行結果】
+----+------+------+
|  id|value1|value3|
+----+------+------+
|B001|   200|  num2|
|C001|   300|  num3|
|E001|   500|  num5|
+----+------+------+</pre>



<p class="wp-block-paragraph">使い方はこれまで見てきた例とほとんど同じで <code>on</code> 引数に <code>["id", "value1"]</code> といった形で複数のキーとなる列をリストで指定します。</p>



<p class="wp-block-paragraph">結果を見ると <code>id</code> と <code>value1</code> がともに一致する列のみ抽出されています。</p>



<h3 class="wp-block-heading jinr-heading d--bold">異なる列名で結合する場合</h3>



<p class="wp-block-paragraph">複数データソースからデータを取得して分析をする場合、同じ意味でも列名が異なるケースはよくあります。このような場合の対処法についても見ておきましょう。</p>



<p class="wp-block-paragraph">列名が異なる例として <code>df_d</code> という DataFrame を作っておきます。このデータは <code>df_b</code> と内容は同じなのですが <code>id</code> に該当する列名が <code>no</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="">data_d = [
    ("B001", "aaa"),
    ("C001", "bbb"),
    ("D001", "ccc"),
    ("E002", "ddd"),
]
df_d = spark.createDataFrame(data_d, ["no", "value5"])
df_d.printSchema()
df_d.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
 |-- no: string (nullable = true)
 |-- value5: string (nullable = true)

+----+------+
|  no|value5|
+----+------+
|B001|   aaa|
|C001|   bbb|
|D001|   ccc|
|E002|   ddd|
+----+------+</pre>



<p class="wp-block-paragraph">これまで使用していた <code>df_a</code> と上記の <code>df_d</code> を結合する例を見てみましょう。</p>



<h4 class="wp-block-heading jinr-heading d--bold">等価演算子 (<code>==</code>) を使用して結合する</h4>



<p class="wp-block-paragraph">異なる列名で結合する場合に、等価演算子 (<code>==</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=""># 等価演算子(==)を使用して異なる列名を条件に結合する
df_inner_equal = df_a.join(df_d, df_a.id == df_d.no, how="inner")
df_inner_equal.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="">【実行結果】
+----+------+----+------+
|  id|value1|  no|value5|
+----+------+----+------+
|B001|   200|B001|   aaa|
|C001|   300|C001|   bbb|
+----+------+----+------+</pre>



<p class="wp-block-paragraph">等価演算子 (<code>==</code>) を使用する場合には、例のように「<code>df_a.id == df_d.no</code>」といった条件を引数に指定します。</p>



<p class="wp-block-paragraph">結果を見ると条件に一致した行のみ抽出されていることが分かるかと思います。ただし、結合結果にはそれぞれの列 (<code>id</code> と <code>no</code>) が含まれる結果となります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">列名を統一してから結合する</h4>



<p class="wp-block-paragraph">上記のように等価演算子 (<code>==</code>) を使用することで異なる列名でも結合ができました。しかし、同じ意味の異なる列が結合結果に残ってしまいます。</p>



<p class="wp-block-paragraph">それぞれの列を残しておく必要がない場合には、列名を統一してから結合します。</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=""># 列名を変更して統一する
df_d = df_d.withColumnRenamed("no", "id")
df_d.show()

# 統一した列名を用いて結合する
df_inner_renamed = df_a.join(df_d, on=["id"], how="inner")
df_inner_renamed.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="">【実行結果】
+----+------+
|  id|value5|
+----+------+
|B001|   aaa|
|C001|   bbb|
|D001|   ccc|
|E002|   ddd|
+----+------+

+----+------+------+
|  id|value1|value5|
+----+------+------+
|B001|   200|   aaa|
|C001|   300|   bbb|
+----+------+------+</pre>



<p class="wp-block-paragraph">列名を統一する場合には、<code>withColumnRenamed</code> を使用して列名を変更します。例では、<code>df_d</code> の <code>no</code> を <code>id</code> に変更しています。その後、<code>id</code> 列をキーにして結合することで異なる列名に対する結合ができます。</p>



<p class="wp-block-paragraph">等価演算子 (<code>==</code>) を使用して結合するか、列名を統一してから結合するかは、結合によって求められる状況によって異なります。各状況に応じでどちらで対応するかを十分に検討してください。</p>



<h3 class="wp-block-heading jinr-heading d--bold">結合アルゴリズムの種類</h3>



<p class="wp-block-paragraph">Spark の結合の <code>join</code> では、結合アルゴリズムをデータセットのサイズ、結合キーの有無、クエリの要件などに基づいて最適なものが選択します。主な結合のアルゴリズムは以下のようなものがあります。</p>



<ol class="wp-block-list jinr-list">
<li>Broadcast Hash Join</li>



<li>Sort Merge Join</li>



<li>Shuffle Hash Join</li>



<li>Broadcast Nested Loop Join</li>



<li>Cartesian Join</li>
</ol>



<p class="wp-block-paragraph">一般的には、上から順に高速な処理と言われます。ただし、実際の性能はケースによるためご注意ください。以降で、各アルゴリズムの概要について説明します。</p>



<h4 class="wp-block-heading jinr-heading d--bold">Broadcast Hash Join</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">Broadcast Hash Join</span> (ブロードキャストハッシュジョイン)は、片方のデータセットが十分に小さい場合に使用されます。</p>



<p class="wp-block-paragraph">Spark は、分散されたノードで処理が実行されます。そのため、例えばマスタテーブルなど小さいデータセットがある場合には、各ノードに先にブロードキャストで配布し、その後で大きなデータセットとハッシュテーブルを使用して結合することで効率的にデータを結合します。</p>



<p class="wp-block-paragraph">主に小さなデータセットと大きなデータセットの結合で使用され、処理は高速です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">Sort Merge Join </h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">Sort Merge Join</span> (ソートマージジョイン)は、両方のデータセットが大きい場合に使用されます。</p>



<p class="wp-block-paragraph">このアルゴリズムは、結合キーに基づいてデータがソート、シャッフルされた後、ソートされたデータを使用してマージ結合が行われます。両方のデータセットが大きく、データの分散が一様でない場合の結合で使用され、効率的に処理がされます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">Shuffle Hash Join</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">Shuffle Hash Join</span> (シャッフルハッシュジョイン)は、両方のデータセットが中程度のサイズの場合に使用されることが多いアルゴリズムです。</p>



<p class="wp-block-paragraph">このアルゴリズムでは、結合キーに基づいてデータがシャッフルされ、その後ハッシュベースの結合が行われます。中程度のデータセットには適していますが Broadcast Hash Join や Sort Merge Join よりは一般的に少し遅くなります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">Broadcast Nested Loop Join</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">Broadcast Nested Loop Join</span> (ブロードキャストネステッドループジョイン)は、結合キーがない場合等に使用されます。</p>



<p class="wp-block-paragraph">このアルゴリズムでは、小さいデータセットが各ノードにブロードキャストされて大きなデータセットのデータに対してループによる結合が行われます。結合キーがない場合といった通り、組み合わせで結合するため通常避けられるべき結合の種類です。</p>



<p class="wp-block-paragraph">上記の <code>join</code> での結合例で紹介したように結合キーを指定して結合する場合には、通常選択されることはありません。</p>



<h4 class="wp-block-heading jinr-heading d--bold">Cartesian Join</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">Cartesian Join</span> (カルテシアンジョイン)は、結合キーが指定されていない場合で、データセット間のカルテシアン積（すべての可能なペアの結合）を生成する場合に使用されます。</p>



<p class="wp-block-paragraph">このアルゴリズムは、リソースを大量に消費し非常に遅いプロセスであるため、通常は避けられるべき結合の種類であり、特定の分析や複雑なクエリなどで他の結合方法が適用できな場合に限り使われるものです。</p>



<p class="wp-block-paragraph">上記の <code>join</code> での結合例で紹介したように結合キーを指定して結合する場合には、通常選択されることはありません。</p>



<h4 class="wp-block-heading jinr-heading d--bold">チューニングの際に考慮するべきこと</h4>



<p class="wp-block-paragraph">Spark では、上記のような結合アルゴリズムをデータセットのサイズ、結合キーの有無、クエリの要件などに基づいて最適なものが選択されます。</p>



<p class="wp-block-paragraph">実行計画を確認する <code>explain</code> メソッドや実行結果を確認する Spark UI を用いると、どの結合アルゴリズムが選択されているかを確認することができます。もし遅いとされる Broadcast Nested Loop Join や Cartesian Join が選択されているような場合には、<code>repartition</code> 等でパーティションサイズを調整したり、クエリを変更するなどを再検討するのが良いでしょう。</p>



<p class="wp-block-paragraph">また、<code>join</code> の際に特定のアルゴリズムを使用するようにヒントを与える <code>hint</code> メソッドというものもあります。以下は、Broadcast Hash Join を使用するようにヒントを与える例です。</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="">df = df1.join(df2.hint("broadcast"), on=["Key1"])</pre>



<p class="wp-block-paragraph">上記例では <code>df2</code> が小さいデータセットの場合に <code>df2</code> をブロードキャストしてから結合するように促すことができます。</p>



<p class="wp-block-paragraph">また、同様に Sort Merge Join を使用するように促したい場合には、以下のようにすることもできます。</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="">df = df1.join(df2.hint("merge"), on=["Key1"])</pre>



<p class="wp-block-paragraph">なお、注意事項として上記はあくまでヒントであるため<span class="jinr-d--text-color d--marker1 d--bold">必ずそのアルゴリズムが選択されるわけではない</span>ことに注意してください。</p>



<p class="wp-block-paragraph">どのアルゴリズムが選択されるかは、最終的にはデータセットのサイズや結合キーの有無、クエリの要件によって Spark が自動的に判定して最適なものを選択します。</p>



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



<p class="wp-block-paragraph">PySpark で <span class="jinr-d--text-color d--marker1 d--bold">DataFrame を結合する方法</span>について解説しました。</p>



<p class="wp-block-paragraph">PySpark では、DataFrameの結合方法として <span class="jinr-d--text-color d--marker1 d--bold"><code>join</code></span> メソッドが用意されています。この記事では <code>join</code> メソッドの使い方の基本を紹介しました。</p>



<p class="wp-block-paragraph">また、Spark では分散環境で動作するため、内部的に効率的な結合アルゴリズムが選択されます。Spark の結合アルゴリズムの種類についても簡単に説明しました。</p>



<p class="wp-block-paragraph">パフォーマンスチューニングの際には、どの結合アルゴリズムが選択されているかを確認して必要に応じて <code>repartition</code> 等でパーティションサイズを調整したり、クエリを変更するなどの検討が必要になります。</p>



<p class="wp-block-paragraph">データ結合は、データ活用において非常に重要なデータ操作です。ぜひ、PySpark での結合操作をうまく使いこなしてもらいたいと思います。</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 class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/pyspark/dataframe-join" 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/pyspark-dataframe-join/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【pandas】SeriesやDataFrameを連結する方法 ~ concat ~</title>
		<link>https://tech.nkhn37.net/pandas-dataframe-concat/</link>
					<comments>https://tech.nkhn37.net/pandas-dataframe-concat/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 18 Mar 2022 20:00:00 +0000</pubDate>
				<category><![CDATA[pandas]]></category>
		<category><![CDATA[append]]></category>
		<category><![CDATA[concat]]></category>
		<category><![CDATA[ignore_index]]></category>
		<category><![CDATA[inner]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[keys]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[outer]]></category>
		<category><![CDATA[verify_integrity]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=3154</guid>

					<description><![CDATA[pandasのSeriesやDataFrameを連結する方法について解説します。 SeriesやDataFrameの連結方法 データ分析の際には、異なる種類のデータソースの組み合わせから深い知見や研究成果が得られるという [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">pandasの<span class="marker"><strong>Seriesや</strong></span><span class="marker"><strong>DataFrameを連結する方法</strong></span>について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">SeriesやDataFrameの連結方法</h2>



<p class="wp-block-paragraph">データ分析の際には、異なる種類のデータソースの組み合わせから深い知見や研究成果が得られるということがほとんどです。ここでいう「組み合わせ」とは2つのデータセットを単に連結するだけではなく、重複するデータを適切に処理することも含まれます。</p>



<p class="wp-block-paragraph">pandasで中心的なデータ構造はSeriesやDataFrameです。これらは連結処理を念頭に置いて設計されているため、データを簡単に連結することができます。具体的には、pandasのSeriesやDataFrameを連結したい場合、<span class="marker"><strong><code>concat</code></strong></span>関数を使用することができます。</p>



<p class="wp-block-paragraph">この記事では、pandasの<code>concat</code>関数を用いたデータの連結方法を説明します。</p>



<h4 class="wp-block-heading jinr-heading d--bold">concat関数の基本的な使い方</h4>



<p class="wp-block-paragraph">SeriesやDataFrameを連結する場合には<span class="marker"><strong><code>concat</code></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

# ===== Seriesの連結
# データの準備
ser1 = pd.Series(['A', 'B', 'C', 'D', 'E'], index=[1, 2, 3, 4, 5])
ser2 = pd.Series(['V', 'W', 'X', 'Y', 'Z'], index=[6, 7, 8, 9, 10])

# 連結
ser_concat = pd.concat([ser1, ser2])
print(ser_concat, '\n')

# ===== DataFrameの連結
# データの準備
df1 = pd.DataFrame([['A', 'B'], ['C', 'D'], ['E', 'F']],
                   index=[1, 2, 3], columns=['attr1', 'attr2'])
df2 = pd.DataFrame([['U', 'V'], ['W', 'X'], ['Y', 'Z']],
                   index=[4, 5, 6], columns=['attr1', 'attr2'])

# 連結
df_concat = pd.concat([df1, df2])
print(df_concat)</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="">【実行結果】
1     A
2     B
3     C
4     D
5     E
6     V
7     W
8     X
9     Y
10    Z
dtype: object 

  attr1 attr2
1     A     B
2     C     D
3     E     F
4     U     V
5     W     X
6     Y     Z</pre>



<p class="wp-block-paragraph">上記では、SeriesとDataFrameをそれぞれ連結をしています。使用方法は簡単で、<code>concat</code>関数の引数に連結したい対象のSeriesやDataFrameを含むリストを指定するだけです。</p>



<h4 class="wp-block-heading jinr-heading d--bold">インデックスが重複している場合</h4>



<p class="wp-block-paragraph"><code>concat</code>関数の特徴として、連結するデータのインデックスが重複していても、それぞれのインデックスが保持される点があります。以下は、インデックス2, 3が重複しているケースです。</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

# ===== DataFrameの連結
# データの準備
df1 = pd.DataFrame([['A', 'B'], ['C', 'D'], ['E', 'F']],
                   index=[1, 2, 3], columns=['attr1', 'attr2'])
df2 = pd.DataFrame([['U', 'V'], ['W', 'X'], ['Y', 'Z']],
                   index=[2, 3, 4], columns=['attr1', 'attr2'])

# 連結 (インデックスが重複していても保持する)
df_concat = pd.concat([df1, df2])
print(df_concat)</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
  attr1 attr2
1     A     B
2     C     D
3     E     F
2     U     V
3     W     X
4     Y     Z</pre>



<p class="wp-block-paragraph">上記結果を見ると、インデックス2, 3が複数回出現していることが分かります。</p>



<p class="wp-block-paragraph">このような状況でも問題がなければそのままで構いません。もし、重複が問題になる場合は、後述する<code>verify_integrity</code>や<code>ignore_index</code>を使った対処法があります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">重複がある場合に例外を出す ~ verify_integrity ~</h4>



<p class="wp-block-paragraph"><code>concat</code>関数は、インデックスが重複していても保持します。インデックスの重複が問題になる場合、重複があることを例外として出して対処する方法があります。</p>



<p class="wp-block-paragraph">重複した場合に例外を出すには、以下のように<span class="marker"><strong><code>verify_integrity</code></strong></span>を<code>True</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

# ===== DataFrameの連結
df1 = pd.DataFrame([['A', 'B'], ['C', 'D'], ['E', 'F']],
                   index=[1, 2, 3], columns=['attr1', 'attr2'])
df2 = pd.DataFrame([['U', 'V'], ['W', 'X'], ['Y', 'Z']],
                   index=[2, 3, 4], columns=['attr1', 'attr2'])

# 連結 (インデックス重複時は例外:ValueError)
try:
    df_concat = pd.concat([df1, df2], verify_integrity=True)
    print(df_concat)
except ValueError as ex:
    print(ex)</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="">【実行結果】
Indexes have overlapping values: Int64Index([2, 3], dtype='int64')</pre>



<p class="wp-block-paragraph"><code>verify_integrity</code>を<code>True</code>に設定すると、インデックスが重複していた場合には、<code>ValueError</code>の例外が発生します。この例外をキャッチすることで、処理を変更することが可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">インデックスを無視する ~ ignore_index ~</h4>



<p class="wp-block-paragraph">インデックスが重複しているケースで、もともとのインデックスが意味を持たない場合は、インデックスを無視して新しいインデックスを振ることが可能です。</p>



<p class="wp-block-paragraph">インデックスを無視して新しいインデックスを振るには、以下のように<span class="marker"><strong><code>ignore_index</code></strong></span>をTrueに設定します。</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

# ===== DataFrameの連結
df1 = pd.DataFrame([['A', 'B'], ['C', 'D'], ['E', 'F']],
                   index=[1, 2, 3], columns=['attr1', 'attr2'])
df2 = pd.DataFrame([['U', 'V'], ['W', 'X'], ['Y', 'Z']],
                   index=[2, 3, 4], columns=['attr1', 'attr2'])

# 連結 (インデックスを無視する)
df_concat = pd.concat([df1, df2], ignore_index=True)
print(df_concat)</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
0     A     B
1     C     D
2     E     F
3     U     V
4     W     X
5     Y     Z</pre>



<p class="wp-block-paragraph">上記結果から、もともとのインデックスが無視され、新しいインデックスが0から設定されてデータが結合されていることが分かります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">連結するデータにキーを指定して階層型インデックス（マルチインデックス）にする ~ keys ~</h4>



<p class="wp-block-paragraph">データを連結する際に、元のデータのキーを残して結合したい場合は、階層型インデックス（マルチインデックス）を使用して対応することができます。階層型インデックスにするには、以下のように<span class="marker"><strong><code>keys</code></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

# ===== DataFrameの連結
# データの準備
df1 = pd.DataFrame([['A', 'B'], ['C', 'D'], ['E', 'F']],
                   index=[1, 2, 3], columns=['attr1', 'attr2'])
df2 = pd.DataFrame([['U', 'V'], ['W', 'X'], ['Y', 'Z']],
                   index=[2, 3, 4], columns=['attr1', 'attr2'])

# 連結 (階層型のインデックスにする)
df_concat = pd.concat([df1, df2], keys=['D1', 'D2'])
print(df_concat)</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
D1 1     A     B
   2     C     D
   3     E     F
D2 2     U     V
   3     W     X
   4     Y     Z</pre>



<p class="wp-block-paragraph">上記の例では<code>"D1"</code>、<code>"D2"</code>を指定しています。結果として、それぞれのキーの下に元のデータのインデックスが階層型インデックスとして配置され、データが連結されています。</p>



<h4 class="wp-block-heading jinr-heading d--bold">積集合での連結 ~ join=&#8221;inner&#8221; ~</h4>



<p class="wp-block-paragraph">上記で見てきた例では、列名が全く同じデータを連結してきました。では、列名が異なるデータを連結する場合はどうなるでしょうか。以下の例で見てみましょう。</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

# ===== DataFrameの連結
df1 = pd.DataFrame([['A', 'B'], ['C', 'D'], ['E', 'F']],
                   index=[1, 2, 3], columns=['attr1', 'attr2'])
df2 = pd.DataFrame([['U', 'V'], ['W', 'X'], ['Y', 'Z']],
                   index=[4, 5, 6], columns=['attr2', 'attr3'])

# 連結 (デフォルトはjoin='outer')
df_concat = pd.concat([df1, df2])
print(df_concat, '\n')

# 連結 (join='inner')
df_concat = pd.concat([df1, df2], join='inner')
print(df_concat)</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
1     A     B   NaN
2     C     D   NaN
3     E     F   NaN
4   NaN     U     V
5   NaN     W     X
6   NaN     Y     Z 

  attr2
1     B
2     D
3     F
4     U
5     W
6     Y</pre>



<p class="wp-block-paragraph">concat関数は、デフォルトでは<span class="marker"><strong><code>join="outer"</code></strong></span>となっています。<code>outer</code>は和集合を意味し、両方の列を含んだ連結が行われ、値がない部分は上記結果のように<code>NaN</code>となります。</p>



<p class="wp-block-paragraph">もし、それぞれのデータセットに存在する列のみを連結したい場合は、<span class="marker"><strong><code>join="inner"</code></strong></span>を指定します。これにより積集合としての連結が行われます。上記結果を見ると、<code>join="inner"</code>を指定した場合は、両方に存在する<code>"attr2"</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 class="wp-block-paragraph"><code>concat</code> 関数の公式ドキュメントは<a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">appendメソッドによるデータ連結【非推奨】</h3>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--heading-iconbox1 ">
			<div class="a--heading-iconbox-title">
			<div class="a--iconbox-title-icon"><i class="jif jin-ifont-caution" aria-hidden="true"></i></div>
			<div class="a--iconbox-title-text">注意点</div>
			</div>
			<div class="a--jinr-iconbox">
<p class="wp-block-paragraph"><code>append</code> メソッドは、1.4.0から非推奨になっており、将来的には pandas から削除される予定です。バージョンによっては <code>concat</code> 関数を使用するよう警告が表示される場合があります。</p>



<p class="wp-block-paragraph"><code>append</code> メソッドは使用可能な場合であっても、データ連結の際は <code>concat</code> 関数の使用を推奨します。</p>
</div>
		</div></section>



<h2 class="wp-block-heading jinr-heading d--bold">その他のデータの結合方法（merge, join）</h2>



<p class="wp-block-paragraph">上記では、<code>concat</code>関数を用いた連結方法について紹介しました。pandasには、他にも<span class="marker"><strong><code>merge</code></strong></span>関数や<span class="marker"><strong><code>join</code></strong></span>メソッドという強力なデータ結合方法があります。</p>



<p class="wp-block-paragraph">データベースのSQLに慣れている人にとっては、<code>merge</code>関数や<code>join</code>メソッドが理解しやすいかもしれません。これらの使用方法については「<a href="https://tech.nkhn37.net/pandas-dataframe-merge-join/" target="_blank" rel="noreferrer noopener">DataFrameを結合する方法</a>」でまとめていますので興味があれば参考にしてください。</p>



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



<p class="wp-block-paragraph">pandasのSeriesやDataFrameを連結する方法について解説しました。具体的には、<span class="marker"><strong><code>concat</code></strong></span>関数によるデータ連結方法について説明しました。</p>



<p class="wp-block-paragraph">データ分析では、単にデータを連結するだけではなく、重複するデータの適切な処理や、連結時に元のデータを保持しながら階層型インデックス（マルチインデックス）を作成する方法、さらに<code>outer</code>や<code>inner</code>結合を使い分けることが重要です。これらについて本記事で紹介しました。</p>



<p class="wp-block-paragraph">データ分析においては、複数のデータソースを適切に結合してから分析を行うことで、有益な情報を抽出できます。<code>concat</code>関数を利用したデータ結合に慣れることは重要です。</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 class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/pandas/concat" 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-concat/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【pandas】DataFrameを結合する方法 ~ merge, join ~</title>
		<link>https://tech.nkhn37.net/pandas-dataframe-merge-join/</link>
					<comments>https://tech.nkhn37.net/pandas-dataframe-merge-join/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 12 Mar 2022 20:00:00 +0000</pubDate>
				<category><![CDATA[pandas]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[left_index]]></category>
		<category><![CDATA[left_on]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[right_index]]></category>
		<category><![CDATA[right_on]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=3055</guid>

					<description><![CDATA[pandasのDataFrameを結合する方法について解説します。 DataFrameの結合 データ分析の際には、データベースやCSVファイル等、様々なデータソースからデータを取得して分析することがほとんどです。この時、 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">pandasの<span class="marker"><strong>DataFrameを結合する方法</strong></span>について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">DataFrameの結合</h2>



<p class="wp-block-paragraph">データ分析の際には、データベースやCSVファイル等、様々なデータソースからデータを取得して分析することがほとんどです。この時、各データで同じ意味を表すキー列をもとに結合して分析できるようにすることは、データに対する深い知見を得るために必要不可欠です。</p>



<p class="wp-block-paragraph">Pythonのデータ分析で使用されるpandasでは、DataFrameの結合方法として<span class="marker"><strong><code>merge</code></strong></span>関数や<span class="marker"><strong><code>join</code></strong></span>メソッドといった非常に便利な機能が提供されています。</p>



<p class="wp-block-paragraph">以降では、以下図に示したような製品一覧と関連する情報を結合する例で<code>merge</code>関数や<code>join</code>メソッドを用いたDataFrameの結合方法を紹介していきます。</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="1024" height="715" src="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-17-1024x715.png" alt="DataFrameの結合用データ例 merge join" class="wp-image-3064" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-17-1024x715.png 1024w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-17-300x209.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-17-768x536.png 768w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-17.png 1455w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">上記例では、各製品シリアル一覧と関連する品質情報実績、顧客情報、製品特徴のデータがあるものとします。製造メーカー等では生産管理システムのマスタや製造実績、品質管理システムの品質実績など、様々なシステムのデータをつなげて分析したいといったことがよくあります。実際の現場で使われているデータはもっと複雑なデータが多いと思いますが、上記のような簡単データで結合のイメージをつかんでもらえればと思います。</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 class="wp-block-paragraph">同じ構造をもつデータを単純に連結する場合には、<code>concat</code>を使うことができます。concat については「<a href="https://tech.nkhn37.net/pandas-dataframe-concat/" target="_blank" rel="noreferrer noopener">SeriesやDataFrameを連結する方法 ~ concat ~</a>」を参考にしてください。</p>
</div>
		</div></section>



<h2 class="wp-block-heading jinr-heading d--bold">merge関数によるDataFrameの結合の基本</h2>



<p class="wp-block-paragraph">データを結合する場合には、データの関係性をよく考慮することが重要です。データの関係に応じて「1対1」「多対1」「多対多」という関係性があります。以降では、それぞれの関係性のデータを使いながら<span class="marker"><strong><code>merge</code></strong></span>関数を使用してデータを結合する方法を紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">1対1の結合 </h3>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="368" src="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-18-1024x368.png" alt="DataFrameの結合 merge (1対1)" class="wp-image-3065" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-18-1024x368.png 1024w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-18-300x108.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-18-768x276.png 768w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-18.png 1143w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">上記図の例は「1対1」の関係があるデータです。「<code>serial_no</code>」をキー列として見てみると、各レコード（各行）は1対1に対応していることがわかります。ここでは、製品一覧と品質情報を<code>serial_no</code>をキーに<code>merge</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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)

# 品質情報
quality_result = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'quality': [100, 200, 300, 400, 500]
     }
)

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'品質実績(quality_result):\n{quality_result}\n')

# 製品一覧と品質情報をマージ（1対1）
result_df = pd.merge(product_list, quality_result)

print(f'製品一覧と品質情報をマージ（1対1）:\n{result_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="">【実行結果】
製品一覧(product_list):
  serial_no customer_id product_code
0      A001       cid_1          p_a
1      B001       cid_1          p_b
2      C001       cid_2          p_c
3      C002       cid_2          p_c
4      D001       cid_3          p_d

品質実績(quality_result):
  serial_no  quality
0      A001      100
1      B001      200
2      C001      300
3      C002      400
4      D001      500

製品一覧と品質情報をマージ（1対1）:
  serial_no customer_id product_code  quality
0      A001       cid_1          p_a      100
1      B001       cid_1          p_b      200
2      C001       cid_2          p_c      300
3      C002       cid_2          p_c      400
4      D001       cid_3          p_d      500</pre>



<p class="wp-block-paragraph"><code>merge</code>関数の引数に結合するDataFrameを指定すると、結合されたDataFrameが返却されます。<code>merge</code>関数は、自動的に1つ以上の同じ名前の列名を探してキーにして結合をしてくれます。上記例では「<code>serial_no</code>」がキーとなります。</p>



<h3 class="wp-block-heading jinr-heading d--bold">多対1の結合 </h3>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="315" src="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-16-1024x315.png" alt="DataFrameの結合 merge (多対1)" class="wp-image-3063" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-16-1024x315.png 1024w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-16-300x92.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-16-768x236.png 768w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-16.png 1252w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">上記図の例は「多対1」の関係があるデータです。「<code>customer_id</code>」をキー列として見てみると、製品一覧の複数レコードに1つの顧客情報のレコードが対応しています。ここでは、製品一覧と顧客情報を<code>customer_id</code>をキーにして<code>merge</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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)

# 顧客情報
customer_info = pd.DataFrame(
    {'customer_id': ['cid_1', 'cid_2', 'cid_3'],
     'customer_name': ['顧客１', '顧客２', '顧客３']
     }
)

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'顧客情報(customer_info):\n{customer_info}\n')

# 製品一覧と顧客情報をマージ（多対1）
result_df = pd.merge(product_list, customer_info)

print(f'製品一覧と顧客情報をマージ（多対1）:\n{result_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="">製品一覧(product_list):
  serial_no customer_id product_code
0      A001       cid_1          p_a
1      B001       cid_1          p_b
2      C001       cid_2          p_c
3      C002       cid_2          p_c
4      D001       cid_3          p_d

顧客情報(customer_info):
  customer_id customer_name
0       cid_1           顧客１
1       cid_2           顧客２
2       cid_3           顧客３

製品一覧と顧客情報をマージ（多対1）:
  serial_no customer_id product_code customer_name
0      A001       cid_1          p_a           顧客１
1      B001       cid_1          p_b           顧客１
2      C001       cid_2          p_c           顧客２
3      C002       cid_2          p_c           顧客２
4      D001       cid_3          p_d           顧客３</pre>



<p class="wp-block-paragraph">上記結果を見てみると<code>customer_id</code>をキーにして製品一覧に顧客情報が結合されていることが分かります。製品一覧の方が多であるため、顧客情報は複製されて各行に結合されていることが分かるかと思います。</p>



<h3 class="wp-block-heading jinr-heading d--bold">多対多の結合</h3>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="523" src="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-19-1024x523.png" alt="DataFrameの結合 merge (多対多)" class="wp-image-3068" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/03/image-19-1024x523.png 1024w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-19-300x153.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-19-768x393.png 768w, https://tech.nkhn37.net/wp-content/uploads/2022/03/image-19.png 1174w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">上記図の例は「多対多」の関係があるデータです。「<code>product_code</code>」をキー列としてみてみると、製品一覧の複数レコードに、複数の製品特徴のレコードが対応しているということが分かります。ここでは、製品一覧と製品特徴を<code>product_code</code>をキーにして<code>merge</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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)

# 製品特徴
product_feature = pd.DataFrame(
    {'product_code': ['p_a', 'p_a', 'p_b', 'p_b', 'p_c', 'p_c',
                      'p_d', 'p_d', 'p_d'],
     'feature': ['a-1', 'a-2', 'b-1', 'b-2', 'c-1', 'c-2',
                 'd-1', 'd-2', 'd-3']
     }
)

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'製品特徴(product_feature):\n{product_feature}\n')

# 製品一覧と製品特徴をマージ（多対多）
result_df = pd.merge(product_list, product_feature)

print(f'製品一覧と製品特徴をマージ（多対多）:\n{result_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="">【実行結果】
製品一覧(product_list):
  serial_no customer_id product_code
0      A001       cid_1          p_a
1      B001       cid_1          p_b
2      C001       cid_2          p_c
3      C002       cid_2          p_c
4      D001       cid_3          p_d

製品特徴(product_feature):
  product_code feature
0          p_a     a-1
1          p_a     a-2
2          p_b     b-1
3          p_b     b-2
4          p_c     c-1
5          p_c     c-2
6          p_d     d-1
7          p_d     d-2
8          p_d     d-3

製品一覧と製品特徴をマージ（多対多）:
   serial_no customer_id product_code feature
0       A001       cid_1          p_a     a-1
1       A001       cid_1          p_a     a-2
2       B001       cid_1          p_b     b-1
3       B001       cid_1          p_b     b-2
4       C001       cid_2          p_c     c-1
5       C001       cid_2          p_c     c-2
6       C002       cid_2          p_c     c-1
7       C002       cid_2          p_c     c-2
8       D001       cid_3          p_d     d-1
9       D001       cid_3          p_d     d-2
10      D001       cid_3          p_d     d-3</pre>



<p class="wp-block-paragraph">上記結果を見てみると、多対多の関係であるため、ある製品シリアルに関するレコードが複数行に増えていることが分かるかと思います。</p>



<p class="wp-block-paragraph">上記で見てきた通り、<code>merge</code>関数は自動的に1つ以上のキーを探して結合してくれます。データの関係性による結合の違いを見てもらうために自動でのキー結合をで結果を見てもらいましたが、実際のデータ分析の場面では、結合したいキーを明確に指定して結合することがほとんどです。以降では、<code>merge</code>関数で、キーを指定してDataFrameを結合する方法を紹介していきます。</p>



<h2 class="wp-block-heading jinr-heading d--bold">merge関数でキーを指定したDataFrameの結合</h2>



<p class="wp-block-paragraph">ここでは、<code>merge</code>関数でキー列を指定してDataFrameを結合する方法を説明します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">onでキーを指定して結合</h3>



<p class="wp-block-paragraph"><code>merge</code>関数でキー列を指定する場合は、以下の例のように<span class="marker"><strong><code>on</code></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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)

# 品質情報
quality_result = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'quality': [100, 200, 300, 400, 500]
     }
)

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'品質実績(quality_result):\n{quality_result}\n')

# onでキーを指定してマージ
result_df = pd.merge(product_list, quality_result, on='serial_no')

print(f'onでキー(serial_no)を指定してマージ\n{result_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="">【実行結果】
製品一覧(product_list):
  serial_no customer_id product_code
0      A001       cid_1          p_a
1      B001       cid_1          p_b
2      C001       cid_2          p_c
3      C002       cid_2          p_c
4      D001       cid_3          p_d

品質実績(quality_result):
  serial_no  quality
0      A001      100
1      B001      200
2      C001      300
3      C002      400
4      D001      500

onでキー(serial_no)を指定してマージ
  serial_no customer_id product_code  quality
0      A001       cid_1          p_a      100
1      B001       cid_1          p_b      200
2      C001       cid_2          p_c      300
3      C002       cid_2          p_c      400
4      D001       cid_3          p_d      500</pre>



<p class="wp-block-paragraph">上記例では、明示的に<code>"serial_no"</code>をキーとして結合しています。</p>



<p class="wp-block-paragraph">この例では、それぞれのDataFrameが同一名の列を持っているため、簡単に結合できます。しかし、データ分析では同じ意味でも異なる列名であることがよくあります。この場合には、以降で説明する<code>left_on</code>や<code>right_on</code>を使用します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">left_onとright_onでそれぞれのDataFrameのキーを指定する</h3>



<p class="wp-block-paragraph">データを結合する際には、それぞれのDataFrameで意味は同じなのに異なる列名となっている場合がよくあります。このような場合には<span class="marker"><strong><code>left_on</code></strong></span>や<span class="marker"><strong><code>right_on</code></strong></span>を使ってそれぞれのDataFrameにおけるキー列を指定します。</p>



<p class="wp-block-paragraph">ここで左(left)と言っているのは、<code>merge</code>関数の第1引数に指定するDataFrameで、右(<code>right</code>)と言っているのはmerge関数の第2引数に指定する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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)

# 品質情報
quality_result = pd.DataFrame(
    {'serial': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'quality': [100, 200, 300, 400, 500]
     }
)

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'品質実績(quality_result):\n{quality_result}\n')

# 左右のDataFrameのキーをそれぞれ指定してマージ
result_df = pd.merge(product_list, quality_result,
                     left_on='serial_no', right_on='serial')

print(f'左右のDataFrameのキーをそれぞれ指定してマージ:\n{result_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="">【実行結果】
製品一覧(product_list):
  serial_no customer_id product_code
0      A001       cid_1          p_a
1      B001       cid_1          p_b
2      C001       cid_2          p_c
3      C002       cid_2          p_c
4      D001       cid_3          p_d

品質実績(quality_result):
  serial  quality
0   A001      100
1   B001      200
2   C001      300
3   C002      400
4   D001      500

左右のDataFrameのキーをそれぞれ指定してマージ:
  serial_no customer_id product_code serial  quality
0      A001       cid_1          p_a   A001      100
1      B001       cid_1          p_b   B001      200
2      C001       cid_2          p_c   C001      300
3      C002       cid_2          p_c   C002      400
4      D001       cid_3          p_d   D001      500</pre>



<p class="wp-block-paragraph">上記例では、製品一覧ではシリアルナンバーは「<code>serial_no</code>」であるのに対して、品質情報では「<code>serial</code>」となっており名前が異なっています。この場合は、<code>merge</code>関数をそのまま使用しても一致するキーがなく、自動ではうまく結合できません。</p>



<p class="wp-block-paragraph">このような場合には「<code>left_on="serial_no"</code>」「<code>right_on="serial"</code>」としてそれぞれ結合するキー名称を指定することで指定列をキーにして結合することができます。</p>



<p class="wp-block-paragraph">上記結果を見ても分かるように、キー列は一つにまとめられるわけではなく複数列出てくる点も覚えておきましょう。もし、キー列が複数出てこないようにしたい場合は、事前にDataFrameの列名を揃えておく必要があります。</p>



<h3 class="wp-block-heading jinr-heading d--bold">left_indexとright_indexを指定してDataFrameのインデックスで結合</h3>



<p class="wp-block-paragraph">これまでの例では、DataFrameの列名を使用した<code>merge</code>関数の実行例を見てきました。pandasのDataFrameでは、インデックスを持っているためインデックスを用いての結合をすることも可能です。</p>



<p class="wp-block-paragraph">インデックスを使用して結合する場合には、以下の例のように「<span class="marker"><strong><code>left_index=True</code></strong></span>」「<span class="marker"><strong><code>right_index=True</code></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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)
# serial_no列をインデックスに設定
product_list = product_list.set_index('serial_no')

# 品質情報
quality_result = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'quality': [100, 200, 300, 400, 500]
     }
)
# serial_no列をインデックスに設定
quality_result = quality_result.set_index('serial_no')

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'品質実績(quality_result):\n{quality_result}\n')

# インデックスを使ってマージ
result_df = pd.merge(product_list, quality_result,
                     left_index=True, right_index=True)

print(f'インデックスを使ってマージ:\n{result_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="">【実行結果】
製品一覧(product_list):
          customer_id product_code
serial_no                         
A001            cid_1          p_a
B001            cid_1          p_b
C001            cid_2          p_c
C002            cid_2          p_c
D001            cid_3          p_d

品質実績(quality_result):
           quality
serial_no         
A001           100
B001           200
C001           300
C002           400
D001           500

インデックスを使ってマージ:
          customer_id product_code  quality
serial_no                                  
A001            cid_1          p_a      100
B001            cid_1          p_b      200
C001            cid_2          p_c      300
C002            cid_2          p_c      400
D001            cid_3          p_d      500</pre>



<p class="wp-block-paragraph">上記例では、これまでと異なり<code>set_index</code>を使って<code>"serial_no"</code>列をインデックスとして登録していることに注意してください。</p>



<p class="wp-block-paragraph">結果を見ると分かりますが「<code>left_index=True</code>」「<code>right_index=True</code>」を指定することで、インデックスを使った結合ができていることが分かるかと思います。</p>



<h3 class="wp-block-heading jinr-heading d--bold">joinメソッドを用いたインデックスでの結合</h3>



<p class="wp-block-paragraph"><code>merge</code>関数でインデックスを用いた結合の例を紹介しましたが、DataFrameでは、インデックスをキーとして結合を実行するための<span class="marker"><strong><code>join</code></strong></span>メソッドが用意されています。<code>join</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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)
# serial_no列をインデックスに設定
product_list = product_list.set_index('serial_no')

# 品質情報
quality_result = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'quality': [100, 200, 300, 400, 500]
     }
)
# serial_no列をインデックスに設定
quality_result = quality_result.set_index('serial_no')

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'品質実績(quality_result):\n{quality_result}\n')

# joinメソッドを使ってインデックスで結合
result_df = product_list.join(quality_result)

print(f'joinメソッドを使ってインデックスで結合:\n{result_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="">【実行結果】
製品一覧(product_list):
          customer_id product_code
serial_no                         
A001            cid_1          p_a
B001            cid_1          p_b
C001            cid_2          p_c
C002            cid_2          p_c
D001            cid_3          p_d

品質実績(quality_result):
           quality
serial_no         
A001           100
B001           200
C001           300
C002           400
D001           500

joinメソッドを使ってインデックスで結合:
          customer_id product_code  quality
serial_no                                  
A001            cid_1          p_a      100
B001            cid_1          p_b      200
C001            cid_2          p_c      300
C002            cid_2          p_c      400
D001            cid_3          p_d      500</pre>



<p class="wp-block-paragraph"><code>merge</code>は関数でしたが、<code>join</code>についてはDataFrameのメソッドです。そのため、<code>join</code>メソッドは、左側となるDataFrameでメソッドとして呼び出し、右側となるDataFrameを引数として指定します。結果としては、merge関数で「<code>left_index=True</code>」「<code>right_index=True</code>」とした場合と同じです。</p>



<h3 class="wp-block-heading jinr-heading d--bold">left_on, right_on, left_index, right_indexの混在での結合</h3>



<p class="wp-block-paragraph">上記では、列を指定する「<code>left_on</code>」「<code>right_on</code>」、インデックスでの結合を指定する「<code>left_index=True</code>」「<code>right_index=True</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

# 製品一覧
product_list = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'customer_id': ['cid_1', 'cid_1', 'cid_2', 'cid_2', 'cid_3'],
     'product_code': ['p_a', 'p_b', 'p_c', 'p_c', 'p_d']
     }
)
# serial_no列をインデックスに設定
product_list = product_list.set_index('serial_no')

# 品質情報
quality_result = pd.DataFrame(
    {'serial_no': ['A001', 'B001', 'C001', 'C002', 'D001'],
     'quality': [100, 200, 300, 400, 500]
     }
)

print(f'製品一覧(product_list):\n{product_list}\n')
print(f'品質実績(quality_result):\n{quality_result}\n')

# インデックスを使ってマージ（左：インデックスを使用、右：列名を指定）
result_df = pd.merge(product_list, quality_result,
                     left_index=True, right_on='serial_no')

print(f'インデックスを使ってマージ（左：インデックス、右：列名）\n{result_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="">【実行結果】
製品一覧(product_list):
          customer_id product_code
serial_no                         
A001            cid_1          p_a
B001            cid_1          p_b
C001            cid_2          p_c
C002            cid_2          p_c
D001            cid_3          p_d

品質実績(quality_result):
  serial_no  quality
0      A001      100
1      B001      200
2      C001      300
3      C002      400
4      D001      500

インデックスを使ってマージ（左：インデックス、右：列名）
  customer_id product_code serial_no  quality
0       cid_1          p_a      A001      100
1       cid_1          p_b      B001      200
2       cid_2          p_c      C001      300
3       cid_2          p_c      C002      400
4       cid_3          p_d      D001      500</pre>



<p class="wp-block-paragraph">上記例では、左側となる製品一覧は、DataFrameのインデックスを使用し、右側となる品質情報は、列名をキーとして結合しています。このようにインデックスや列名を混在させて、柔軟に結合することが可能です。</p>



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



<p class="wp-block-paragraph">pandasの<span class="marker"><strong>DataFrameを結合する方法</strong></span>について解説しました。</p>



<p class="wp-block-paragraph">pandasでは、DataFrameの結合方法として<span class="marker"><strong><code>merge</code></strong></span>関数や<span class="marker"><strong><code>join</code></strong></span>メソッドが用意されています。結合時には、1対1、多対1、多対多といったことを考慮して結合をすることが適切な結合のためには重要です。それぞれのパターンに関する結合を例を使って紹介しました。</p>



<p class="wp-block-paragraph">また、<code>merge</code>関数で結合する際のキーの指定は非常に重要です。列名を指定する<code>on</code>、<code>left_on</code>、<code>right_on</code>やインデックスで結合する<code>left_index=True</code>、<code>right_index=True</code>といった指定方法について説明しました。</p>



<p class="wp-block-paragraph">データ分析では、異なるデータソースのデータを適切に結合できることが、データから深い知見を得るために必要不可欠です。是非、<code>merge</code>関数や<code>join</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 class="wp-block-paragraph"><code>merge</code> 関数の公式ドキュメントは<a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.merge.html" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。<br><code>join</code> メソッドの公式ドキュメントは<a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.join.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 class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/pandas/dataframe-merge-join" 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-merge-join/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Python】文字列を連結・結合する方法</title>
		<link>https://tech.nkhn37.net/python-str-join/</link>
					<comments>https://tech.nkhn37.net/python-str-join/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 00:00:00 +0000</pubDate>
				<category><![CDATA[文字列]]></category>
		<category><![CDATA[join]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=1459</guid>

					<description><![CDATA[Python で文字列を連結・結合する方法について解説します。 文字列を連結・結合する方法 プログラミングでは、文字列の扱いは非常に重要です。文字列操作の中でも、文字列を連結・結合する場面には頻繁に直面します。 この記事 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Python で<span class="jinr-d--text-color d--marker1 d--bold">文字列を連結・結合する方法</span>について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">文字列を連結・結合する方法</h2>



<p class="wp-block-paragraph">プログラミングでは、文字列の扱いは非常に重要です。文字列操作の中でも、文字列を連結・結合する場面には頻繁に直面します。</p>



<p class="wp-block-paragraph">この記事では、Python で<span class="jinr-d--text-color d--marker1 d--bold">文字列を連結・結合する方法</span>について紹介します。</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 class="wp-block-paragraph">類似処理のファイルパス組み立ての場合については「<a href="https://tech.nkhn37.net/python-filepath-join/" target="_blank" rel="noreferrer noopener">ファイルパスを組み立てる方法</a>」を参考にしてください。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">文字列を連結・結合する</h3>



<h4 class="wp-block-heading jinr-heading d--bold">複数の文字列を連結・結合する方法</h4>



<p class="wp-block-paragraph">複数の文字列を連結・結合する場合には「<span class="jinr-d--text-color d--marker1 d--bold"><code>+</code> 演算子</span>」「<span class="jinr-d--text-color d--marker1 d--bold"><code>+=</code> 演算子</span>」「<span class="jinr-d--text-color d--marker1 d--bold">文字列リテラルの列挙</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="">s1 = "a"
s2 = "b"
s3 = "c"

# +演算子で文字列を連結・結合する
temp_str = s1 + s2 + s3
print(temp_str)

# +=演算子で文字列を連結・結合する
s4 = "d"
temp_str += s4
print(temp_str)

# 文字列リテラルを連続して列挙して連結・結合する
temp_str = "e" "f" "g"
print(temp_str)</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="">【実行結果】
abc
abcd
efg</pre>



<p class="wp-block-paragraph">例のように複数文字列を <code>+</code> 演算子や <code>+=</code> 演算子によって連結・結合できます。また、文字列リテラルを単純に並べるだけでも連結・結合が可能です。文字列リテラルの列挙の場合は、間にスペースやバックスラッシュによる改行があっても問題ありません。</p>



<h4 class="wp-block-heading jinr-heading d--bold">数値と文字列を連結・結合する方法</h4>



<p class="wp-block-paragraph">数値と文字列を連結・結合する場合には、型が異なるため単純に <code>+</code> 演算子は適用できません。そのまま連結・結合しようとすると <code>TypeError</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="">s1 = "a"
n1 = 100

# そのまま連結・結合しようとするとエラーとなる
temp_str = s1 + "_" + n1
print(temp_str)</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="">【実行結果】
TypeError: can only concatenate str (not "int") to str</pre>



<p class="wp-block-paragraph">このエラーを解決するには、以下のように型を揃えて実行します。</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="">s1 = "a"
n1 = 100

# +演算子で文字列と数値を連結・結合する
temp_str = s1 + "_" + str(n1)
print(temp_str)

# +=演算子で文字列を連結・結合する
n2 = 0.01
temp_str += "_"
temp_str += str(n2)
print(temp_str)

# formatを使用して連結・結合する
temp_str = "{}_{}".format(s1, n1)
print(temp_str)

# f-stringを使用して連結・結合する
temp_str = f"{s1}_{n1:05}_{n2:.5f}"
print(temp_str)</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="">【実行結果】
a_100
a_100_0.01
a_100
a_00100_0.01000</pre>



<p class="wp-block-paragraph">例では、<code>str</code> を使うことで数値を文字列に変換してから <code>+</code> 演算子等を使うことで数値と文字列を結合しています。</p>



<p class="wp-block-paragraph">また、<code>format</code> や <code>f-string</code> を使用して連結することで数値のフォーマットを変えつつ結合するも可能です。<code>format</code> や <code>f-string</code> については「<a href="https://tech.nkhn37.net/python-str-format-f-string/" target="_blank" rel="noreferrer noopener">文字列のフォーマットを整える方法</a>」を参考にしてください。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--heading-iconbox1 ">
			<div class="a--heading-iconbox-title">
			<div class="a--iconbox-title-icon"><i class="jif jin-ifont-caution" aria-hidden="true"></i></div>
			<div class="a--iconbox-title-text">注意点</div>
			</div>
			<div class="a--jinr-iconbox">
<p class="wp-block-paragraph"><code>+</code> 演算子、<code>+=</code> 演算子、文字列リテラルの列挙といった連結・結合方法は、少ない数の文字列の連結・結合では可読性も高く、適した方法です。しかし、結合の数が多くなるとパフォーマンスが低下することがあります。このような時には、後述する <code>join</code> メソッドを使用する方が適切です。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">リストを連結・結合して文字列にする方法</h3>



<p class="wp-block-paragraph">リストの文字列や数値を連結・結合して文字列にする場合には、<code>str</code> の <span class="jinr-d--text-color d--marker1 d--bold"><code>join</code></span> メソッドを使用します。<code>join</code> は、非常に効率的な連結・結合方法で Python では頻繁に用います。特に、多くの文字列を連結・結合する場合には効果的です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">文字列のリストを文字列に連結・結合する方法</h4>



<p class="wp-block-paragraph"><code>join</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="">sample_list = ["Pytho", "Java", "Go", "C", "C#"]

# 文字列をそのまま結合
print("".join(sample_list))

# 区切り文字でjoinで結合
print(",".join(sample_list))</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="">【実行結果】
PythoJavaGoCC#
Pytho,Java,Go,C,C#</pre>



<p class="wp-block-paragraph">文字列を単純につなげたい場合は、空文字 (<code>""</code>) の <code>join</code> メソッドに連結・結合したい対象リストを渡すことで結合できます。</p>



<p class="wp-block-paragraph">区切り文字を指定する場合は、区切り文字の文字列の <code>join</code> メソッドに結合対象リストを渡します。例えば、<code>","</code> (カンマ) を区切り文字として結合したい場合は「<code>",".join(sample_list)</code>」とします。もちろん他の区切り文字も使用できます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">数値リストを文字列に連結・結合する方法</h4>



<p class="wp-block-paragraph">数値リストに対して単純に <code>join</code> を適用してしまうと <code>TypeError</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="">sample_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 数値リストをjoinでそのまま連結することはできない
print(",".join(sample_list))</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="">【実行結果】
TypeError: sequence item 0: expected str instance, int found</pre>



<p class="wp-block-paragraph">数値リストを <code>join</code> で結合する場合には、以下のように数値リストを <code>str</code> で文字列に変換してから <code>join</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="">sample_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 数値リストをjoinで結合する場合はstrに変換してからjoinに渡す
print(",".join([str(i) for i in sample_list]))</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="">【実行結果】
1,2,3,4,5,6,7,8,9,10</pre>



<p class="wp-block-paragraph">例のようにリスト内包表記を使ってまとめて作成すると簡単です。リスト内包表記については「<a href="https://tech.nkhn37.net/python-list-comprehension/" target="_blank" rel="noreferrer noopener">リスト（list）内包表記の使い方</a>」を参考にしてください。</p>



<h4 class="wp-block-heading jinr-heading d--bold">異なる型のオブジェクトを含むリストを文字列に連結・結合する方法</h4>



<p class="wp-block-paragraph">上記では、文字列だけ含むリスト、数値だけ含むリストを中心に扱ってきましたが、Python では異なる型のオブジェクトを含むリストを扱うことが可能です。</p>



<p class="wp-block-paragraph">ほとんどの型は <code>str</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="">class CustomClass1:
    pass


class CustomClass2:
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return f"&lt;CustomClass2 value={self.value}>"


# 様々な型が混在している場合
sample_list = [1, 2, "a", "b", CustomClass1(), CustomClass2(123), 8.0, 9.0]

# strで文字列に変換ができれば結合可能
print(",".join([str(i) for i in sample_list]))</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="">【実行結果例】
1,2,a,b,&lt;__main__.CustomClass1 object at 0x00000249B9E5A190>,&lt;CustomClass2 value=123>,8.0,9.0</pre>



<p class="wp-block-paragraph"><code>sample_list</code> は、複数の型のオブジェクトを含んでいます。開発者が定義したようなカスタムクラスでも、自動的に <code>__str__</code> メソッドが提供されるため <code>CustomClass1</code> クラスに <code>str</code> を適用した場合は「<code>&lt;main.CustomClass1 object at 0x00000249B9E5A190></code>」のような文字列で表示され、基本的には問題は起こりません。</p>



<p class="wp-block-paragraph">また、<code>CustomClass2</code> では、開発者が <code>__str__</code> メソッドを個別にオーバーライドして定義しています。例では文字列を適切に返却しているので問題は起こりませんが、仮に <code>None</code> のようなコードを書いてしまうと <code>TypeError</code> が発生するので注意してください。</p>



<p class="wp-block-paragraph">異なる型を含むリストを扱う場合には、型チェックや例外処理を十分意識する必要があります。また、<code>__str__</code> を個別実装するような場合には、<code>None</code> を返してしまったり、予期しない例外を発生させないように十分注意し、利用者に伝わりやすい簡潔な文字列表現を返却するように十分検討するようにしてください。</p>



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



<p class="wp-block-paragraph">Python で<span class="jinr-d--text-color d--marker1 d--bold">文字列を連結・結合する方法</span>について解説しました。</p>



<p class="wp-block-paragraph"><code>+</code> 演算子や <code>+=</code> 演算子を使って単純に連結・結合する方法や <code>join</code> メソッドについて例を使って使い方を説明しました。</p>



<p class="wp-block-paragraph">少ない数の連結・結合では、<code>+</code> 演算子や <code>+=</code> 演算子を使った方が可読性も高く、適していますが、数が多くなる場合にはより効率的に処理が可能な <code>join</code> メソッドを使用することを検討してください。</p>



<p class="wp-block-paragraph">文字列の連結・結合はプログラミングにおいては頻繁に出てきます。使い方をしっかり覚えて効率よく文字列の連結・結合をしてもらえればと思います。</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 class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-basic/string/join" 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/python-str-join/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-06-14 21:57:17 by W3 Total Cache
-->