Pandas read_csv() で Python 例を挙げて

⚡ スマートサマリー

Pandasの`read_csv()`関数は、ローカルまたはリモートのカンマ区切りファイルを、1回の呼び出しでDataFrameに変換します。このチュートリアルでは、UCI成人国勢調査データセットをインポートし、15個の列に名前を付け、groupby集計を使用して結果を要約します。

  • 🔘 電話1回: pd.read_csv() はファイルパス、 URLまたは、読み取りメソッドを公開する任意のオブジェクト。
  • ☑️ 列制御: 列にラベルを付ける名前を指定し、index_col=Falseを指定すると、単純な整数インデックスが保持されます。
  • 空白: skipinitialspace=True は、成人データセット内のすべてのカンマの後に続くスペースを削除します。
  • 🧪 グループ化と集計: groupby() は、カウント、最小値、最大値、平均値、中央値、または標準偏差を使用してフレームを要約します。
  • 🛠️ 大きなファイル: usecols、dtype、chunksizeを使用すると、数ギガバイトのエクスポートにおける解析時間とメモリ使用量を削減できます。
  • ⚠️ 一般的なエラー: エンコーディング、不正な行、およびデータ型の混在には、それぞれ修正するための引数が文書化されています。

Pandas read_csv() と例

Pandas に CSV をインポート

TensorFlow チュートリアルでは、 成人データセットこれは分類タスクによく使用されます。以下で使用するファイルは生データです。 adult.data UCI機械学習リポジトリからのエクスポート、データセットページには圧縮ダウンロードも提供されており、 ucimlrepo 直接パスが解決されなくなった場合はパッケージ化してください。

データはCSV形式で保存されています。データセットには8つのカテゴリ変数が含まれています。

  • ワーククラス
  • 教育
  • 夫婦の
  • 職業
  • 関係
  • レース
  • セックス
  • 母国

そして、6つの連続変数:

  • 年齢
  • fnlwgt
  • 教育番号
  • 資本利得
  • 資本損失
  • 時間_週

収入とともに label 列、これにより、渡す15個の列名が作成されます。 パンダ 次のセクションで説明します。

パンダの read_csv() メソッド

CSVデータセットをインポートするには、オブジェクトpd.read_csv()を使用できます。基本的なシグネチャは次のとおりです。

パンダの read_csv() 構文

pandas.read_csv(filepath_or_buffer, sep=',', names=None, index_col=None, skipinitialspace=False)
  • ファイルパスまたはバッファ: パス、 URLまたはデータを保持するファイルライクオブジェクト
  • sep=',': 使用する区切り文字
  • 名前=なし列に名前を付けます。データセットに10個の列がある場合は、10個の名前を渡す必要があります。
  • index_col=なし: 行インデックスとして使用する列を指定します。False を渡すと、新しい整数インデックスが強制的に使用されます。
  • skipinitialspace=False区切り文字の後のスペースをスキップします

引数の全リストについては、公式 pandas.read_csv() のドキュメント.

パンダの read_csv() の例

以下のコードスニペットは、15個の列すべてに名前を付け、UCIファイルを指定し、このデータセット内の各カンマの後に続くスペースを削除します。

## Import csv
import pandas as pd
## Define path data
COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital',
           'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
           'hours_week', 'native_country', 'label']
PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
df_train = pd.read_csv(PATH,
                       skipinitialspace=True,
                       names = COLUMNS,
                       index_col=False)
df_train.shape

出力:

(32561, 15)

この形状から、32,561行15列であることが確認できたので、COLUMNS内のすべての名前がファイル内のフィールドと一致したことになります。

キー Pandas read_csv() パラメータ

read_csv() 関数は 50 を超える引数を受け付けますが、実際のインポート処理のほとんどを網羅しているのはごく少数の引数です。以下のデフォルト値は、最新の pandas API リファレンスに記載されているものです。

デフォルト 何それがありません
9月 「、」 区切り文字として使用される文字または正規表現。他の形式の場合は、sep=';' または sep='\t' を使用してください。
ヘッダ 「推測する」 列ラベルを含む行番号。ファイルにヘッダー行がない場合は、header=None を渡してください。
設定されていません 列ラベルの明示的なリスト。header=0 と組み合わせると、既存のヘッダーを置き換えることができます。
インデックス列 なし 行インデックスとして使用する列。index_col=False の場合、単純な整数インデックスが強制的に使用されます。
使用列 なし ラベルまたは位置に基づいて、読み込む列のサブセットを指定します。解析時間とメモリ使用量の両方を削減できます。
dtype なし 列ごとのデータ型。例: {'age': 'int32'}。型推論はスキップされます。
na_values なし 成人データセットの「?」プレースホルダーなど、NaNとして読み取られる余分な文字列。
スキップ行数 / 行数 なし 先頭行をスキップするか、最初のN行のデータのみを読み取ります。
日付の解析 なし 読み込み時にdatetime型に変換する列と、date_formatの組み合わせ。
エンコーディング 'utf-8' ファイルのテキストエンコーディング。「latin-1」または旧バージョンのエクスポートには「cp1252」を使用してください。
チャンクサイズ なし ファイルをN行ずつのブロックに分割して出力するイテレータを返します。
悪い行 'エラー' 不正な行の処理方法:行を上げる、警告を表示する、またはスキップする。

このうち2つは特筆に値する。 index_col=False これは、設定しないのとは異なります。これは、Pandasに最初の列を昇格させないように明示的に指示するもので、ファイルの各行が不要な区切り文字で終わっている場合に望ましい動作です。 names ファイルの宣言をサイレントに上書きするので、 header=0 CSVファイルに実際にヘッダー行が含まれている場合は、その横にヘッダー行が添えられます。

パンダの groupby() メソッド

データを確認する簡単な方法は、groupby メソッドを使用することです。このメソッドを使用すると、データをグループごとに集計できます。以下は、groupby() メソッドで使用できる集計の一覧です。

  • カウント: カウント
  • 分: 分
  • 最大: 最大
  • 意味:意味
  • 中央値: 中央値
  • 標準偏差: std
  • ほか

groupby() 関数内では、集計を適用する前に、グループ化の対象となる列を指定します。

一つのグループを見てみましょうping 成人データセットを使用すると、収益の種類(50万ドル以上または50万ドル未満)ごとに、すべての連続変数の平均値が取得できます。

df_train.groupby(['label']).mean()
ラベル 年齢 fnlwgt 教育番号 資本利得 資本損失 時間_週
<= 50K 36.783738 190340.86517 9.595065 148.752468 53.142921 38.840210
> 50K 44.249841 188005.00000 11.611657 4006.142456 195.001530 45.473026

世帯の種類別に最低年齢を確認できます。

df_train.groupby(['label'])['age'].min()
label
<=50K    17
>50K     19
Name: age, dtype: int64

複数の列でグループ化することもできます。たとえば、世帯の種類や婚姻状況に応じて最大のキャピタルゲインを取得できます。

df_train.groupby(['label', 'marital'])['capital_gain'].max()
label  marital
<=50K  Divorced                 34095
       Married-AF-spouse         2653
       Married-civ-spouse       41310
       Married-spouse-absent     6849
       Never-married            34095
       Separated                 7443
       Widowed                   6849
>50K   Divorced                 99999
       Married-AF-spouse         7298
       Married-civ-spouse       99999
       Married-spouse-absent    99999
       Never-married            99999
       Separated                99999
       Widowed                  99999
Name: capital_gain, dtype: int64

グループ化後にグラフを作成できます。その方法の一つは、グループ化された結果を直接グラフ化することです。

より分かりやすいグラフを作成するには、mean() の後に unstack() を適用して、婚姻状況をインデックスから列に移動させます。こうすることで、グラフは収入ラベルごとに 1 つのグループに分かれ、フラットな多段階インデックスで生成される 14 本の棒グラフ (2 × 7) の代わりに表示されます。

あなたが使用している場合 Jupyter Notebook %matplotlib をインラインで追加することを忘れないでください。そうしないと、プロットが表示されません。

%matplotlib inline
df_plot = df_train.groupby(['label', 'marital'])['capital_gain'].mean().unstack()
df_plot

その積み重ねられていないフレームを棒グラフとしてプロットすると、以下の図が得られます。

所得区分と婚姻状況別の平均資本利得を示す棒グラフ

Pandasで大きなCSVファイルを読み込む方法

成人データセットは小さいですが、数ギガバイトのエクスポートでは同じ処理が停止する可能性があります。3つの引数でほとんどの処理が行われます。

  • 使用列 実際に必要な列のみを読み込みます。pandasのドキュメントによると、これにより解析速度が大幅に向上し、メモリ使用量も削減されるとのことです。
  • dtype 各列を型に固定するため、Pandas は型推論をスキップし、デフォルトでは整数を 64 ビットに拡張しません。
  • チャンクサイズ DataFrameではなくTextFileReaderを返すため、N行のブロックをループ処理して、処理を進めながら集計することができます。
import pandas as pd

# read only the columns you need, with explicit types
cols  = ['age', 'education', 'capital_gain', 'label']
types = {'age': 'int32', 'capital_gain': 'int32'}
df = pd.read_csv(PATH, names=COLUMNS, usecols=cols, dtype=types,
                 skipinitialspace=True, index_col=False)

# stream the file in fixed-size chunks instead of loading it whole
total = 0
for chunk in pd.read_csv(PATH, names=COLUMNS, chunksize=10000,
                         skipinitialspace=True, index_col=False):
    total = total + len(chunk)
print(total)

基本的な準備が整ったら、さらに2つの選択肢が役立ちます。 engine='pyarrow' マルチスレッドのArrowパーサーに切り替え、 dtype_backend='pyarrow' 結果は矢印付きの列に保持されます。 low_memory デフォルトでは True に設定されており、ファイルを内部的に分割して解析しますが、列内に複数の型が混在する可能性があります。そのため、この設定に頼るのではなく、明示的な dtype を設定してください。

最後に、 compression='infer' これは、.gz、.zip、.bz2、.xz、または.zstで終わるパスがその場で解凍されることを意味するため、アーカイブを読み込む前に解凍する必要はありません。

Pandasのread_csv()でよく発生するエラーとその解決方法

read_csv() の失敗のほとんどは 4 つの原因によるもので、それぞれに解決策となる引数が文書化されています。

エラー 原因となる 修正する
ファイルが見つかりませんエラー パスはスクリプトではなく、作業ディレクトリからの相対パスです。 絶対パスを使用するか、 URL スキームは、http、ftp、s3、gs、またはfileのいずれかです。
UnicodeDecodeError ファイルはデフォルトのエンコーディングであるUTF-8ではありません。 encoding='latin-1' または正しいコーデックを指定するか、encoding_errors='replace' を指定してください。
ParserError: データのトークン化エラー 行には、ヘッダーで宣言されているよりも多くのフィールドが含まれています。 on_bad_lines='skip' または 'warn' を渡すか、正しい sep を設定します。
DtypeWarning: 列に複数の型が含まれています チャンク化された型推論では、1つの列に異なる型が検出されました。 明示的なdtypeを設定するか、low_memory=Falseを設定してください。
列が1つずれています 末尾に区切り文字があると、Pandas は最初のフィールドをインデックスに昇格させます。 index_col=False を渡します。

成人データセットでは、欠損値のケースが直接的に示されています。不明な職種、職業、出身国は、明示的に宣言しない限り、リテラルの疑問符として保存されるため、文字列「?」として表示されます。

# tolerate rows with too many fields instead of raising
df = pd.read_csv(PATH, names=COLUMNS, on_bad_lines='skip')

# read a file that is not UTF-8
df = pd.read_csv('sales.csv', encoding='latin-1')

# treat the dataset's '?' placeholder as a missing value
df = pd.read_csv(PATH, names=COLUMNS, na_values='?', skipinitialspace=True)

よくあるご質問

どちらも同じパーサーを呼び出します。read_csv() はデフォルトでカンマ区切りですが、read_table() は一般的な区切り文字付きファイルを読み込み、区切り文字を自分で設定する必要があります。カンマ区切りのファイルには read_csv() を、タブ区切りまたはパイプ区切りのエクスポートには read_table() を使用してください。

df.to_csv('output.csv', index=False) を呼び出します。ping インデックスを使用すると、次回の読み込み時に名前のない最初の列が生成されることがなくなります。ファイルのインポート時に使用した設定を反映させるには、sep、encoding、またはcompression引数を追加してください。

parse_dates 関数に列名または列位置を渡し、レイアウトが ISO 8601 でない場合は date_format を追加してください。例えば、date_format='%d/%m/%Y' のように指定します。これがない場合、日付列は単なるオブジェクト文字列として渡されるため、別途 to_datetime 関数を呼び出す必要があります。

sep に文字を設定します。例えば、sep=';' または sep='\t' のように指定します。1 文字より長い区切り文字は正規表現として扱われ、処理速度が低下します。 Python engine.sep=None は、そのエンジンが最初の有効な行から区切り文字を検出できるようにします。

nrows を使用すると、返されるデータ行数を制限でき、skiprows を使用すると、先頭の行のブロックをスキップできます。これらを組み合わせると、ファイルをページ送りできます。たとえば、skiprows=1000000 と nrows=999999 を組み合わせると、2 つ目の 100 万行を読み込むことができます。

はい。圧縮のデフォルト設定は「推論」なので、.gz、.zip、.bz2、.xz、.zstで終わるパスは自動的に解凍されます。 URLhttp、ftp、s3、gs、またはファイルを使用する方法はすべて機能し、storage_optionsは認証情報をリモートバックエンドに渡します。

学習済みのモデルは、型エラーの可能性が高い箇所を特定し、ほぼ重複するカテゴリのスペルをクラスタリングし、欠損値を周囲の列から補完します。これにより、手動でのクリーンアップ作業は、ルールベースのna_valuesやdtype設定だけでは解決できない行に絞り込まれます。

Copilotは、ファイルのサンプルを読み取るとすぐに定型コードを生成します。引数リストは、データ型やエンコーディングが推測されることが多いため、あくまでも下書きとして扱ってください。生成されたキーワードは、実行前に必ずpandas APIリファレンスと照らし合わせて確認してください。