はじめに
みなさんはDataFrameの操作を全て覚えているだろうか。自慢ではないが、私は全て覚えることはできておらず、やりたい操作がある度にGoogle検索をかけている。結果、いつも同じWebサイトにとび、「あぁ、そうだこれこれ……」と思い出し、コーディングを進めている。私はこの作業に嫌気がさした。ここに、極めて利己的なまとめページを作成する。もしこれが誰かの助けにもなれば、筆者、望外の喜びである。
A. データフレームの入出力関連
DataFrameの作成
input_output.py
df = pd.DataFrame([[0,1,2,3], \
[4,5,6,7], \
[8,9,10,11]],
columns=['col_0','col_1','col_2','col_3'], \
index=['row_0','row_1','row_2'])
out.sh
>>> df.head()
col_0 col_1 col_2 col_3
row_0 0 1 2 3
row_1 4 5 6 7
row_2 8 9 10 11
indexとcolumnsの取得
ind_col.py
# 列名、columnsの取得
df.columns
# > Index(['col_0', 'col_1', 'col_2', 'col_3'], dtype='object')
# インデックスの取得
df.index
# > Index(['row_0', 'row_1', 'row_2'], dtype='object')
DataFrameの大きさなどを確認
dfsize.py
df.info()
Excelファイルの読み込み/書き出し
ここで一点注意。なぜかファイルを読み込み/書き出しの際は、"columns"は"header"、"index"は"index_col"と名前が変わる(何故...?)。
excel.py
# 読み込み
df = pd.read_excel(filepath, header=0, index_col=0, sheet_name=0)
# 書き出し
# 行名・列名を書き出す必要がないときは、index/headerをFalseにする
df.to_excel(filepath, index=True, header=True)
# ExcelWriterオブジェクトを使うと、複数のpandas.DataFrameオブジェクトを別々のシートに書き出すことが可能。
with pd.ExcelWriter('data/dst/pandas_to_excel_multi.xlsx') as writer:
df.to_excel(writer, sheet_name='sheet1')
df2.to_excel(writer, sheet_name='sheet2')
対応関係を下表にまとめる。
列名の行 | 行名の列 | |
---|---|---|
DataFrameへのアクセス | columns | index |
ファイルの読み込み | header | index_col |
ファイルの書き出し | header | index |
B. データフレームの値へのアクセス関連
列・行の値を取得してリスト・numpy arrayに変換
value.py
# ある列の値を取得し、listに変換
l = df['Column_Name'].tolist()
# ある行の値を取得し、listに変換
r = df.loc['Index_Name'].tolist()
#ある列の値を取得し、numpy arrayに変換
l = df['Column_Name'].values
#ある行の値を取得し、numpy arrayに変換
r = df.loc['Index_Name'].values
この時tolist()をしないと、Series型になる。
C. 列の値を用いた計算関連
applyを用いない方法
calc_non_apply.py
df['B_minus_A'] = df['A'] - df['B']
applyを用いる方法
calc_apply.py
def divided_by_2(x):
return float(x) / 2
df['A_divided_by_2'] = df['A'].apply(divided_by_2)
D. ソーティング関連
sort.py
# ある列に関して、昇順でソート
df.sort_values('Column_Name')
# 降順にしたい場合は、ascending=Falseとする
df.sort_values('Column_Name', ascending=False)
E. query関連
数値操作
query.py
# 不等式で絞り込み
df.query('Column_Name > 10') #単条件
df.query('Column_Name > 10 and Column_Name_2 < 10') #複数条件
# 変数を使用 (@をつける)
g = 10
df.query('Column_Name > @g')
# リストを使用して、複数項目に一致する行を抽出する
value_list = ['Value1','Value2','Value3']
df.query('Column_Name in @value_list')
# 列名に変数を使用することができる -> f文字を使用
g = 10
cn = 'Column_Name'
df.query(f'{cn} > @g')
# -> Column_Name列に格納されている値が10以上である行を残すことができる!
文字列操作
query.py
# 特定の文字を含む
df.query('Column_Name.str.contains("some")')
# 特定の文字ではじまる
df.query('Column_Name.str.startswith("some")')
# 特定の文字でおわる
df.query('Column_Name.str.endswith("some")')
F. queryを使わない絞り込み
nonquery.py
# 条件一つ
df[df['Column_Name'] < 0.5]
# 複数条件
df[(df['Column_Name'] < 0.5) and (df['Column_Name_2'] == 'Something')]
df[(df['Column_Name'] < 0.5) or (df['Column_Name_2'] == 'Something')]
# 列名を直接指定して絞り込み
df[['col_1','col_2','col_3']]
# 行名を直接指定して絞り込み
df.loc[['index_1','index_2','index_3']]
G. 空値関連
列Aの空値を列Bの値で埋める
fillna.py
df['A'].fillna(df['B'], inplace=True)
H. 行・列の追加関連
既存のデータフレームに行を追加
add_row.py
# 行名を'Ind'とし、新規行を追加
df.loc['Ind'] = ['Str1', 4, 'Str2']