pandasのデータ処理でよく使う便利構文まとめ
目次
こんにちは。
今日はPythonのpandasによるデータ処理でよく使う構文をまとめてみようと思います。
【前置き】pandasを使う理由
時代はデータサイエンス!その前に...
昨今ビジネスにおけるデータサイエンスの需要が高まっています。いわゆるビッグデータ分析ですね。
つまり顧客の行動履歴などの企業が持つデータから意味を見出して、新しい価値(サービスや商品といったビジネス)を創出しようという試みが活発になっています。
しかし、ただ大量のデータを集めても、その効果を発揮させるためには、データの前処理が欠かせません。
前処理って何だ
前処理というのは、分析の目的に応じて不要なデータをある条件で絞ったり、データを整形(計算で扱いやすい形に変形)することを指します。
また、分析の規模が大きくなってくると、複数のデータを結合したりすることもあります。
pandasって何だ
pandasはプログラミング言語であるPythonのライブラリの一つで、Excelのような表形式のデータを扱うことを得意としています。
基本的にビッグデータというものは表のような形で扱います。それをプログラム上で効率よく扱うということは、データ処理を効率よく行うこと、つまりビジネスにおいて無駄な作業を減らして新しい価値を作るスピードを加速できます。
Pythonやpandasは無料で使えますし、世界でも人気の言語です。pandasを使いこなすことは、間違いなくこれからのビッグデータ時代に必要なスキルの一つと言えると思います。
やっと本題。 pandasの便利な構文まとめ
少しpandasを使う背景について長くなってしまいましたが、ここからは構文を箇条書きベースでさくさく書いていきます。私もハンドブック的に使う予定です。
覚えやすいように、簡単な解説も混ぜながらまとめてみます。
使用環境
ちなみに私が今回使用している環境です。
- Mac OS : Catalina 10.15.4
- Python3 version : 3.8.2
pandasの導入
import pandas as pd
データフレームの作成
2次元配列をDataFrameにします。
l = [['a1','b1'],['a2','b2']]
df = pd.DataFrame(l)
列やインデックスに名前をつける場合
cols = ['col_A', 'col_B']
rows = ['row_1', 'row_2']
df = pd.DataFrame(l, columns=cols, index=rows)
CSVファイルの入出力
CSVファイルを読み込み
df = pd.read_csv('filename.csv', encoding='utf-8')
オプションでheaader=None
とつければ列名は連番で自動付与されます。
CSVファイルに出力
df.to_csv('filename.csv', index=False, header=False)
入力はpandasのメソッドですが、出力はDataFrameのメソッドとして呼びます。
データの選択
ある列col
の中身を見たい
df['col']
df.col # 列名が英語の場合
列名をstring
、つまりシングルクォーテーションで渡します。
複数列見たい
df[['col1','col2']]
[[]]
と、2つ重なるのに注意ですね。
複数ある場合の列名はリストで渡すので、内側がリストの[]
です。外側がDataFrameの[]
。
行の選択
loc
は行名、iloc
は行番号を指定します。
df.loc[0]
df.iloc[0]
要素の選択
df.at[0,'a']
df.iat[0,0]
at
は行名・列名で選択し、iat
は行番号・列番号で指定します。
データの書き換え
列名の書き換え
配列で一気に書き換える
cols = ['A','B','C','D']
df.columns = cols
columns
メソッドで列名を呼びます。そこにcols
リストを代入することでdf
の列名を上書きできます。
列名の一部を書き換えるには、
df.rename(columns={'A':'a', 'B':'b'})
とします。置き換えて更新するには、df = df.rename(...)
とすればよいです。
データの中身を置き換え
前の項で紹介した各種選択方法で列や要素を選択し、代入すれば上書きされます。 サイズが異なるとうまくいきませんので注意。
df.iat[0,0] = 1
NULL値を置換したい
NULLの場合は専用のメソッドがあります。
df['A'].fillna(0)
この例ではA列のNULL値をすべて0で置換しています。
列の追加・削除
新しく列を追加したい場合
df['new_col'] = 0
この例では、すべて0が入った列が作成されます。(ブロードキャスト。)
列の削除をしたい場合
df.drop('a',axis=1)
axis
を指定しないか、0にすると、行を指定して削除できます。
df.drop(0,axis=0)
計算・演算
列同士の計算
列AとBを掛け算したい場合、
df['result'] = df['A'] * df['B']
新たにresult
という列を作成して、結果をそこに格納しています。
もちろん掛け算だけでなく、四則演算やnumpy
の演算が可能です。
import numpy as np
df['result'] = np.floor(df['A'] - df['B']/10 ) + .1
こんなことも可能。Excelの計算式のイメージで使えますね。
列の値をまとめて集計したい
df['A'].sum()
.sum()
や.mean()
など.
を使って呼び出せる構文をメソッドといいます。
統計量を見る際に便利なメソッドがあります。
df.describe()
なんとこの一行でDataFrameの全ての列に対して以下の統計量が確認できます。
- count データ数
- mean 平均値
- std 標準偏差
- min 最小値
- 25% 25パーセンタイル
- 50% 50パーセンタイル
- 75% 75パーセンタイル
- max 最大値
列を指定すれば、その列の統計量だけ見ることもできます。確認できる値は上記と同じです。
df['A'].describe()
列の値をグループごとに集計したい
列Aが同じもの同士で、B列の値を合計したいとき
df.groupby('A')['B'].sum()
groupby
メソッドを使う場合、グループ化したい列の名は('')
で指定します。
よく使うのは、年月や日付といった時間軸や、地域といった位置情報の軸ですね。
また、集計したい列はDataFrameの列選択のことなので[]
で指定します。
集計方法はメソッドとして.sum()
や.mean()
で呼べます。これはgroupbyを使わなくても同様ですね。
抽出
データの抽出です。例外処理にも使えるのでかなり使用頻度高いです。
ある列の中身がNULLの行を削除したい
df = df[~df['A'].isnull()]
分解して考えると、
df['A'].isnull()
これでデータのNull値の行がTRUE
で返ってきます。
~
はNOT
を意味するので、NULL以外の行です。
df[ ]
の中にdf
と同じ長さのBoolean型Series配列を与えると、TRUE
の行だけ抽出できるので、結果的にNULL以外の行が抽出できます。
ある条件に一致する行を抽出したい
上のテクニックと同じ考え方です。A列の中身が100の行を抽出したい場合は以下のようにします。
df[df['A']==100]
つまりdf[]
の中にboolean
のSeries配列を作ってあげればよいのですね。
==
でなくとも、あらゆる条件式が使えます。
ある条件に一致する行を削除したい
上と同じ考え方です。「一致しない行を抽出する」、と考えます。
たとえば100以上の値がエラーで削除したい場合は、100未満を抽出します。
df[df['A']<100]
データの中身を確認したい
NULLの行があるか確認したい
booleanの便利なところは、sum
でTRUE
の数を合計できることですね。ちなみにmean
で発生率を出すことができます。
A列のデータにNULLが何個あるかを知りたいときは以下です。
df['A'].isnull().sum()
これで全ての列にあるNULLの数を調べることもできます。
df.isnull().sum()
どんな値が入っているか知りたい
先頭x行を見たいとき
df.head(x)
xを指定しないと、5行見れます。
ユニークな値、つまり重複しない値の種類を知りたい場合
df['A'].unique()
ユニークな値の頻度を知りたい場合、つまりどの値が何個入っているかを知りたい場合
df['A'].value_counts()
counts
とs
がつくのが注意ですね。
DataFrameの行や列を省略しないで表示させたいとき
中身をちゃんと見たいのに表示されず...
で省略されてしまうとき。
pd.set_option('display.max_rows', 100) # 100行見たい
pd.set_option('display.max_columns', 100) # 100列見たい
このようにset_option
してあげてからdf
と打ってあげると、ちゃんと中身が表示されます。
引数の100の部分はデータの数に合わせて調整しましょう。
重複している行を確認・抽出したい
duplicated
のメソッドを使うことでboolean
列で返ってきます。重複しているものがTRUE
、ユニークがFALSE
。
df.duplicated(subset=['A','B'], keep=False)
重複を判定する列はsubset
としてlist
で渡します。(1列ならstring
でも可。)
keep=False
は重複している行すべて(重複しているもの、重複されているもの)がTRUE
で返ってきます。
上記の例だとA
,B
列のデータが一致する行が全てTRUE
なので、以下のようにdf[]
の中に書くことで、一致する行を全て取り出せます。
df[df.duplicated(subset=['A','B'], keep=False)]
デフォルトはkeep='first'
で、最初に出てきた行(重複される方)はFALSE
で返ってきます。
keep='last'
で最後に重複するものをFALSE
にできます。
keepする方がFALSE
になるのは感覚と異なるかもしれません。重複を取り出したいというモチベーションが元にあるメソッドなので、取り出すもの(=元のdfにkeepされないもの)がTRUE
で、keepするもの(=元のdfに残しておきたいもの)がFALSE
ということです。
df[~df.duplicated(keep='last')]
たとえば日付順に並んでいるDataFrameにこのようにすれば、重複している行に関しては、古い行を除外して、最新の日付の行のみを取り出すことができます。
グラフで可視化したい
簡単にデータの傾向を見たいときは、やはりグラフが一番ですね。
df.plot('A','B')
これでA列の値をx軸にとり、B列の値をy軸にとった平面プロット(折れ線グラフ)ができます。
df.plot('A',['B','C'])
2本の列データを並列に見たい場合はこのようにリストで渡せば良いです。2本の折れ線グラフができます。
まとめ
というわけでビッグデータ時代に便利なツール、pandasでよく使う構文やテクニックをまとめてみました。
特にデータの中身を確認したり、エラー値を除外するのは必ずと言っていいほど使う重要な処理です。ぜひ使いこなしたいですね。
また頻出の重要テクニックがあれば追記してまとめていきたいと思います。
参考
私が学習に使用した本はこちらです。Pythonの基礎から体系的に学習したい方におすすめです。
Pythonデータサイエンスハンドブック ―Jupyter、NumPy、pandas、Matplotlib、scikit-learnを使ったデータ分析、機械学習 単行本(ソフトカバー) –pandasの章のあとには機械学習や可視化の方法もまとめてあり、データサイエンスのスキルが幅広く習得できるようになっています。
オライリーの本は学術書っぽい硬派な感じで、個人的にはとても好きです。