<?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>「read」タグの記事一覧Python Tech</title>
	<atom:link href="https://tech.nkhn37.net/tag/read/feed/" rel="self" type="application/rss+xml" />
	<link>https://tech.nkhn37.net</link>
	<description>Python学習サイト</description>
	<lastBuildDate>Wed, 24 Dec 2025 21:17:17 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://tech.nkhn37.net/wp-content/uploads/2021/01/cropped-lion-normal-clear-1-32x32.png</url>
	<title>「read」タグの記事一覧Python Tech</title>
	<link>https://tech.nkhn37.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【PySpark】日付フォルダで分割してデータを入出力する方法 partitionBy</title>
		<link>https://tech.nkhn37.net/pyspark-write-partitionby-date/</link>
					<comments>https://tech.nkhn37.net/pyspark-write-partitionby-date/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Thu, 21 Dec 2023 20:00:00 +0000</pubDate>
				<category><![CDATA[PySpark]]></category>
		<category><![CDATA[delta lake]]></category>
		<category><![CDATA[partitionby]]></category>
		<category><![CDATA[read]]></category>
		<category><![CDATA[save]]></category>
		<category><![CDATA[write]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=9912</guid>

					<description><![CDATA[PySpark でデータを保存する際に、日付フォルダで分割してデータを入出力する方法を解説します。 データを日付フォルダに分割して保存 PySpark で DataFrame の入出力を行う際は write やread  [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">PySpark で<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">PySpark で DataFrame の入出力を行う際は <code>write</code> や<code>read</code> メソッドを使用します。PySpark での DataFrame の基本的な入出力方法については「<a href="https://tech.nkhn37.net/pyspark-dataframe-read-write/" data-type="link" data-id="https://tech.nkhn37.net/pyspark-dataframe-read-write/" target="_blank" rel="noreferrer noopener">DataFrameの入出力 read, write</a>」を参考にしてください。</p>



<p class="wp-block-paragraph">データレイク（例：Amazon S3、Azure ADLS等）において、特に大量のデータを管理している際、日付フォルダにデータを分割して保存することは、クエリのパフォーマンス向上などの観点で重要な方法です。</p>



<p class="wp-block-paragraph">この記事では、PySpark において<span class="jinr-d--text-color d--marker1 d--bold">日付フォルダでデータを効率的に分割して入出力する方法</span>を紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">データのフォルダ分割と保存：メリットと注意点</h3>



<p class="wp-block-paragraph">データをフォルダ分割して保存して扱うメリットや注意するべき点を紹介します。考え方を十分理解されている方は読み飛ばしていただいて構いません。</p>



<h4 class="wp-block-heading jinr-heading d--bold">メリット</h4>



<p class="wp-block-paragraph">データレイクでデータを扱う場合、効率的に管理できるようフォルダ構成をよく検討することが重要です。扱うデータの特徴により適切な構成は異なりますが、例えば、時系列データ保存では、日付ごとフォルダを分ける方法はベストプラクティスの 1 つです。</p>



<p class="wp-block-paragraph">日付ごとフォルダを分けてデータ管理することは、以下のようなメリットがあります。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>内容</th></tr></thead><tbody><tr><td>クエリのパフォーマンス向上</td><td>日付ごとにデータを分けることで、特定の日付範囲のクエリの実行時間を短縮できます。</td></tr><tr><td>データ整理／管理の簡素化</td><td>日付ごとにデータを分けることで、データの所在が明確になり、管理が容易になります。</td></tr><tr><td>スケーラビリティの向上</td><td>大規模データセットの効率的な分散処理が可能になります。</td></tr><tr><td>データ追加／更新の容易さ</td><td>特定の日付データのみを効率的に追加・更新できます。</td></tr><tr><td>コスト削減</td><td>データ取得量で従量課金されるクラウドサービスを使用する場合に、不要なデータ取得を避けることでコストを削減できます。</td></tr></tbody></table></figure>



<h4 class="wp-block-heading jinr-heading d--bold">注意するべき点</h4>



<h5 class="wp-block-heading jinr-heading d--bold">分割単位について十分な検討が必要</h5>



<p class="wp-block-paragraph">フォルダ分割単位は 年、月、日、時間などいくつか検討できます。どういった単位で分割するかは、その後のデータ活用方法に応じて十分検討するべきです。いくつかの一般的なケースと階層分けの考え方を紹介します。</p>



<ol class="wp-block-list jinr-list">
<li>年単位（year=YYYY/）：年単位でデータ集計したい場合に適しています。</li>



<li>月単位（year=YYYY/month=MM/）：月単位でデータ集計したい場合に適しています。BI では、各種データを月集計するケースが多いため、このような時に向いています。</li>



<li>日単位（year=YYYY/month=MM/day=DD/）：日単位でデータ集計したい場合に適しています。</li>
</ol>



<h5 class="wp-block-heading jinr-heading d--bold">最適な分割方法を選択する</h5>



<p class="wp-block-paragraph">日付フォルダ分割は、一般的に時系列データに適していますが、すべてのデータに最適とは限りません。日付分割ではなく、他の目的に沿った意味のフォルダで整理した方がよい場合もあります。</p>



<p class="wp-block-paragraph">また、どの階層まで分割するかも検討が必要です。例えば、データ量が多い時に分割単位を細かくしすぎると小さなファイルが多数生成される可能性があり、ファイルシステムに負荷をかける可能性があります。逆に、分割単位が大きい場合、読み込むファイルサイズが大きくなり、パフォーマンスに影響が起こる可能性もあります。</p>



<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">Microsoft Azure Data Lake Storage Gen2 のベストプラクティスにデータ構造検討のための情報があるので参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://learn.microsoft.com/ja-jp/azure/storage/blobs/data-lake-storage-best-practices" target="_blank" rel="noreferrer noopener">Azure Data Lake Storage Gen2 の使用に関するベスト プラクティス</a></p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">PySpark で日付フォルダに分割してデータを入出力する方法</h3>



<p class="wp-block-paragraph">PySpark を使用して日付に基づいてデータを効率的に分割し、管理するための実践的な手法を順を追って説明します。</p>



<h4 class="wp-block-heading jinr-heading d--bold">使用するデータの用意</h4>



<p class="wp-block-paragraph">使用するサンプルデータを以下のコードにより生成します。このデータは、2023/10/1 ~ 2024/3/31 までで 1 時間毎に収集されるデータとして、sin 波にノイズを加えた時系列データを想定しています。例えば、ある設備の計測器からのデータと考えると分かりやすいでしょう。</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
import numpy as np
import matplotlib.pyplot as plt

# サンプル時系列データの生成 (1時間毎データ)
h_range = pd.date_range(start="2023-10-01", end="2024-03-31 23:00:00", freq="H")
hours = np.arange(len(h_range))

# サンプルデータを生成 (週周期で時間単位のsin波)
sin_wave = np.sin(hours / (7 * 24))
# ランダムノイズを生成
noise = np.random.normal(0, 0.3, len(h_range))
# 波形にランダムノイズを付与
measurement_values = sin_wave + noise

# 描画
plt.figure(figsize=(12, 6))
plt.plot(h_range, measurement_values, label='Measurement with Noise')
plt.title('Hourly Measurement Values Over Time')
plt.xlabel('Date and Time')
plt.ylabel('Measurement Value')
plt.legend()
plt.grid(True)
plt.show()</pre>



<p class="wp-block-paragraph"><strong>描画結果</strong></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="1024" height="541" src="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-16-1024x541.png" alt="サンプルデータ" class="wp-image-9941" srcset="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-16-1024x541.png 1024w, https://tech.nkhn37.net/wp-content/uploads/2023/12/image-16-300x159.png 300w, https://tech.nkhn37.net/wp-content/uploads/2023/12/image-16-768x406.png 768w, https://tech.nkhn37.net/wp-content/uploads/2023/12/image-16.png 1031w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">結果として生成されるデータは上記のようになります。以降の例では、このデータを日付をベースに分割してデータを入出力する例を説明していきます。</p>



<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>write.partitionBy</code></span> を使用します。なお、<code>write</code> の基本的な使い方が分からない方は「<a href="https://tech.nkhn37.net/pyspark-dataframe-read-write/" data-type="link" data-id="https://tech.nkhn37.net/pyspark-dataframe-read-write/" target="_blank" rel="noreferrer noopener">DataFrameの入出力 read, write</a>」を参照してください。</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.functions import dayofmonth, month, year

# Sparkセッションの初期化
spark = SparkSession.builder.appName("partition_example").getOrCreate()

# pandasのDataFrameを作成
pandas_df = pd.DataFrame({
    "datetime": h_range,
    "measurement": measurement_values
}    
)
# Spark DataFrameに変換
df = spark.createDataFrame(pandas_df)
# 年・月・日の列を作成しておく
df = df.withColumn("year", year("datetime"))
df = df.withColumn("month", month("datetime"))
df = df.withColumn("day", dayofmonth("datetime"))
df.show()

# 年単位でパーティション分割して保存
df.write.mode("overwrite").partitionBy("year").parquet("./yearly")

# 月単位でパーティション分割して保存
df.write.mode("overwrite").partitionBy("year", "month").parquet("./monthly")

# 日単位でパーティション分割して保存
df.write.mode("overwrite").partitionBy("year", "month", "day").parquet("./daily")</pre>



<p class="wp-block-paragraph">上記プログラムでは、まず pandas の DataFrame を作成し、それを Spark の DataFrame に変換しています。その後に <code>datetime</code> 列から <code>year</code>, <code>month</code>, <code>day</code> の情報を抽出して列を追加し、これらを基にデータを分割して保存します。</p>



<p class="wp-block-paragraph">ファイルを書き込む <code>write.partitionBy</code> で基準とする列名を指定します。年月日で階層構造を作って作成したい場合は「<code>,</code> (カンマ)」で区切って階層順に列を指定します。</p>



<p class="wp-block-paragraph">結果としては年は「year=YYYY」、月は「month=MM」、日は「day=DD」という形式のフォルダが作成され、各フォルダに <code>parquet</code> ファイルが出力されます。出力ファイル数は Spark ノードに依存するため複数ファイル出力される場合があります。</p>



<p class="wp-block-paragraph"><strong>年単位フォルダでの保存</strong></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="495" height="98" src="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-12.png" alt="" class="wp-image-9920" srcset="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-12.png 495w, https://tech.nkhn37.net/wp-content/uploads/2023/12/image-12-300x59.png 300w" sizes="(max-width: 495px) 100vw, 495px" /></figure>
</div>


<p class="wp-block-paragraph"><strong>月単位フォルダでの保存</strong></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="491" height="286" src="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-13.png" alt="" class="wp-image-9921" srcset="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-13.png 491w, https://tech.nkhn37.net/wp-content/uploads/2023/12/image-13-300x175.png 300w" sizes="(max-width: 491px) 100vw, 491px" /></figure>
</div>


<p class="wp-block-paragraph"><strong>日単位フォルダでの保存</strong></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="500" height="272" src="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-14.png" alt="" class="wp-image-9922" srcset="https://tech.nkhn37.net/wp-content/uploads/2023/12/image-14.png 500w, https://tech.nkhn37.net/wp-content/uploads/2023/12/image-14-300x163.png 300w" sizes="(max-width: 500px) 100vw, 500px" /></figure>
</div>


<h4 class="wp-block-heading jinr-heading d--bold">データを読み込む方法</h4>



<p class="wp-block-paragraph">日付フォルダで分割したファイルを読み込む際には <code>read</code> メソッドを使用します。いくつかのパターンでの読み込み例を紹介します。</p>



<h5 class="wp-block-heading jinr-heading d--bold">特定のフォルダを指定して読み込む場合</h5>



<p class="wp-block-paragraph">特定の年月のフォルダを指定して読み込む場合は、以下のように対象フォルダを <code>read.parquet</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_read = spark.read.parquet("./monthly/year=2023/month=10")

# ソートしてから表示
df_read = df_read.sort(df_read.datetime)
df_read.show(5)
df_read.orderBy(df_read.datetime, ascending=False).show(5)</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="">【実行結果】
+-------------------+--------------------+---+
|           datetime|         measurement|day|
+-------------------+--------------------+---+
|2023-10-01 00:00:00| 0.14901424590336979|  1|
|2023-10-01 01:00:00|-0.03552694454855405|  1|
|2023-10-01 02:00:00| 0.20621104213982733|  1|
|2023-10-01 03:00:00|  0.4747651507543513|  1|
|2023-10-01 04:00:00|-0.04643873812079383|  1|
+-------------------+--------------------+---+
only showing top 5 rows

+-------------------+-------------------+---+
|           datetime|        measurement|day|
+-------------------+-------------------+---+
|2023-10-31 23:00:00|-0.9504823233260842| 31|
|2023-10-31 22:00:00|-1.1440374606662784| 31|
|2023-10-31 21:00:00|-1.3387133335934447| 31|
|2023-10-31 20:00:00|-1.5053170384963321| 31|
|2023-10-31 19:00:00|  -0.64692450768512| 31|
+-------------------+-------------------+---+
only showing top 5 rows</pre>



<p class="wp-block-paragraph">上記では、読み込んだ先頭と末尾の 5 行を出力していますが、指定した月のファイルが読み込めていることが分かるかと思います。月の例で紹介していますが、年や日の分割をした場合についても同様です。</p>



<h5 class="wp-block-heading jinr-heading d--bold">フォルダ配下をまとめて読み込む場合</h5>



<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_read = spark.read.parquet("./monthly/year=2023")
# df_read = spark.read.parquet("./monthly/year=2023/*")

# ソートしてから表示
df_read = df_read.sort(df_read.datetime)
df_read.show(5)
df_read.orderBy(df_read.datetime, ascending=False).show(5)</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="">【実行結果】
+-------------------+--------------------+---+-----+
|           datetime|         measurement|day|month|
+-------------------+--------------------+---+-----+
|2023-10-01 00:00:00| 0.14901424590336979|  1|   10|
|2023-10-01 01:00:00|-0.03552694454855405|  1|   10|
|2023-10-01 02:00:00| 0.20621104213982733|  1|   10|
|2023-10-01 03:00:00|  0.4747651507543513|  1|   10|
|2023-10-01 04:00:00|-0.04643873812079383|  1|   10|
+-------------------+--------------------+---+-----+
only showing top 5 rows

+-------------------+-------------------+---+-----+
|           datetime|        measurement|day|month|
+-------------------+-------------------+---+-----+
|2023-12-31 23:00:00| 0.6467656757056162| 31|   12|
|2023-12-31 22:00:00| 0.9802973425873306| 31|   12|
|2023-12-31 21:00:00| 0.6717463226887521| 31|   12|
|2023-12-31 20:00:00|0.23803665242220395| 31|   12|
|2023-12-31 19:00:00| 0.1319102042628495| 31|   12|
+-------------------+-------------------+---+-----+
only showing top 5 rows</pre>



<p class="wp-block-paragraph">年フォルダ配下をまとめて指定する場合は、上記のように <code>"./monthly/year=2023"</code> といった形で年フォルダを指定します。また、ワイルドカードでの読み込みもできるので <code>"./monthly/year=2023/*" </code>としても同様です。</p>



<h5 class="wp-block-heading jinr-heading d--bold">他のサブディレクトリやファイルがある場合</h5>



<p class="wp-block-paragraph">フォルダ配下をまとめて指定する場合で、他のサブディレクトリやファイルがある場合には、ワイルドカードを使用できます。例えば、任意の月フォルダを <code>month=*</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_read = spark.read.parquet("./monthly/year=2023/month=*")

# ソートしてから表示
df_read = df_read.sort(df_read.datetime)
df_read.show(5)
df_read.orderBy(df_read.datetime, ascending=False).show(5)</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="">【実行結果】
+-------------------+--------------------+---+
|           datetime|         measurement|day|
+-------------------+--------------------+---+
|2023-10-01 00:00:00| 0.14901424590336979|  1|
|2023-10-01 01:00:00|-0.03552694454855405|  1|
|2023-10-01 02:00:00| 0.20621104213982733|  1|
|2023-10-01 03:00:00|  0.4747651507543513|  1|
|2023-10-01 04:00:00|-0.04643873812079383|  1|
+-------------------+--------------------+---+
only showing top 5 rows

+-------------------+-------------------+---+
|           datetime|        measurement|day|
+-------------------+-------------------+---+
|2023-12-31 23:00:00| 0.6467656757056162| 31|
|2023-12-31 22:00:00| 0.9802973425873306| 31|
|2023-12-31 21:00:00| 0.6717463226887521| 31|
|2023-12-31 20:00:00|0.23803665242220395| 31|
|2023-12-31 19:00:00| 0.1319102042628495| 31|
+-------------------+-------------------+---+
only showing top 5 rows</pre>



<h5 class="wp-block-heading jinr-heading d--bold">いくつかの特定フォルダを複数読み込む場合</h5>



<p class="wp-block-paragraph">フォルダ配下のいくつかのフォルダを複数読み込む場合は、以下のようにそれぞれのフォルダを読み込み <code>union</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=""># いくつかの特定フォルダを複数読み込む場合
df1 = spark.read.parquet("./monthly/year=2023/month=11")
df2 = spark.read.parquet("./monthly/year=2023/month=12")
df_read = df1.union(df2)

# ソートしてから表示
df_read = df_read.sort(df_read.datetime)
df_read.show(5)
df_read.orderBy(df_read.datetime, ascending=False).show(5)</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="">【実行結果】
+-------------------+-------------------+---+
|           datetime|        measurement|day|
+-------------------+-------------------+---+
|2023-11-01 00:00:00|-0.8046957296660957|  1|
|2023-11-01 01:00:00|-1.1793663638979297|  1|
|2023-11-01 02:00:00|-0.9072289030283197|  1|
|2023-11-01 03:00:00| -1.191455395525611|  1|
|2023-11-01 04:00:00| -1.149843255157325|  1|
+-------------------+-------------------+---+
only showing top 5 rows

+-------------------+-------------------+---+
|           datetime|        measurement|day|
+-------------------+-------------------+---+
|2023-12-31 23:00:00| 0.6467656757056162| 31|
|2023-12-31 22:00:00| 0.9802973425873306| 31|
|2023-12-31 21:00:00| 0.6717463226887521| 31|
|2023-12-31 20:00:00|0.23803665242220395| 31|
|2023-12-31 19:00:00| 0.1319102042628495| 31|
+-------------------+-------------------+---+
only showing top 5 rows</pre>



<h3 class="wp-block-heading jinr-heading d--bold">Delta Lake を使用する場合</h3>



<p class="wp-block-paragraph">Delta Lake を使う場合も基本的には同じ考え方で使用することができます。Delta Lake は、データレイク上で ACID 特性を提供し、スケーラブルで安全なデータ処理、管理を提供するための機能レイヤーでレイクハウス実装で活用できる技術です。</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">Delta Lake の概要や基本的な使い方の基本については「<a href="https://tech.nkhn37.net/pyspark-delta-lake/" data-type="link" data-id="https://tech.nkhn37.net/pyspark-delta-lake/" target="_blank" rel="noreferrer noopener">Delta Lakeの使い方の基本</a>」にまとめていますので興味があれば参考にしてください。</p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold">日付フォルダでデータを分割して出力する</h4>



<p class="wp-block-paragraph">Delta Lake 版に書き換えたプログラムは以下になります。これまで紹介してきたプログラムとの変化点は 2 点です。DataFrame の操作に関わる部分に変更はありません。</p>



<ol class="wp-block-list jinr-list">
<li>Spark セッション初期化の際に Delta Lake のための <code>config</code> を設定</li>



<li>保存の際に <code>format("delta")</code>を指定し、<code>parquet</code> を <code>save</code> に変更</li>
</ol>



<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 delta import configure_spark_with_delta_pip
from pyspark.sql.functions import dayofmonth, month, year

# Sparkセッションの初期化
builder = (
    SparkSession.builder.appName("partition_example")
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension")
    .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog")
)
# Delta Lakeで動作するように設定
spark = configure_spark_with_delta_pip(builder).getOrCreate()

# pandasのDataFrameを作成
pandas_df = pd.DataFrame({
    "datetime": h_range,
    "measurement": measurement_values
}    
)
# Spark DataFrameに変換
df = spark.createDataFrame(pandas_df)
# 年・月・日の列を作成しておく
df = df.withColumn("year", year("datetime"))
df = df.withColumn("month", month("datetime"))
df = df.withColumn("day", dayofmonth("datetime"))
df.show()

# 年単位でパーティション分割して保存
df.write.format("delta").mode("overwrite").partitionBy("year").save("./yearly-delta")

# 月単位でパーティション分割して保存
df.write.format("delta").mode("overwrite").partitionBy("year", "month").save("./monthly-delta")

# 日単位でパーティション分割して保存
df.write.format("delta").mode("overwrite").partitionBy("year", "month", "day").save("./daily-delta")</pre>



<p class="wp-block-paragraph">実行すると Delta Lake としてファイルが保存されます。<code>parquet</code> でデータが保存されるとともに <code>_delta_log</code> というフォルダが生成されます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">データを読み込む方法</h4>



<p class="wp-block-paragraph">Delta Lake 版でデータを読み込む場合の変化としては、読み込みの際に <code>format("delta")</code> を指定し、<code>parquet</code> を <code>load</code> に変更します。上記で見てきた読み込みのパターンで見てみましょう。実行結果は変わらないため省略します。</p>



<p class="wp-block-paragraph">なお、Delta Lake はワイルドカード指定をサポートしていない点に注意が必要です。（※Delta Lake のバージョンにより異なる可能性があります）</p>



<h5 class="wp-block-heading jinr-heading d--bold">特定のフォルダを指定して読み込む場合</h5>



<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_read = spark.read.format("delta").load("./monthly-delta/year=2023/month=10")</pre>



<h5 class="wp-block-heading jinr-heading d--bold">フォルダ配下をまとめて読み込む場合</h5>



<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_read = spark.read.format("delta").load("./monthly-delta/year=2023")</pre>



<h5 class="wp-block-heading jinr-heading d--bold">他のサブディレクトリやファイルがある場合</h5>



<p class="wp-block-paragraph">他のサブディレクトリがある場合、Delta Lake ではワイルドカード指定できないため、<code>month=*</code> のような指定ができません。そのため、以降で紹介するように複数フォルダをそれぞれ読み込んで <code>union</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=""># いくつかのフォルダを複数読み込む場合
df1 = spark.read.format("delta").load("./monthly-delta/year=2023/month=11")
df2 = spark.read.format("delta").load("./monthly-delta/year=2023/month=12")
df_read = df1.union(df2)</pre>



<p class="wp-block-paragraph">レイクハウス構築の際には、Delta Lake の技術を採用する場合もあると思うので、使い方を覚えておくと良いかと思います。</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">データを保存する際に、日付フォルダで分割してデータを保存する方法</span>を解説しました。</p>



<p class="wp-block-paragraph">データレイク（例：Amazon S3、Azure ADLS等）において、特に大量のデータを管理している際、日付フォルダにデータを分割して保存することは重要な方法です。これにより、クエリのパフォーマンス向上など多くの利点があります。</p>



<p class="wp-block-paragraph">この記事では、簡単なサンプルデータを用意して、日付フォルダで分割して保存、読み込みを行う方法を実装例を用いて紹介しました。</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-data-analysis/pyspark/dataframe-write-partitionby" 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-write-partitionby-date/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【PySpark】DataFrameの入出力 read, write</title>
		<link>https://tech.nkhn37.net/pyspark-dataframe-read-write/</link>
					<comments>https://tech.nkhn37.net/pyspark-dataframe-read-write/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Tue, 31 Oct 2023 20:00:00 +0000</pubDate>
				<category><![CDATA[PySpark]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[DataFrame]]></category>
		<category><![CDATA[DataFrameReader]]></category>
		<category><![CDATA[DataFrameWriter]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[ORC]]></category>
		<category><![CDATA[Parquet]]></category>
		<category><![CDATA[read]]></category>
		<category><![CDATA[write]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=9652</guid>

					<description><![CDATA[PySpark での DataFrame の入出力方法を解説します。 DataFrameの入出力 PySpark は、分散処理フレームワーク Apache Spark の Python 用 API です。PySpark  [&#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">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">この記事では、<span class="jinr-d--text-color d--marker1 d--bold">PySpark で DataFrame を入出力する方法</span>を紹介します。データフォーマットとしては分析でよく使用される CSV、Parquet、ORC、JSON といった形式を扱います。</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>



<h3 class="wp-block-heading jinr-heading d--bold">ファイル形式</h3>



<p class="wp-block-paragraph">今回の入出力で扱うファイル形式 (CSV、Parquet、ORC、JSON) について説明してます。各ファイルに関して詳しい人は読み飛ばしていただいて結構です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">CSV ファイル</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">CSV (Comma-Separated Values)</span> ファイルは、データをテキストとして表現するシンプルなフォーマットの 1 つです。名前の通り、CSV ファイルのデータは「, (コンマ)」で区切られた値で構成されます。このフォーマットは、データベースやスプレッドシートからのデータのエクスポートやインポートに非常によく使われます。</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">この記事では、PySpark での入出力を紹介しますが、Python 標準や pandas での CSV 入出力は以下を参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://tech.nkhn37.net/python-csv/" target="_blank" rel="noreferrer noopener">【Python】CSVファイルの入出力</a></p>



<p class="wp-block-paragraph"><a href="https://tech.nkhn37.net/pandas-dataframe-csv/" target="_blank" rel="noreferrer noopener">【pandas】CSVファイルの入出力</a></p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold">Parquet ファイル</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">Parquet</span> ファイルは、データ分析でよく使用される列指向のストレージフォーマットです。大量のデータの効率的な読み取り、書き込み、および圧縮をサポートするため、大規模なデータ分析に適しています。</p>



<p class="wp-block-paragraph">Parquet ファイルは、バイナリフォーマットのため直接参照できませんが、データ加工の処理フローでは Parquet で効率よく処理し、データの利用ユーザーに公開する際に CSV ファイルにして提供するといったことも行われます。</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">この記事では、PySpark での入出力を紹介しますが、pandas での Parquet 入出力は以下を参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://tech.nkhn37.net/pandas-parquet/" target="_blank" rel="noreferrer noopener">【pandas】Parquetファイルの入出力</a></p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold">ORCファイル</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">ORC (Optimized Row Columnar)</span> ファイルは、主に Hadoop エコシステムで使用される列指向のストレージフォーマットの 1 つです。ORC は特に Hive のために設計されており、大量データの効率的な読み取り、書き込み、圧縮をサポートします。</p>



<p class="wp-block-paragraph">ORC は、特に Hive クエリのパフォーマンスを向上させることを目的として設計されているため、Hive を使用する場合は Hadoop エコシステムを中心にデータ処理する場合に適しているが多いです。また、他の SQL ベースのデータベースシステムやデータ処理フレームワークでも ORC フォーマットが利用されることがあります。</p>



<p class="wp-block-paragraph">Parquet と ORC のどちらを選択するかは、使用するツールやエコシステムの要件によって検討するのが適切です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">JSON ファイル</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">JSON (JavaScript Object Notation)</span> ファイルは、JavaScript の一部として生まれたファイルフォーマットですが、現在は多くのプログラミング言語でサポートされています。また、WebAPI（特に RESTful API）で、クライアントとサーバー間でデータをやり取りする際の標準的な手段として広く利用されています。</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">この記事では、PySpark での入出力を紹介しますが、json モジュールでの JSON 入出力については以下を参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://tech.nkhn37.net/python-json-dump-load/" target="_blank" rel="noreferrer noopener">【Python】JSONファイルの入出力</a></p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">ファイルの書き込み <code>write</code></h3>



<p class="wp-block-paragraph">PySpark の DataFrame の書き込みは、<span class="jinr-d--text-color d--marker1 d--bold"><code>write</code></span> メソッドで実行します。<code>write</code> は、<span class="jinr-d--text-color d--marker1 d--bold"><code>DataFrameWriter</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="">from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, StringType, IntegerType

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

# スキーマを定義
schema = StructType([
    StructField("name", StringType(), True),
    StructField("age", IntegerType(), True),
])

# データを作成
data = [("Taro", 25), ("Hanako", 30), ("Yuki", 20)]

# スキーマを指定してデータフレームを生成
df = spark.createDataFrame(data, schema=schema)

# CSVファイルへの書き込み
(df.write
    .option("header", "true")
    .mode("overwrite")
    .csv("./output_csv"))

# Parquetファイルへの書き込み
(df.write
    .mode("overwrite")
    .parquet("./output_parquet"))

# ORCファイルへの書き込み
(df.write
    .mode("overwrite")
    .orc("./output_orc"))

# JSONファイルへの書き込み
(df.write
    .mode("overwrite")
    .json("./output_json"))

# SparkSessionを終了
spark.stop()</pre>



<p class="wp-block-paragraph">出力結果例 (CSV ファイルの場合、他のフォーマットも同様)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="495" height="190" src="https://tech.nkhn37.net/wp-content/uploads/2023/10/image-21.png" alt="pyspark write csv 結果" class="wp-image-9682" srcset="https://tech.nkhn37.net/wp-content/uploads/2023/10/image-21.png 495w, https://tech.nkhn37.net/wp-content/uploads/2023/10/image-21-300x115.png 300w" sizes="(max-width: 495px) 100vw, 495px" /></figure>
</div>


<p class="wp-block-paragraph">例では、Spark のセッションを「<code>SparkSession.builder.appName("DataFrameInputOutput").getOrCreate()</code>」で初期化しています。<code>"DataFrameExample"</code> の部分は Spark アプリケーションの名前です。なお、<code>SparkSession</code> を終了する際は <code>stop()</code> を使用します。</p>



<p class="wp-block-paragraph">書き込みのための <code>write</code> は、書き込み対象の DataFrame を使って <code>df.write.csv("output_path")</code> のように使用します。<code>"output_path"</code> の部分にはファイルを出力するフォルダ名を指定します。なお、フォルダがない場合は作成されます。</p>



<p class="wp-block-paragraph">Parquet ファイルは <code>parquet</code> メソッド、ORC ファイルは <code>orc</code> メソッド、JSON ファイルは <code>json</code> メソッドというように各ファイルフォーマット名のメソッドが用意されています。また、以降で説明する <code>option</code> や <code>mode</code> といったメソッドと併用することで出力をコントロールできます。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>option</code> メソッド</h4>



<p class="wp-block-paragraph"><code>write</code> メソッドでは、<span class="jinr-d--text-color d--marker1 d--bold"><code>option</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=""># CSVファイルへの書き込み
(df.write
    .option("header", "true")
    .mode("overwrite")
    .csv("./output_csv"))</pre>



<p class="wp-block-paragraph">例では、<code>option</code> メソッドで <code>"header"</code> を <code>"true"</code> に設定し、ヘッダー行を出力するようにしています。</p>



<p class="wp-block-paragraph">Apache Spark の DataFrame の <code>option</code> メソッドは、様々な読み取りや書き込みオペレーションの設定を変更するためのキーと値のペアを指定する際に使用します。このメソッドは、主にファイルを読み込む <code>read</code> やファイルに書き込む <code>write</code> と組み合わせて使用されます。</p>



<p class="wp-block-paragraph">Parquet や ORC は、スキーマ情報を含むファイルフォーマットのため <code>header</code> の指定は必要ありません。なお、例では DataFrame を作成する際に <code>StructType</code> や<code>StructField</code> を使ってスキーマを明確に指定しています。</p>



<p class="wp-block-paragraph">PySpark では必ずしもスキーマを指定しなくても使えますが、スキーマ情報を指定しておくことでデータを適切に扱うことができるため、スキーマ情報を指定することをおすすめします。</p>



<p class="wp-block-paragraph"><code>"header"</code> 以外にも <code>option</code> には指定できるものがあるため調べてみてください。例えば、CSV ファイル書き込みでは <code>"delimiter"</code> 等のオプションを指定できます。</p>



<p class="wp-block-paragraph">PySparkでは <code>option</code> や後述する <code>mode</code> といったメソッドを例のようにチェーンでつなげる書き方が一般的に使用されます。改行する際には例のように <code>()</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">DataFrame の作成とスキーマ定義方法は「<a href="https://tech.nkhn37.net/pyspark-dataframe-create-and-schema/" data-type="link" data-id="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>mode</code> メソッド</h4>



<p class="wp-block-paragraph"><code>write</code> メソッドでは <span class="jinr-d--text-color d--marker1 d--bold"><code>mode</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=""># CSVファイルへの書き込み
(df.write
    .option("header", "true")
    .mode("overwrite")
    .csv("./output_csv"))</pre>



<p class="wp-block-paragraph">例では <code>"overwrite"</code> を指定してファイルを上書きしています。</p>



<p class="wp-block-paragraph"><code>mode</code> で指定できる代表的なモードは以下の通りです。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>モード</th><th>概要</th></tr></thead><tbody><tr><td><code>overwrite</code></td><td>既存のデータを上書きします。指定したパスにデータが存在する場合、それを削除して新しいデータを書き込みます。</td></tr><tr><td><code>append</code></td><td>既存のデータに追加します。指定したパスに既にデータが存在する場合、新しいデータをその後に追加します。</td></tr><tr><td><code>ignore</code></td><td>既存のデータが存在する場合、何も行わずに操作をスキップします。つまり、新しいデータの書き込みを行いません。</td></tr><tr><td><code>error</code> または <code>errorifexists</code></td><td>既存のデータが存在する場合、エラーをスローします。このモードがデフォルトの振る舞いです。</td></tr></tbody></table></figure>



<h4 class="wp-block-heading jinr-heading d--bold">複数ファイルに出力される理由</h4>



<p class="wp-block-paragraph">PySpark による出力すると出力結果例で見たように「<code>part-xxxxx.csv</code>」といった複数ファイルが出力されます。これは、Spark では分散環境で処理をしており、それぞれの処理ノードの各タスクで各パーティションを処理して書き込みを行っているからです。</p>



<p class="wp-block-paragraph">これらの理由を正確に理解するには Spark の Job やパーティション等の処理の概念を理解しておくことをおすすめします。「<a href="https://tech.nkhn37.net/spark-application-concept/" target="_blank" rel="noreferrer noopener">Sparkアプリケーションの概念を理解する</a>」で Spark アプリケーションの構成やデータ構造、処理概念についてまとめていますので参考にしてください。</p>



<h3 class="wp-block-heading jinr-heading d--bold">ファイルの読み込み <code>read</code></h3>



<p class="wp-block-paragraph">PySpark の DataFrame のデータ読み込みは <span class="jinr-d--text-color d--marker1 d--bold"><code>read</code></span> メソッドで実行します。<code>read</code> は、<span class="jinr-d--text-color d--marker1 d--bold"><code>DataFrameReader</code></span> クラスのメソッドとして実装されています。</p>



<p class="wp-block-paragraph">以下例は、上記の <code>write</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="">from pyspark.sql import SparkSession

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

# CSVファイルの読み込み
df_csv = (spark.read
                .option("header", "true")
                .option("inferSchema", "true")
                .csv("./output_csv"))
df_csv.printSchema()
df_csv.show()

# Parquetファイルへの書き込み
df_parquet = (spark.read
                    .parquet("./output_parquet"))
df_parquet.printSchema()
df_parquet.show()

# ORCファイルへの書き込み
df_orc = (spark.read
                .orc("./output_orc"))
df_orc.printSchema()
df_orc.show()

# JSONファイルへの書き込み
df_json = (spark.read
                .json("./output_json"))
df_json.printSchema()
df_json.show()

# SparkSessionを終了
spark.stop()</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
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)

+------+---+
|  name|age|
+------+---+
|Hanako| 30|
|  Taro| 25|
|  Yuki| 20|
+------+---+

root
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)

+------+---+
|  name|age|
+------+---+
|Hanako| 30|
|  Taro| 25|
|  Yuki| 20|
+------+---+

root
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)

+------+---+
|  name|age|
+------+---+
|Hanako| 30|
|  Taro| 25|
|  Yuki| 20|
+------+---+

root
 |-- age: long (nullable = true)
 |-- name: string (nullable = true)

+---+------+
|age|  name|
+---+------+
| 30|Hanako|
| 25|  Taro|
| 20|  Yuki|
+---+------+</pre>



<p class="wp-block-paragraph"><code>SparkSession</code> の部分の説明は、上記で説明しているため割愛します。<code>read</code> は、<code>SparkSession</code> を介して <code>spark.read.csv("file_path")</code> のように使用します。</p>



<p class="wp-block-paragraph">また、<code>option</code> メソッドと併用することで読み込みをコントロールできます。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>option</code> メソッド</h4>



<p class="wp-block-paragraph"><code>read</code> メソッドでは、<span class="jinr-d--text-color d--marker1 d--bold"><code>option</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=""># CSVファイルの読み込み
df_csv = (spark.read
                .option("header", "true")
                .option("inferSchema", "true")
                .csv("./output_csv"))
df_csv.printSchema()
df_csv.show()</pre>



<p class="wp-block-paragraph">例では <code>option</code> メソッドで <code>"header"</code> を <code>"true"</code> にすることで、ヘッダー行を読み込んでいます。また、CSV ファイルはスキーマ情報を持っていないため <code>"inferSchema"</code> を <code>option</code> で指定することでスキーマ情報を推定しながら読み込むことができます。 スキーマ情報は <code>printSchema</code> で確認できます。</p>



<p class="wp-block-paragraph">Parquet 等のファイルフォーマットはスキーマ情報を含むため <code>"header"</code> や <code>"inferSchema"</code> を指定する必要はありません。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>schema</code> メソッドによるスキーマ指定</h4>



<p class="wp-block-paragraph"><code>StructType</code> と <code>StructField</code> でスキーマを定義し <span class="jinr-d--text-color d--marker1 d--bold"><code>schema</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="">from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, StringType, IntegerType

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

# スキーマを定義
schema = StructType([
    StructField("name", StringType(), True),
    StructField("age", IntegerType(), True),
])

# CSVファイルの読み込み
df_csv = (spark.read
                .option("header", "true")
                .schema(schema)
                .csv("./output_csv"))
df_csv.printSchema()
df_csv.show()

# Parquetファイルへの書き込み
df_parquet = (spark.read
                    .schema(schema)
                    .parquet("./output_parquet"))
df_parquet.printSchema()
df_parquet.show()

# ORCファイルへの書き込み
df_orc = (spark.read
                .schema(schema)
                .orc("./output_orc"))
df_orc.printSchema()
df_orc.show()

# JSONファイルへの書き込み
df_json = (spark.read
                .schema(schema)
                .json("./output_json"))
df_json.printSchema()
df_json.show()

# SparkSessionを終了
spark.stop()</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
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)

+------+---+
|  name|age|
+------+---+
|Hanako| 30|
|  Taro| 25|
|  Yuki| 20|
+------+---+

root
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)

+------+---+
|  name|age|
+------+---+
|Hanako| 30|
|  Taro| 25|
|  Yuki| 20|
+------+---+

root
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)

+------+---+
|  name|age|
+------+---+
|Hanako| 30|
|  Taro| 25|
|  Yuki| 20|
+------+---+

root
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)

+------+---+
|  name|age|
+------+---+
|Hanako| 30|
|  Taro| 25|
|  Yuki| 20|
+------+---+
</pre>



<p class="wp-block-paragraph">スキーマを指定すると、データを読み込む際に PySpark が各フィールドのデータ型を推測する必要がなくなり、大きなデータセットを扱う際には読み込み時間の短縮が期待できます。</p>



<p class="wp-block-paragraph">また、データの正確性の保証や、エラーの早期発見ができますし、コード内にスキーマを明示することにより、他の開発者がコードを読む際の可読性が高まります。</p>



<h3 class="wp-block-heading jinr-heading d--bold">出力ファイルを 1 つに統合する方法 <code>coalesce</code>、<code>repartition</code></h3>



<p class="wp-block-paragraph">上記例では、出力ファイルが複数になりましたが、それは Spark が分散処理をしているためでした。また、ファイルの読み込み時は、複数ファイルになっていても問題なく読み込みが可能でした。</p>



<p class="wp-block-paragraph">しかし、利用者に提供する時など、場合によってはファイルをまとめた方が都合がよい場合があります。ファイルを 1 つに統合する方法についても見ておきましょう。</p>



<p class="wp-block-paragraph">なお、1 つにまとめる操作は、処理ノード間のデータ移動が発生することがあるため、加工処理の途中で実行すると全体の処理時間が長くなってしまいます。そのため、処理途中では分割されたファイルのまま扱い、利用者に提供するレベルまでデータが整理された後にまとめる処理を実行するとよいでしょう。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>coalesce</code> による統合</h4>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold"><code>coalesce</code></span> メソッドは、パーティション数を減少させて、単一パーティションに統合することができます。これにより、ファイル出力数をコントロールできます。</p>



<p class="wp-block-paragraph">以下のようにすることで、複数ファイルを 1 つのファイルに統合することができます。</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

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

# スキーマを定義
schema = StructType([
    StructField("name", StringType(), True),
    StructField("age", IntegerType(), True),
])

# データを作成
data = [("Taro", 25), ("Hanako", 30), ("Yuki", 20)]

# スキーマを指定してデータフレームを生成
df = spark.createDataFrame(data, schema=schema)


# CSVファイルへの書き込み
(df.coalesce(1).write
    .option("header", "true")
    .mode("overwrite")
    .csv("./output_csv_onefile"))

# Parquetファイルへの書き込み
(df.coalesce(1).write
    .mode("overwrite")
    .parquet("./output_parquet_onefile"))

# ORCファイルへの書き込み
(df.coalesce(1).write
    .mode("overwrite")
    .orc("./output_orc_onefile"))

# JSONファイルへの書き込み
(df.coalesce(1).write
    .mode("overwrite")
    .json("./output_json_onefile"))

# SparkSessionを終了
spark.stop()</pre>



<p class="wp-block-paragraph">出力結果例 (CSV ファイルの場合、他のフォーマットも同様)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="501" height="108" src="https://tech.nkhn37.net/wp-content/uploads/2023/10/image-18.png" alt="coalesce 出力例" class="wp-image-9669" srcset="https://tech.nkhn37.net/wp-content/uploads/2023/10/image-18.png 501w, https://tech.nkhn37.net/wp-content/uploads/2023/10/image-18-300x65.png 300w" sizes="(max-width: 501px) 100vw, 501px" /></figure>
</div>


<p class="wp-block-paragraph"><code>coalesce</code> を使用して出力する際には <code>df.coalesce(1).write</code> というようにします。これにより 1 つの CSV ファイルとして出力可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>repartition</code> による統合</h4>



<p class="wp-block-paragraph"><code>coalesce</code> と同じようなメソッドとして <span class="jinr-d--text-color d--marker1 d--bold"><code>repartition</code></span> があります。以下のようにすることで複数ファイルに 1 つのファイルに統合できます。</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

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

# スキーマを定義
schema = StructType([
    StructField("name", StringType(), True),
    StructField("age", IntegerType(), True),
])

# データを作成
data = [("Taro", 25), ("Hanako", 30), ("Yuki", 20)]

# スキーマを指定してデータフレームを生成
df = spark.createDataFrame(data, schema=schema)


# CSVファイルへの書き込み
(df.repartition(1).write
    .option("header", "true")
    .mode("overwrite")
    .csv("./output_csv_onefile"))

# Parquetファイルへの書き込み
(df.repartition(1).write
    .mode("overwrite")
    .parquet("./output_parquet_onefile"))

# ORCファイルへの書き込み
(df.repartition(1).write
    .mode("overwrite")
    .orc("./output_orc_onefile"))

# JSONファイルへの書き込み
(df.repartition(1).write
    .mode("overwrite")
    .json("./output_json_onefile"))

# SparkSessionを終了
spark.stop()</pre>



<p class="wp-block-paragraph">出力結果例 (CSV ファイルの場合、他のフォーマットも同様)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="495" height="116" src="https://tech.nkhn37.net/wp-content/uploads/2023/10/image-19.png" alt="repartition 出力例" class="wp-image-9670" srcset="https://tech.nkhn37.net/wp-content/uploads/2023/10/image-19.png 495w, https://tech.nkhn37.net/wp-content/uploads/2023/10/image-19-300x70.png 300w" sizes="(max-width: 495px) 100vw, 495px" /></figure>
</div>


<p class="wp-block-paragraph"><code>repartition</code> を使用して出力する際には <code>df.repartition(1).write</code> というようにします。上記のように <code>repartition</code> でも同様にファイルをまとめることが可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>coalesce</code> と <code>repartition</code> の使い分け基準</h4>



<p class="wp-block-paragraph">上記の通り <code>coalesce</code> と <code>repartition</code> という類似するメソッドを紹介しました。どちらをいつ使うかという考え方について説明します。もともと、<code>coalesce</code> と <code>repartition</code> は、動作と使用目的が異なっています。</p>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold"><code>coalesce</code></span> は、パーティション数を減少させるために使用します。また、<code>coalesce</code> はシャッフルという処理ノード間のデータ移動が発生する負荷の高い処理を回避するように複数パーティションを単一パーティションに統合します。そのため、大量の小さなパーティションを統合して効率的なサイズのパーティションを作成する際に適します。</p>



<p class="wp-block-paragraph">なお、<code>coalesce</code> で処理ノード間の移動が全く発生しないということではないので注意してください。例えば、処理ノード 1 と処理ノード 2 があり、それぞれに 2 つのパーティションが存在する場合、<code>coalesce(1)</code> を使用すると、全てのパーティションを 1 つにまとめる必要があります。このような場合は、データをノード間で移動する必要があります。この場合、<code>coalesce</code>は、既存パーティションを移動して、他のパーティションと結合する最も効率的な方法を選択します。</p>



<p class="wp-block-paragraph">また、<code>coalesce</code> は、パーティションを増やす場合には使用できません。パーティション数を増やす場合には、<code>repartition</code> の方を使う必要があります。</p>



<p class="wp-block-paragraph">一方で、<span class="jinr-d--text-color d--marker1 d--bold"><code>repartition</code></span> は、データをシャッフルして新しいパーティションに再分配します。使い方としては、パーティション数を増やす場合や、特定の列に基づいてデータを再分配する場合に使用します。PySpark では、処理ノード数に対して適切なパーティション数を持つことで効率的な処理が可能となります。このような調整を行う際には <code>repartition</code> を使用するのが適切です。</p>



<p class="wp-block-paragraph"><code>coalesce</code> と <code>repartition</code> の使い分けの基準は以下のような考え方ができます。</p>



<ul class="wp-block-list jinr-list">
<li>パーティション数を減少させる場合：<code>coalesce</code></li>



<li>パーティション数を増やす場合：<code>repartition</code></li>



<li>特定の列に基づいてパーティションを再分割する場合：<code>repartition</code></li>
</ul>



<p class="wp-block-paragraph">状況によりどちらを選択するべきか十分に検討してみてください。</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>について解説しました。データ分析でよく利用される CSV、Parquet、ORC、JSON といったファイル形式を扱いました。</p>



<p class="wp-block-paragraph">PySpark の DataFrame でのデータの書き込みは <span class="jinr-d--text-color d--marker1 d--bold"><code>write</code></span> メソッドとして、読み込みは <span class="jinr-d--text-color d--marker1 d--bold"><code>read</code></span> メソッドとして実装されています。それぞれのメソッドでは <code>option</code> 等のメソッドを追加で指定することで挙動をコントロールできます。</p>



<p class="wp-block-paragraph">また、Spark を使用するとファイルの出力が複数になるという特徴があります。Spark では分散処理環境で処理を実行しており、それぞれの処理ノードの各タスクで各パーティションを処理して書き込みを行っているためです。必要に応じてファイル数を制御する <span class="jinr-d--text-color d--marker1 d--bold"><code>coalesce</code></span> や <span class="jinr-d--text-color d--marker1 d--bold"><code>repartition</code></span> といったメソッドについても紹介しました。</p>



<p class="wp-block-paragraph">PySpark を用いたデータ処理の流れの中で、ファイルの入出力である <code>read</code> と <code>write</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/pyspark/dataframe-input-output" 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 class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.nkhn37.net/pyspark-dataframe-read-write/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Python】configparserによる設定ファイル管理</title>
		<link>https://tech.nkhn37.net/python-configparser-basic/</link>
					<comments>https://tech.nkhn37.net/python-configparser-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 20 Mar 2021 00:00:00 +0000</pubDate>
				<category><![CDATA[configparser]]></category>
		<category><![CDATA[ConfigParser]]></category>
		<category><![CDATA[read]]></category>
		<category><![CDATA[write]]></category>
		<category><![CDATA[設定ファイル]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=1327</guid>

					<description><![CDATA[Python で設定ファイルの管理をするための configparser について解説します。 configparser による設定ファイルの管理 システムを構築する際には、システムの動作を制御する設定情報を設定ファイル [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Python で設定ファイルの管理をするための <span class="jinr-d--text-color d--marker1 d--bold"><code>configparser</code></span> について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold" id="configparserによるconfigファイルの管理"><code>configparser</code> による設定ファイルの管理</h2>



<p class="wp-block-paragraph">システムを構築する際には、システムの動作を制御する設定情報を設定ファイルとして管理することがほとんどです。Python では、設定ファイルを管理するためのモジュールとして <span class="jinr-d--text-color d--marker1 d--bold"><code>configparser</code></span> モジュールが用意されています。</p>



<p class="wp-block-paragraph">この記事では、<code>configparser</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">Python の設定ファイル管理では、YAML や TOML ファイルもよく使用されます。以下も参考にしてください。</p>



<ul class="wp-block-list jinr-list">
<li><a href="https://tech.nkhn37.net/python-yaml-basic/" target="_blank" rel="noreferrer noopener">PyYAMLでのYAMLファイル管理</a></li>



<li><a href="https://tech.nkhn37.net/python-tomllib-basic/" target="_blank" rel="noreferrer noopener">tomllibでTOMLファイルを読み込む方法</a></li>
</ul>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold" id="configファイルの形式">設定ファイルの形式</h3>



<p class="wp-block-paragraph"><code>configparser</code> では、Windows で主に使用される INI ファイルに似た構造を扱うことができます。<code>configparser</code> の<a href="https://docs.python.org/ja/3/library/configparser.html?#module-configparser" target="_blank" rel="noreferrer noopener">公式ドキュメント</a>に注釈がありますが、Windows のレジストリ用に拡張された INI 文法はサポートされていません。</p>



<p class="wp-block-paragraph">具体的には、以下のような形式のファイルになります。</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="">[WEB_SERVER]
host = xxx.xxx.xxx.xxx
port = 80

[DB_SERVER]
host = xxx.xxx.xxx.xxx
port = 3306</pre>



<p class="wp-block-paragraph">設定ファイルの中で <code>[]</code> で囲われている部分をセクションと言い、設定情報の 1 つの区分を表しています。</p>



<p class="wp-block-paragraph">例では、Web サーバーに関するホスト名 (<code>host</code>)、ポート (<code>port</code>) の情報を <code>[WEB_SERVER]</code> のセクションで管理しており、DB サーバーに関するホスト名 (<code>host</code>)、ポート (<code>port</code>) の情報を <code>[DB_SERVER]</code> のセクションで管理しています。</p>



<p class="wp-block-paragraph">セクションや設定値は、任意に増やすことができます。以降では、このような設定ファイルを <code>configparser</code> で具体的に扱う方法について見ていきます。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="configparserによるconfigファイル管理の基本的な使い方"><code>configparser</code> による設定ファイル管理の基本</h3>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold"><code>configparser</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="">import configparser

config = configparser.ConfigParser()
config["WEB_SERVER"] = {"HOST": "xxx.xxx.xxx.xxx", "PORT": 80}
config["DB_SERVER"] = {"HOST": "xxx.xxx.xxx.xxx", "PORT": 3306}

# configファイルへの書き込み
with open("config.ini", "w") as config_file:
    config.write(config_file)

# configファイルからの読み込み
config1 = configparser.ConfigParser()
config1.read("config.ini")
# 読み込んだ結果を参照
print(config1["WEB_SERVER"])
print(config1["WEB_SERVER"]["HOST"])
print(config1["WEB_SERVER"]["PORT"])
print(config1["DB_SERVER"])
print(config1["DB_SERVER"]["HOST"])
print(config1["DB_SERVER"]["PORT"])</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="">【実行結果】
&lt;Section: WEB_SERVER>
xxx.xxx.xxx.xxx
80
&lt;Section: DB_SERVER>
xxx.xxx.xxx.xxx
3306</pre>



<p class="wp-block-paragraph">例では、設定ファイル情報を <code>config.ini</code> ファイルに書き込み、その後に書き込んだ設定情報を読みこんで表示しています。</p>



<h4 class="wp-block-heading jinr-heading d--bold" id="configファイルの設定と書き込み">設定ファイルの書き込み</h4>



<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="">import configparser

config = configparser.ConfigParser()
config["WEB_SERVER"] = {"HOST": "xxx.xxx.xxx.xxx", "PORT": 80}
config["DB_SERVER"] = {"HOST": "xxx.xxx.xxx.xxx", "PORT": 3306}</pre>



<p class="wp-block-paragraph"><code>configparser</code> を使用するには、<code>configparser</code> をインポートし、<span class="jinr-d--text-color d--marker1 d--bold"><code>ConfigParser</code></span> クラスのオブジェクトを作成します。</p>



<p class="wp-block-paragraph"><code>ConfigParser</code> クラスのオブジェクトでは「<code>オブジェクト名["セクション名"] = {キー: 設定値, ...}</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=""># configファイルへの書き込み
with open("config.ini", "w") as config_file:
    config.write(config_file)</pre>



<p class="wp-block-paragraph">上記部分は設定ファイルを書き込んでいる部分です。対象ファイルを書き込みモード (<code>"w"</code>)で開いて、<code>ConfigParser</code> クラスの <span class="jinr-d--text-color d--marker1 d--bold"><code>write</code></span> メソッドにファイルオブジェクトを渡すことで設定情報の書き込みができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold" id="configファイルの読み込み">設定ファイルの読み込み</h4>



<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=""># configファイルからの読み込み
config1 = configparser.ConfigParser()
config1.read("config.ini")</pre>



<p class="wp-block-paragraph">設定ファイルへ読み込むには、書き込み時と同じように <code>ConfigParse</code> クラスのオブジェクトを生成し、<span class="jinr-d--text-color d--marker1 d--bold"><code>read</code></span> メソッドに読み込む config ファイルのパスを指定します。</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=""># 読み込んだ結果を参照
print(config1["WEB_SERVER"])
print(config1["WEB_SERVER"]["HOST"])
print(config1["WEB_SERVER"]["PORT"])
print(config1["DB_SERVER"])
print(config1["DB_SERVER"]["HOST"])
print(config1["DB_SERVER"]["PORT"])</pre>



<p class="wp-block-paragraph">読み込んだ結果を設定値を参照する場合には、上記のように「<code>オブジェクト名["セクション名"]["キー"]</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"><code>configparser</code></span> について解説しました。</p>



<p class="wp-block-paragraph">システムを構築する際には、システムの動作を制御する設定情報を設定ファイルとして管理することがほとんどです。<code>configparser</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>configparse</code>r の公式ドキュメントは<a href="https://docs.python.org/ja/3/library/configparser.html?#module-configparser" 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-libraries/configparser" 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-configparser-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Python】ファイル入出力の基本</title>
		<link>https://tech.nkhn37.net/python-open-write/</link>
					<comments>https://tech.nkhn37.net/python-open-write/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Tue, 09 Feb 2021 00:00:00 +0000</pubDate>
				<category><![CDATA[入出力]]></category>
		<category><![CDATA[close]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[mode]]></category>
		<category><![CDATA[open]]></category>
		<category><![CDATA[read]]></category>
		<category><![CDATA[readlines]]></category>
		<category><![CDATA[walrus]]></category>
		<category><![CDATA[with]]></category>
		<category><![CDATA[write]]></category>
		<category><![CDATA[writelines]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=891</guid>

					<description><![CDATA[Python のファイル入出力の基本について解説します。 Pythonのファイル入出力 Python でのファイル入出力は、ファイルを開いてデータを読み書きする基本的な操作です。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" id="ファイル入出力">Pythonのファイル入出力</h2>



<p class="wp-block-paragraph">Python でのファイル入出力は、ファイルを開いてデータを読み書きする基本的な操作です。Python にはファイル入出力用の様々な関数やメソッドが用意されており、簡単に処理を実行できます。</p>



<p class="wp-block-paragraph">この記事では、Python のファイル入出力の基本となる各種関数・メソッドの使い方や <code>with</code> による自動ファイルクローズなど基本を紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="ファイル入出力の手順">ファイル入出力の手順</h3>



<p class="wp-block-paragraph">ファイル入出力の基本的な手順は以下のような流れとなります。</p>



<ol class="wp-block-list jinr-list">
<li><code>open</code> 関数でファイルを開く。</li>



<li><code>read</code> / <code>readline</code> メソッドでデータを読み込む、または <code>write</code> / <code>writelines</code> メソッドでデータを書き込む。</li>



<li><code>close</code> メソッドでファイルを閉じる。</li>
</ol>



<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="">input_text = "サンプル"

# ファイルを開く（オープン）
file = open("sample.txt", "w+", encoding="utf-8")
# 文字列の書き込み
file.write(input_text)
# ファイルを閉じる（クローズ）
file.close()</pre>



<p class="wp-block-paragraph"><code>open</code> 関数では、ファイルパス、モード、文字コードを指定します。例では、<code>write</code> で<code>input_text</code> に格納した文字列をファイルに書き込み、<code>close</code> で閉じています。読み込みの場合は、メソッドが変わるだけで流れは同じです。</p>



<p class="wp-block-paragraph"><code>close</code> を忘れるとファイルが占有されたままとなり、他のプログラムがアクセスできなくなる可能性がありますので注意が必要です。なお、後述する <code>with</code> を使うと、自動的にファイルを閉じることができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="ファイルのモード-mode">ファイルのモード（<code>mode</code>）</h3>



<p class="wp-block-paragraph">ファイルの入出力では<span class="jinr-d--text-color d--marker1 d--bold">モード（<code>mode</code>）</span>を指定することで挙動の制御ができます。</p>



<p class="wp-block-paragraph">主なモードは以下の通りです。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>mode</th><th>内容</th></tr></thead><tbody><tr><td><code>r</code></td><td>読み込み専用<br>（ファイルが存在しない場合はエラー）</td></tr><tr><td><code>r+</code></td><td>読み書き両用<br>（ファイルが存在しない場合はエラー）</td></tr><tr><td><code>w</code></td><td>書き込み専用<br>（ファイルが存在しない場合は新規作成）</td></tr><tr><td><code>w+</code></td><td>読み書き両用<br>（オープン時に内容をクリア、ファイルが存在しない場合は新規作成）</td></tr><tr><td><code>a</code></td><td>追記専用<br>（ファイルが存在する場合に末尾に追記、ファイルが存在しない場合は新規作成）</td></tr><tr><td><code>a+</code></td><td>読み書き両用<br>（ファイルが存在する場合に末尾に追記、ファイルが存在しない場合は新規作成）</td></tr><tr><td><code>b</code></td><td>バイナリモード<br>（<code>rb</code>、<code>wb</code> のように <code>r</code> や <code>w</code> と併用）</td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><code>w</code> モードは書き込むたびに内容が上書きされるため注意が必要です。ログファイルのように追記する場合は <code>a</code>、<code>a+</code> モードを使用します。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="with命令により自動でファイルをcloseする"><code>with</code> による自動クローズ</h3>



<p class="wp-block-paragraph">ファイルを開いたら、不要になった時点で <code>close</code> する必要があります。しかし、コードが複雑で長くなるとクローズを忘れる可能性があることから、ファイルのオープン時間は短く保つことが推奨されます。</p>



<p class="wp-block-paragraph">これらの問題を解決するために <span class="jinr-d--text-color d--marker1 d--bold"><code>with</code></span> を使用します。<code>with</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="">input_text = "サンプル"

# withでopenを実行する
with open("sample.txt", "w+", encoding="utf-8") as file:
    # 文字列の書き込み
    file.write(input_text)</pre>



<p class="wp-block-paragraph">例では、文字列の書き込みの <code>write</code> が終わったら自動でファイルをクローズするため、<code>close</code> 忘れを防止できます。特に理由がない限りは積極的に <code>with</code> を使用するようにしましょう。</p>



<p class="wp-block-paragraph">プログラミングでは不要になったらリソースを開放するのが基本です。C/C++ 言語などの他言語では、メモリも同様に確保・解放を行う必要があります。プログラマとしては、使い終わったものは片づける意識を持つように意識しましょう。</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"><strong>【コンテキストマネージャー】</strong></p>



<p class="wp-block-paragraph"><code>with ... as ...</code> は、コンテキストマネージャーと呼ばれる仕組みを使っています。コンテキストマネージャーは独自に実装することも可能です。以下を参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://tech.nkhn37.net/python-context-manager-basic/" target="_blank" rel="noreferrer noopener">コンテキストマネージャーの基本</a></p>
</div>
		</div></section>



<h2 class="wp-block-heading jinr-heading d--bold" id="テキストファイルの入出力-1">テキストファイルの入出力</h2>



<p class="wp-block-paragraph">テキストファイルの入出力方法について基本となる実装例を紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="テキストファイルの読み込み-1">テキストファイルの読み込み</h3>



<h4 class="wp-block-heading jinr-heading d--bold" id="ファイル内容をまとめて取得する-readメソッド">ファイル内容をまとめて取得する <code>read</code></h4>



<p class="wp-block-paragraph">ファイル全体の内容をまとめて取得するには <span class="jinr-d--text-color d--marker1 d--bold"><code>read</code></span> メソッドを使用します。</p>



<p class="wp-block-paragraph">以下は、事前に用意した <code>sample_text.txt</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="">with open("sample_text.txt", "r", encoding="utf-8") as file:
    data = file.read()

print(data)</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="">【実行結果】
Python
ファイルの入出力の基本
テキストファイルの入出力</pre>



<h4 class="wp-block-heading jinr-heading d--bold" id="ファイル内容をまとめて取得する-readメソッド">ファイル内容を 1 文字ずつ取得する <code>read(1)</code></h4>



<p class="wp-block-paragraph">ファイル内容を 1 文字ずつ読み込むには <code>read(1)</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="">with open("sample_text.txt", "r", encoding="utf-8") as file:
    data = []
    # 一文字ずつ読み込む
    while d := file.read(1):
        data.append(d)

print(data, "\n")
data_str = "".join(data)
print(data_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="">【実行結果】
['P', 'y', 't', 'h', 'o', 'n', '\n', 'フ', 'ァ', 'イ', 'ル', 'の', '入', '出', '力', 'の', '基', '本', '\n', 'テ', 'キ', 'ス', 'ト', 'フ', 'ァ', 'イ', 'ル', 'の', '入', '出', '力'] 

Python
ファイルの入出力の基本
テキストファイルの入出力</pre>



<p class="wp-block-paragraph">この例では、1 文字ずつリストに格納し <code>"".join(data)</code> で結合しています。リストの結合は「<a href="https://tech.nkhn37.net/python-str-join/" target="_blank" rel="noreferrer noopener">リストを結合して文字列にする方法 ~ join ~</a>」を参考にしてください。</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"><strong>【セイウチ (Walrus) 演算子】</strong></p>



<p class="wp-block-paragraph">「<span class="jinr-d--text-color d--marker1 d--bold"><code>:=</code></span>」は、Python 3.8 で導入された演算子でセイウチの目と牙に似ていることから「<span class="jinr-d--text-color d--marker1 d--bold">セイウチ (Walrus) 演算子</span>」と言います。この演算子では、変数への代入と評価を同時に行うため、シンプルな記述が可能です。公式ドキュメントは<a href="https://docs.python.org/ja/3/whatsnew/3.8.html#assignment-expressions" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。</p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold" id="ファイルの内容を1行ずつ取得する-readlinesメソッド">ファイルの内容を 1 行ずつ取得する <code>readline</code></h4>



<p class="wp-block-paragraph">ファイルの内容を 1 行ずつリストで取得するには <span class="jinr-d--text-color d--marker1 d--bold"><code>readlines</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="">with open("sample_text.txt", "r", encoding="utf-8") as file:
    # 1行ずつデータを読み出す
    data = file.readlines()

print(data, "\n")
# 取得したデータを出力
for line in data:
    print(line, end="")</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="">【実行結果】
['Python\n', 'ファイルの入出力の基本\n', 'テキストファイルの入出力'] 

Python
ファイルの入出力の基本
テキストファイルの入出力</pre>



<p class="wp-block-paragraph"><code>readlines</code> で取得した各行の末尾には改行が入っているため、そのまま <code>print</code> すると余計な改行が入ってしまいます。例では、余計な改行で見にくくならないように <code>print(line, end="")</code> としています。</p>



<h5 class="wp-block-heading jinr-heading d--bold">順次 1 行ずつ取得して処理する場合</h5>



<p class="wp-block-paragraph"><code>readlines</code> 以外にも <code>open</code> したオブジェクトを使って、以下のように直接 <code>for</code> ループで処理することで 1 行ずつ読み込むことも可能です。</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=""># for文で順次取り出す方法
with open("sample_text.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line, end="")</pre>



<h3 class="wp-block-heading jinr-heading d--bold" id="テキストファイルの書き込み-write">テキストファイルへの書き込み</h3>



<h4 class="wp-block-heading jinr-heading d--bold">文字列をテキストファイルへ書き込む <code>write</code></h4>



<p class="wp-block-paragraph">文字列をテキストファイルを書き込むには、<span class="jinr-d--text-color d--marker1 d--bold"><code>write</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="">data = "Python\nファイルの入出力の基本\nテキストファイルの入出力"

# テキストファイルの書き込み
with open("sample_text_out_str.txt", "w+", encoding="utf-8") as file:
    file.write(data)</pre>



<p class="wp-block-paragraph">例では <code>"w+"</code> の書き込みモードでファイルを <code>open</code> し、<code>write</code> メソッドに文字列を渡しています。出力先の <code>sample_text_out_str.txt</code> には以下が書き込まれます。</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="">Python
ファイルの入出力の基本
テキストファイルの入出力</pre>



<h4 class="wp-block-heading jinr-heading d--bold">文字列リストをまとめてテキストファイルへ書き込む <code>writelines</code></h4>



<p class="wp-block-paragraph">文字列リストをまとめて書き込むには、<span class="jinr-d--text-color d--marker1 d--bold"><code>writelines</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="">data = [
    "Python\n",
    "ファイルの入出力の基本\n",
    "テキストファイルの入出力",
]

# テキストファイルの書き込み
with open("sample_text_out_list.txt", "w+", encoding="utf-8") as file:
    file.writelines(data)</pre>



<p class="wp-block-paragraph"><code>writelines</code> にリストを指定することでファイル出力が可能です。なお、各文字列ごとに改行したい場合は、リスト内の各文字列の末尾に <code>"\n"</code> を含める必要があります。</p>



<h2 class="wp-block-heading jinr-heading d--bold" id="バイナリファイルの入出力">バイナリファイルの入出力</h2>



<p class="wp-block-paragraph">画像などのバイナリファイルの入出力の例を紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold" id="バイナリファイルの読み込み-1">バイナリファイルの読み込み</h3>



<h4 class="wp-block-heading jinr-heading d--bold" id="ファイル内容をまとめて取得する-readメソッド-1">ファイル内容をまとめて取得する <code>read</code></h4>



<p class="wp-block-paragraph"> <code>"rb"</code> モードでバイナリファイルを開き、<code>read</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="">with open("sample_binary.png", "rb") as file:
    data = file.read()

print(data)</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="">【実行結果例】
b'\x89PNG\r\n\x1a\n\x00\x00\x00（・・・中略・・・）\xaeB`\x82'</pre>



<h4 class="wp-block-heading jinr-heading d--bold" id="ファイル内容をまとめて取得する-readメソッド">ファイル内容を 1 バイトずつ取得する <code>read(1)</code></h4>



<p class="wp-block-paragraph">バイナリファイルを 1 バイトずつ読み込むには <code>read(1)</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="">with open("sample_binary.png", "rb") as file:
    data = []
    while d := file.read(1):
        data.append(d)

print(data, "\n")
data_bin = b"".join(data)
print(data_bin)</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="">【実行結果】
[b'\x89', b'P', b'N', b'G', b'\r', b'\n', b'\x1a', b'\n', b'\x00', b'\x00', b'\x00',（・・・中略・・・）, b'\xae', b'B', b'`', b'\x82']
b'\x89PNG\r\n\x1a\n\x00\x00\x00（・・・中略・・・）\xaeB`\x82'</pre>



<h3 class="wp-block-heading jinr-heading d--bold" id="バイナリファイルの書き込み-write">バイナリファイルへの書き込み</h3>



<h4 class="wp-block-heading jinr-heading d--bold">データをバイナリファイルへ書き込む <code>write</code></h4>



<p class="wp-block-paragraph"><code>"wb"</code> モードでバイナリデータを開き、<code>write</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="">with open("sample_binary.png", "rb") as file:
    data = file.read()

# バイナリファイルの書き込み
with open("sample_binary_out.png", "wb") as file:
    file.write(data)</pre>



<p class="wp-block-paragraph">例では、バイナリファイルを読み込み、別名でコピーとして書き込んでいます。</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">ファイル入出力の基本的な流れは以下のようになります。</p>



<ol class="wp-block-list jinr-list">
<li><code>open</code> 関数でファイルを開く。</li>



<li><code>read</code> / <code>readline</code> メソッドでデータを読み込む、または <code>write</code> / <code>writelines</code> メソッドでデータを書き込む。</li>



<li><code>close</code> メソッドでファイルを閉じる。</li>
</ol>



<p class="wp-block-paragraph"><code>close</code> 忘れを防止するには <code>with</code> を使うと自動的にファイルクローズができます。また、<code>open</code>、<code>close</code>、<code>read</code>、<code>readlines</code>、<code>write</code>、<code>writelines</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/input-output/file-input-output" 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-open-write/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-07-22 23:27:25 by W3 Total Cache
-->