PythonでCSVファイルを読み書きする

PythonでCSVファイルを読み書きする

それに直面してみましょう。キーボードとコンソールだけでなく、プログラムに情報を出し入れする必要があります。 テキストファイルを介した情報交換は、プログラム間で情報を共有する一般的な方法です。 データを交換するための最も一般的な形式の1つはCSV形式です。 しかし、どうやってそれを使うのですか?

1つ明確にしましょう。独自のCSVパーサーをゼロから作成する必要はありません(また、作成しません)。 使用できる完全に受け入れ可能なライブラリがいくつかあります。 Python https://docs.python.org/3/library/csv.html [+ csv + library]はほとんどの場合に機能します。 作業に大量のデータまたは数値分析が必要な場合、http://pandas.pydata.org/[+ pandas + library]にはCSV解析機能もあり、残りの処理が必要です。

この記事では、Pythonを使用してテキストファイルからCSVを読み取り、処理し、解析する方法を学びます。 CSVファイルの仕組み、Pythonに組み込まれている非常に重要な `+ csv `ライブラリ、および ` pandas +`ライブラリを使用したCSV解析の仕組みをご覧ください。

それでは始めましょう!

  • __クイズを受ける:*インタラクティブな「PythonでのCSVファイルの読み取りと書き込み」クイズで知識をテストします。 完了すると、学習の進捗状況を経時的に追跡できるようにスコアを受け取ります。

link:/quizzes/python-csv/[クイズに挑戦»]

CSVファイルとは何ですか?

CSVファイル(カンマ区切り値ファイル)は、特定の構造化を使用して表形式のデータを整理するプレーンテキストファイルの一種です。 プレーンテキストファイルであるため、実際のテキストデータのみ、つまり印刷可能なhttps://en.wikipedia.org/wiki/ASCII[ASCII]またはhttps://en.wikipedia.org/wiki/Unicodeのみを含めることができます[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
...

各データがカンマで区切られていることに注意してください。 通常、最初の行は各データ、つまりデータ列の名前を識別します。 その後のすべての行は実際のデータであり、ファイルサイズの制約によってのみ制限されます。

一般に、区切り文字は区切り文字と呼ばれ、使用されるのはコンマだけではありません。 他の一般的な区切り文字には、タブ( + \ t +)、コロン( )およびセミコロン( +; +)文字が含まれます。 CSVファイルを正しく解析するには、使用されている区切り文字を知る必要があります。

CSVファイルはどこから来たのですか?

CSVファイルは通常、大量のデータを処理するプログラムによって作成されます。 これらは、スプレッドシートやデータベースからデータをエクスポートしたり、他のプログラムでインポートしたり使用したりする便利な方法です。 たとえば、データマイニングプログラムの結果をCSVファイルにエクスポートし、それをスプレッドシートにインポートして、データを分析したり、プレゼンテーション用のグラフを生成したり、公開用のレポートを準備したりできます。

CSVファイルはプログラムで簡単に操作できます。 テキストファイルの入力と文字列操作(Pythonなど)をサポートする言語は、CSVファイルを直接操作できます。

Pythonの組み込みCSVライブラリを使用したCSVファイルの解析

https://docs.python.org/3/library/csv.html [`+ csv `ライブラリ]は、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データを辞書に直接読み込むことができます(技術的には、https://docs.python.org/3/library/collections.html#collections.OrderedDict [Ordered辞書])も同様です。

繰り返しますが、入力ファイル `+ 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 +`オプションパラメータをそれらを含むリストに設定して、独自のキーを指定する必要があります。

オプションのPython CSV `+ reader +`パラメーター

`+ reader +`オブジェクトは、https://docs.python.org/3/library/csv.html?highlight = csv#csv-fmt-params [追加パラメーター]を指定することで、さまざまなスタイルの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ファイルには、コンマで区切られた3つのフィールド、「+ name 」、「 address 」、および「 date Joined 」が含まれています。 問題は、「 address +」フィールドのデータにも郵便番号を示すコンマが含まれていることです。

この状況を処理するには、3つの異なる方法があります。

  • 別の区切り文字を使用
    そうすれば、データ自体でコンマを安全に使用できます。 新しい区切り文字を指定するには、オプションのパラメーター「+ delimiter +」を使用します。

  • データを引用符で囲む
    選択した区切り文字の特殊な性質は、引用符付き文字列では無視されます。 したがって、オプションのパラメーター `+ quotechar +`を使用して、引用に使用する文字を指定できます。 その文字もデータに表示されない限り、問題ありません。

  • データ内の区切り文字をエスケープします
    エスケープ文字は、フォーマット文字列と同じように機能し、エスケープされる文字(この場合は区切り文字)の解釈を無効にします。 エスケープ文字を使用する場合、オプションのパラメーター `+ 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ファイルの読み取りは、http://pandas.pydata.org/index.html [+ pandas +]でも可能です。 分析するデータが多い場合は、強くお勧めします。

`+ pandas `は、高性能のデータ分析ツールと使いやすいデータ構造を提供するオープンソースのPythonライブラリです。 ` pandas +`はすべてのPythonインストールで使用できますが、https://www.anaconda.com/[Anaconda]ディストリビューションの重要な部分であり、https://jupyter.org/[Jupyterノートブック]で非常にうまく機能します。データ、コード、分析結果、視覚化、物語のテキストを共有します。

`+ pandas `とその依存関係を ` Anaconda +`にインストールするのは簡単です:

$ conda install pandas

他のPythonインストールでhttps://realpython.com/pipenv-guide/[+ pip +/+ pipenv +]を使用している場合:

$ pip install pandas

「+ pandas 」の仕組みや使用方法については詳しく説明しません。 ` pandas +`を使用して大きなデータセットを読み取り、分析する詳細な処理については、https://realpython.com/workingのhttps://realpython.com/team/stiwari/[Shantnu Tiwari’s]のすばらしい記事をご覧ください。 -with-large-excel-files-in-pandas/[パンダでの大きなExcelファイルの操作]。

`+ 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ファイルを開き、分析し、読み取り、https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html [ 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]))
<class 'str'>

これらの問題に一度に取り組みましょう。 別の列を `+ 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]))
<class 'pandas._libs.tslibs.timestamps.Timestamp'>

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読み取り、処理、および書き込みタスクは、基本的なPythonライブラリ「+ csv 」で簡単に処理できます。 読み込みおよび処理するデータが大量にある場合、 ` pandas +`ライブラリは、迅速で簡単なCSV処理機能も提供します。

  • __クイズを受ける:*インタラクティブな「PythonでのCSVファイルの読み取りと書き込み」クイズで知識をテストします。 完了すると、学習の進捗状況を経時的に追跡できるようにスコアを受け取ります。

link:/quizzes/python-csv/[クイズに挑戦»]

テキストファイルを解析する他の方法はありますか? もちろん! ANTLR、http://www.dabeaz.com/ply/[PLY]、およびhttps://pypi.org/project/PlyPlus/[PlyPlus]などのライブラリはすべてヘビーデューティ解析を処理し、単純な `+ String +`操作が機能しない場合、常に正規表現があります。

しかし、それらは他の記事のトピックです…