【Pandas】CSVを読み込み、DataFrameを編集する方法

Moneyforward ME の家計簿からCSVファイルをダウンロード、Pythonで読み込み

Monyforward ME の家計簿からCSVファイルをダウンロードする。
ダウンロードしたファイルを、”2022-03-01_2022-03-31.csv” とする。
このファイルをPython Pandasを使って、DataFrameに読み込む。

import pandas as pd

# 2022-03-01_2022-03-31.csv は、Moneyforward ME からダウンロードしたもの
CSV_FILE = r'/Path/To/CSV/2022-03-01_2022-03-31.csv'

# CSVファイルを読み込む
df = pd.read_csv(CSV_FILE, encoding='cp932')

encoding = ‘utf-8’ では読み込みエラー。

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8c in position 1: invalid start byte

file –mime コマンドでエンコードを確認する。

$ file --mime /Path/To/CSV/2022-03-01_2022-03-31.csv
/Path/To/CSV/2022-03-01_2022-03-31.csv: application/csv; charset=unknown-8bit

Shift-JIS の場合、charset が uknown-8bit になる。Shift-JIS の場合、read_csv で読み込むときに、encoding=’cp932′ を指定すると、正常に読み出せる。

以下、Pandasでよく使うAPIを列挙。

欠損値(Nan)の操作

# 各要素が欠損値(Nan)かどうかを確認
df.isna()
# 列ごとにNanの合計を確認
df.isna().sum()
# 全体でNanの合計を確認
df.isna().sum().sum()
# 全ての行がNanの場合に削除
df.dropna(how='all')
# 全ての列がNanの場合に削除
df.dropna(how='all', axis=1)
# Nanが一つでも含まれる行を削除
df.dropna(how='any')
# 指定した列にNanの場合に削除
df.dropna(subset=['メモ'])
# 指定した列が全てNanの場合に削除
df.dropna(subset=['メモ', '内容'], how='all')
# オブジェクト自体の変更 inplace=True でdfも変更される
df.dropna(subset=['メモ'], inplace=True)
# 欠損値を0で置き換え
df.fillna(0)

DataFrameの操作

# 各列の型確認
df.dtypes
# 各列を表示
df['日付']
# 特定の行を表示(0始まりに注意。0~3行目までの4行を表示する。4行目は含まれず。)
df[0:4]
# 4行目を表示
df.iloc[4]
# 4行目の中身を表示
df.iloc[4]['内容']
# 指定した列でソート
df.sort_values('内容')
# indexを振り直し (元のindexが新たな列として残る。drop=Trueを指定すると、残らない。)
df.reset_index()
# 特定の条件を満たす行だけ抽出
df[df['金額(円)'] > 0]
df[df['保有金融機関'] == 'PayPay']
# 特定の文字列を含む行だけ抽出(正規表現も可能)
df[df['保有金融機関'].str.contains('Pay')]
df[df['保有金融機関'].str.contains('P.*y')]
# 複数の条件を満たす行を抽出
df[(df['金額(円)'] > 0) & (df['保有金融機関'] == 'PayPay')]
# 新しい列を追加
df['追加列'] = 0
# str型の日付をDatetimeに変換
df['日付'] = pd.to_datetime(df['日付'])
# 特定の日付以降の行を抽出
import datetime as dt
df[df['日付'] > dt.datetime(2022, 3, 3)]
# 特定の期間の行を抽出
df[(df['日付'] > dt.datetime(2022, 3, 3)) & (df['日付'] < dt.datetime(2022, 3, 10))]