PythonでCSVファイルを読み書きする
それに直面してみましょう。キーボードとコンソールだけでなく、プログラムに情報を出し入れする必要があります。 テキストファイルを介した情報交換は、プログラム間で情報を共有する一般的な方法です。 データを交換するための最も一般的な形式の1つはCSV形式です。 しかし、どうやってそれを使うのですか?
1つ明確にしましょう。独自のCSVパーサーをゼロから作成する必要はありません(また、作成しません)。 使用できる完全に受け入れ可能なライブラリがいくつかあります。 Pythoncsv
libraryは、ほとんどの場合に機能します。 作業に大量のデータまたは数値分析が必要な場合、pandas
libraryにはCSV解析機能もあり、残りを処理する必要があります。
この記事では、Pythonを使用してテキストファイルからCSVを読み取り、処理し、解析する方法を学びます。 CSVファイルがどのように機能するかを確認し、Pythonに組み込まれている非常に重要なcsv
ライブラリを学習し、pandas
ライブラリを使用してCSV解析がどのように機能するかを確認します。
それでは始めましょう!
__ Take the Quiz:インタラクティブな「PythonでのCSVファイルの読み取りと書き込み」クイズで知識をテストします。 完了すると、学習の進捗状況を経時的に追跡できるようにスコアを受け取ります。
CSVファイルとは何ですか?
CSVファイル(カンマ区切り値ファイル)は、特定の構造化を使用して表形式のデータを整理するプレーンテキストファイルの一種です。 プレーンテキストファイルであるため、実際のテキストデータ、つまり印刷可能なASCIIまたはUnicode文字のみを含めることができます。
CSVファイルの構造は、名前で指定されます。 通常、CSVファイルはコンマを使用して特定の各データ値を区切ります。 その構造は次のようになります。
column 1 name,column 2 name, column 3 name
first row data 1,first row data 2,first row data 3
second row data 1,second row data 2,second row data 3
...
各データがカンマで区切られていることに注意してください。 通常、最初の行は各データ、つまりデータ列の名前を識別します。 その後のすべての行は実際のデータであり、ファイルサイズの制約によってのみ制限されます。
一般に、区切り文字は区切り文字と呼ばれ、使用されるのはコンマだけではありません。 その他の一般的な区切り文字には、タブ(
)、コロン(:
)、およびセミコロン(;
)文字が含まれます。 CSVファイルを正しく解析するには、使用されている区切り文字を知る必要があります。
CSVファイルはどこから来たのですか?
CSVファイルは通常、大量のデータを処理するプログラムによって作成されます。 これらは、スプレッドシートやデータベースからデータをエクスポートしたり、他のプログラムでインポートしたり使用したりする便利な方法です。 たとえば、データマイニングプログラムの結果をCSVファイルにエクスポートし、それをスプレッドシートにインポートして、データを分析したり、プレゼンテーション用のグラフを生成したり、公開用のレポートを準備したりできます。
CSVファイルはプログラムで簡単に操作できます。 テキストファイルの入力と文字列操作(Pythonなど)をサポートする言語は、CSVファイルを直接操作できます。
Pythonの組み込みCSVライブラリを使用したCSVファイルの解析
csv
libraryは、CSVファイルの読み取りと書き込みの両方を行う機能を提供します。 Excelで生成されたCSVファイルをそのまま使用できるように設計されており、さまざまなCSV形式で動作するように簡単に適応できます。 csv
ライブラリには、CSVファイルとの間でデータの読み取り、書き込み、および処理を行うためのオブジェクトとその他のコードが含まれています。
csv
でCSVファイルを読み取る
CSVファイルからの読み取りは、reader
オブジェクトを使用して行われます。 CSVファイルは、ファイルオブジェクトを返すPythonの組み込みopen()
関数を使用してテキストファイルとして開かれます。 次に、これはreader
に渡され、重労働が行われます。
employee_birthday.txt
ファイルは次のとおりです。
name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March
これを読むためのコードは次のとおりです。
import csv
with open('employee_birthday.txt') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
for row in csv_reader:
if line_count == 0:
print(f'Column names are {", ".join(row)}')
line_count += 1
else:
print(f'\t{row[0]} works in the {row[1]} department, and was born in {row[2]}.')
line_count += 1
print(f'Processed {line_count} lines.')
これにより、次のような出力が得られます。
Column names are name, department, birthday month
John Smith works in the Accounting department, and was born in November.
Erica Meyers works in the IT department, and was born in March.
Processed 3 lines.
reader
によって返される各行は、区切り文字を削除して見つかったデータを含むString
要素のリストです。 返される最初の行には列名が含まれており、特別な方法で処理されます。
csv
を使用してCSVファイルを辞書に読み込む
個々のString
要素のリストを処理するのではなく、CSVデータを辞書(技術的にはOrdered Dictionary)に直接読み取ることもできます。
ここでも、入力ファイルemployee_birthday.txt
は次のとおりです。
name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March
今回は辞書として読み込むためのコードは次のとおりです。
import csv
with open('employee_birthday.txt', mode='r') as csv_file:
csv_reader = csv.DictReader(csv_file)
line_count = 0
for row in csv_reader:
if line_count == 0:
print(f'Column names are {", ".join(row)}')
line_count += 1
print(f'\t{row["name"]} works in the {row["department"]} department, and was born in {row["birthday month"]}.')
line_count += 1
print(f'Processed {line_count} lines.')
これにより、以前と同じ出力が得られます。
Column names are name, department, birthday month
John Smith works in the Accounting department, and was born in November.
Erica Meyers works in the IT department, and was born in March.
Processed 3 lines.
辞書キーはどこから来たのですか? CSVファイルの最初の行には、辞書の作成に使用するキーが含まれていると想定されています。 これらがCSVファイルにない場合は、fieldnames
オプションパラメータをそれらを含むリストに設定して、独自のキーを指定する必要があります。
オプションのPythonCSVreader
パラメータ
reader
オブジェクトは、additional parametersを指定することにより、さまざまなスタイルのCSVファイルを処理できます。その一部を以下に示します。
-
delimiter
は、各フィールドを区切るために使用される文字を指定します。 デフォルトはコンマ(','
)です。 -
quotechar
は、区切り文字を含むフィールドを囲むために使用される文字を指定します。 デフォルトは二重引用符(' " '
)です。 -
escapechar
は、引用符が使用されていない場合に、区切り文字をエスケープするために使用される文字を指定します。 デフォルトはエスケープ文字なしです。
これらのパラメーターについては、もう少し説明が必要です。 次のemployee_addresses.txt
ファイルで作業しているとします。
name,address,date joined
john smith,1132 Anywhere Lane Hoboken NJ, 07030,Jan 4
erica meyers,1234 Smith Lane Hoboken NJ, 07030,March 2
このCSVファイルには、name
、address
、およびdate joined
の3つのフィールドが含まれています。これらのフィールドはコンマで区切られています。 問題は、address
フィールドのデータに、郵便番号を示すコンマも含まれていることです。
この状況を処理するには、3つの異なる方法があります。
-
Use a different delimiter
こうすることで、データ自体でコンマを安全に使用できます。delimiter
オプションのパラメーターを使用して、新しい区切り文字を指定します。 -
Wrap the data in quotes
選択した区切り文字の特殊な性質は、引用符で囲まれた文字列では無視されます。 したがって、引用符に使用する文字をquotechar
オプションパラメーターで指定できます。 その文字もデータに表示されない限り、問題ありません。 -
Escape the delimiter characters in the data
エスケープ文字は、フォーマット文字列の場合と同じように機能し、エスケープされる文字(この場合は区切り文字)の解釈を無効にします。 エスケープ文字を使用する場合は、escapechar
オプションパラメーターを使用して指定する必要があります。
csv
でCSVファイルを書き込む
writer
オブジェクトと.write_row()
メソッドを使用してCSVファイルに書き込むこともできます。
import csv
with open('employee_file.csv', mode='w') as employee_file:
employee_writer = csv.writer(employee_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
employee_writer.writerow(['John Smith', 'Accounting', 'November'])
employee_writer.writerow(['Erica Meyers', 'IT', 'March'])
quotechar
オプションパラメータは、書き込み時にフィールドを引用するために使用する文字をwriter
に指示します。 ただし、引用符を使用するかどうかは、quoting
のオプションのパラメーターによって決まります。
-
quoting
がcsv.QUOTE_MINIMAL
に設定されている場合、.writerow()
は、フィールドにdelimiter
またはquotechar
が含まれている場合にのみフィールドを引用します。 これはデフォルトのケースです。 -
quoting
がcsv.QUOTE_ALL
に設定されている場合、.writerow()
はすべてのフィールドを引用します。 -
quoting
がcsv.QUOTE_NONNUMERIC
に設定されている場合、.writerow()
はテキストデータを含むすべてのフィールドを引用し、すべての数値フィールドをfloat
データ型に変換します。 -
quoting
がcsv.QUOTE_NONE
に設定されている場合、.writerow()
は区切り文字を引用符で囲む代わりにエスケープします。 この場合、escapechar
オプションパラメータの値も指定する必要があります。
ファイルをプレーンテキストで読み戻すと、ファイルが次のように作成されていることがわかります。
John Smith,Accounting,November
Erica Meyers,IT,March
csv
を使用した辞書からのCSVファイルの書き込み
データを辞書に読み込むことができるので、辞書からもデータを書き出すことができるのは公平なことです。
import csv
with open('employee_file2.csv', mode='w') as csv_file:
fieldnames = ['emp_name', 'dept', 'birth_month']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'emp_name': 'John Smith', 'dept': 'Accounting', 'birth_month': 'November'})
writer.writerow({'emp_name': 'Erica Meyers', 'dept': 'IT', 'birth_month': 'March'})
DictReader
とは異なり、辞書を作成するときはfieldnames
パラメーターが必要です。 これは、考えてみると理にかなっています。fieldnames
のリストがないと、DictWriter
は、辞書から値を取得するために使用するキーを知ることができません。 また、fieldnames
のキーを使用して、最初の行を列名として書き出します。
上記のコードは、次の出力ファイルを生成します。
emp_name,dept,birth_month
John Smith,Accounting,November
Erica Meyers,IT,March
pandas
ライブラリを使用したCSVファイルの解析
もちろん、Python CSVライブラリは町で唯一のゲームではありません。 CSVファイルの読み取りはpandas
でも可能です。 分析するデータが多い場合は、強くお勧めします。
pandas
は、高性能のデータ分析ツールと使いやすいデータ構造を提供するオープンソースのPythonライブラリです。 pandas
はすべてのPythonインストールで使用できますが、Anacondaディストリビューションの重要な部分であり、Jupyter notebooksで非常にうまく機能して、データ、コード、分析結果、視覚化、および説明テキストを共有します。 。
pandas
とその依存関係をAnaconda
にインストールするのは簡単です。
$ conda install pandas
他のPythonインストールにpip
/pipenv
を使用している場合:
$ pip install pandas
pandas
の動作や使用方法の詳細については、詳しく説明しません。 pandas
を使用して大規模なデータセットを読み取って分析する方法の詳細については、working with large Excel files in pandasに関するShantnu Tiwari’sのすばらしい記事をご覧ください。
pandas
でCSVファイルを読み取る
pandas
のCSV機能の威力を示すために、hrdata.csv
と呼ばれるもう少し複雑なファイルを作成しました。 会社の従業員に関するデータが含まれています。
Name,Hire Date,Salary,Sick Days remaining
Graham Chapman,03/15/14,50000.00,10
John Cleese,06/01/15,65000.00,8
Eric Idle,05/12/14,45000.00,10
Terry Jones,11/01/13,70000.00,3
Terry Gilliam,08/12/14,48000.00,7
Michael Palin,05/23/13,66000.00,8
CSVをpandas
DataFrame
に読み込むのは、すばやく簡単です。
import pandas
df = pandas.read_csv('hrdata.csv')
print(df)
それだけです。3行のコードで、そのうちの1行だけが実際の作業を行っています。 pandas.read_csv()
は、提供されたCSVファイルを開き、分析して読み取り、データをDataFrameに保存します。 DataFrame
を出力すると、次の出力が得られます。
Name Hire Date Salary Sick Days remaining
0 Graham Chapman 03/15/14 50000.0 10
1 John Cleese 06/01/15 65000.0 8
2 Eric Idle 05/12/14 45000.0 10
3 Terry Jones 11/01/13 70000.0 3
4 Terry Gilliam 08/12/14 48000.0 7
5 Michael Palin 05/23/13 66000.0 8
注目に値するいくつかのポイントを次に示します。
-
まず、
pandas
は、CSVの最初の行に列名が含まれていることを認識し、それらを自動的に使用しました。 私はこれを善と呼んでいます。 -
ただし、
pandas
は、DataFrame
でゼロベースの整数インデックスも使用しています。 インデックスがどうあるべきかを伝えなかったからです。 -
さらに、列のデータ型を見ると、
pandas
がSalary
列とSick Days remaining
列を数値に適切に変換していることがわかりますが、Hire Date
列はそれでもString
。 これは、インタラクティブモードで簡単に確認できます。>>>
>>> print(type(df['Hire Date'][0]))
これらの問題に一度に取り組みましょう。 DataFrame
インデックスとして別の列を使用するには、index_col
オプションパラメータを追加します。
import pandas
df = pandas.read_csv('hrdata.csv', index_col='Name')
print(df)
これで、Name
フィールドはDataFrame
インデックスになります。
Hire Date Salary Sick Days remaining
Name
Graham Chapman 03/15/14 50000.0 10
John Cleese 06/01/15 65000.0 8
Eric Idle 05/12/14 45000.0 10
Terry Jones 11/01/13 70000.0 3
Terry Gilliam 08/12/14 48000.0 7
Michael Palin 05/23/13 66000.0 8
次に、Hire Date
フィールドのデータ型を修正しましょう。 parse_dates
オプションパラメータを使用して、pandas
にデータを日付として読み取るように強制できます。これは、日付として扱う列名のリストとして定義されています。
import pandas
df = pandas.read_csv('hrdata.csv', index_col='Name', parse_dates=['Hire Date'])
print(df)
出力の違いに注意してください。
Hire Date Salary Sick Days remaining
Name
Graham Chapman 2014-03-15 50000.0 10
John Cleese 2015-06-01 65000.0 8
Eric Idle 2014-05-12 45000.0 10
Terry Jones 2013-11-01 70000.0 3
Terry Gilliam 2014-08-12 48000.0 7
Michael Palin 2013-05-23 66000.0 8
日付は適切にフォーマットされ、インタラクティブモードで簡単に確認できます。
>>>
>>> print(type(df['Hire Date'][0]))
CSVファイルの最初の行に列名がない場合は、names
オプションパラメーターを使用して列名のリストを提供できます。 最初の行で提供されている列名をオーバーライドする場合にも、これを使用できます。 この場合、header=0
オプションパラメータを使用して、既存の列名を無視するようにpandas.read_csv()
に指示する必要もあります。
import pandas
df = pandas.read_csv('hrdata.csv',
index_col='Employee',
parse_dates=['Hired'],
header=0,
names=['Employee', 'Hired','Salary', 'Sick Days'])
print(df)
列名が変更されたため、index_col
およびparse_dates
オプションパラメーターで指定された列も変更する必要があることに注意してください。 これにより、次の出力が得られます。
Hired Salary Sick Days
Employee
Graham Chapman 2014-03-15 50000.0 10
John Cleese 2015-06-01 65000.0 8
Eric Idle 2014-05-12 45000.0 10
Terry Jones 2013-11-01 70000.0 3
Terry Gilliam 2014-08-12 48000.0 7
Michael Palin 2013-05-23 66000.0 8
pandas
でCSVファイルを書き込む
もちろん、pandas
からデータを再び取得できない場合は、あまり効果がありません。 CSVファイルへのDataFrame
の書き込みは、で読み取るのと同じくらい簡単です。 新しい列名でデータを新しいCSVファイルに書き込みましょう。
import pandas
df = pandas.read_csv('hrdata.csv',
index_col='Employee',
parse_dates=['Hired'],
header=0,
names=['Employee', 'Hired', 'Salary', 'Sick Days'])
df.to_csv('hrdata_modified.csv')
このコードと上記の読み取りコードの唯一の違いは、print(df)
呼び出しがdf.to_csv()
に置き換えられ、ファイル名が提供されることです。 新しいCSVファイルは次のようになります。
Employee,Hired,Salary,Sick Days
Graham Chapman,2014-03-15,50000.0,10
John Cleese,2015-06-01,65000.0,8
Eric Idle,2014-05-12,45000.0,10
Terry Jones,2013-11-01,70000.0,3
Terry Gilliam,2014-08-12,48000.0,7
Michael Palin,2013-05-23,66000.0,8
結論
CSVファイルの読み取りの基本を理解していれば、データのインポートを処理する必要があるときに足がひっかかりません。 ほとんどのCSVの読み取り、処理、および書き込みタスクは、基本的なcsv
Pythonライブラリで簡単に処理できます。 読み取りおよび処理するデータが多い場合、pandas
ライブラリはすばやく簡単なCSV処理機能も提供します。
__ Take the Quiz:インタラクティブな「PythonでのCSVファイルの読み取りと書き込み」クイズで知識をテストします。 完了すると、学習の進捗状況を経時的に追跡できるようにスコアを受け取ります。
テキストファイルを解析する他の方法はありますか? もちろん! ANTLR、PLY、PlyPlusなどのライブラリはすべて、高負荷の解析を処理できます。単純なString
操作が機能しない場合は、常に正規表現があります。
しかし、それらは他の記事のトピックです…