pandas の基本的な使い方、備忘録です。
公式
pandas: powerful Python data analysis toolkit
jupyter notebook を使っている時は、メソッドにカーソルを置いて、Shift + Tab でそのメソッドの説明が読めます。
DataFrameの生成と操作
CSVファイル
読み込み
windows で日本語のファイルを扱う場合は、encoding='cp932'を引数にします。
>>> import pandas as pd
>>> df = pd.read_csv('test_load.csv')
保存
>>> df.to_csv('test_save.csv', index = False)
表の作成
ほとんどないですが、スクラッチからDataFrameを生成する場合です。
>>> df_grade = pd.DataFrame(data={'name':['Taro', 'Jiro', 'Saburo'], 'age':[5, 10, 15], 'grade':[50, 80, 70]})
>>> df_grade
name age grade
0 Taro 5 50
1 Jiro 10 80
2 Saburo 15 70
列の取り出し
Series として取り出し
>>> df_grade['name'] 0 Taro 1 Jiro 2 Saburo Name: name, dtype: object
DataFrame として一列取り出し
>>> df_grade[['name']]
name
0 Taro
1 Jiro
2 Saburo
DataFrame として複数列取り出し
>>> df_grade[['name', "age"]]
name age
0 Taro 5
1 Jiro 10
2 Saburo 15
行の取り出し
>>> df_grade[1:3]
name age grade
1 Jiro 10 80
2 Saburo 15 70
行のフィルタリング
boolean の配列を作成し、ture の行のみ抽出することができます。
>>> arr_bool = df_grade["grade"] >= 70
>>> arr_bool
0 False
1 True
2 True
Name: grade, dtype: bool
>>> df_grade[arr_bool]
name age grade
1 Jiro 10 80
2 Saburo 15 70
上の操作は1行で行えます。
>>> df_grade[df_grade["grade"] >= 70]
name age grade
1 Jiro 10 80
2 Saburo 15 70
複数の条件で抜き出すこともできます。
# df[(条件) & (条件)]
# df[(条件) | (条件)]
>>> df_grade[(df_grade['grade'] >= 70) & (df_grade['age']>10)]
name age grade
2 Saburo 15 70
以下の関数も同じように行のフィルタリングに使うことができます。
loc及びilocよる取り出し
location や index location の略だと思います。
>>> df_grade.loc[:,'name']
0 Taro
1 Jiro
2 Saburo
Name: name, dtype: object
>>> df_grade.loc[:,['name', 'age']]
name age
0 Taro 5
1 Jiro 10
2 Saburo 15
>>> df_grade.iloc[1:3,1:3]
age grade
1 10 80
2 15 70
列名の変更
>>> df_grade.rename(columns={'name': 'first name'})
first name age grade
0 Taro 5 50
1 Jiro 10 80
2 Saburo 15 70
>>> df_grade.rename(columns={'name': 'first name', 'age': 'full age'})
first name full age grade
0 Taro 5 50
1 Jiro 10 80
2 Saburo 15 70
ソート
>>> df_grade
name age grade
0 Taro 5 50
1 Jiro 10 80
2 Saburo 15 70
>>> df_grade.sort_values('grade')
name age grade
0 Taro 5 50
2 Saburo 15 70
1 Jiro 10 80
列の追加
>>> df_grade['gender']='m'
>>> df_grade
name age grade gender
0 Taro 5 50 m
1 Jiro 10 80 m
2 Saburo 15 70 m
行の追加
>>> df_grade_f = pd.DataFrame(data={'name':['Hanako', 'Kanako', 'Nanako'], 'age':[8, 12, 16], 'grade':[55, 85, 75], 'gender':['f', 'f', 'f']})
>>> df_grade_f
name age grade gender
0 Hanako 8 55 f
1 Kanako 12 85 f
2 Nanako 16 75 f
>>> df_grade = df_grade.append(df_grade_f, ignore_index=True)
>>> df_grade
name age grade gender
0 Taro 5 50 m
1 Jiro 10 80 m
2 Saburo 15 70 m
3 Hanako 8 55 f
4 Kanako 12 85 f
5 Nanako 16 75 f
groupby
SQLのgroupbyと同じような感覚です。
集計関数
>>> df_grade[['gender', 'grade']].groupby('gender').mean()
gender grade
f 71.666667
m 66.666667
ピボットテーブル
>>> df_grade.pivot_table(values='grade', index=['gender'], columns=['age'], aggfunc=sum) age 5 8 10 12 15 16 gender f NaN 55.0 NaN 85.0 NaN 75.0 m 50.0 NaN 80.0 NaN 70.0 NaN
テーブルの結合
SQLの join と同じような感覚です。
>>> print(df) user_id name score 0 0 tanaka 20 1 1 yamada 40 2 2 takahasi 30 3 3 sato 50 >>> print(df2) device_id user_id weapon 0 0 2 sword 1 1 1 knife 2 2 10 arrow 3 3 5 lod >>> df.merge(df2, left_on = 'user_id', right_on = 'user_id', how = "inner") user_id name score device_id weapon 0 1 yamada 40 1 knife 1 2 takahasi 30 0 sword >>>
また、キーに複数の列を指定したい場合は、on にキーとする列名のリストを渡します。
同じような関数でjoinもあります。
join は、デフォルトでindexを使ってjoin してくれます。
関数を列に適用
データ例を作成します。
>>> import numpy as np
>>> df_norm_data = pd.DataFrame(data = {'data1': np.random.normal(loc = 2, scale = 4, size = 1000), 'data2': np.random.normal(loc = 5, scale = 3, size = 1000)})
>>> df_norm_data.head(10)
data1 data2
0 0.526135 4.127409
1 -0.768730 5.385454
2 -0.417630 8.570257
3 0.734564 4.505055
4 -3.589744 6.321659
5 0.140246 -2.551671
6 2.430789 5.759566
7 -5.400427 5.946560
8 5.438419 6.283404
9 5.050853 2.611055
関数を列に適用し、新しい列を作成する、または既存の列を変更することができます。
>>> df_norm_data['data1'] = df_norm_data['data1'].apply(round, 'data1') >>> df_norm_data.head() data1 data2 0 1 4.127409 1 -1 5.385454 2 0 8.570257 3 1 4.505055 4 -4 6.321659
統計分析
基本的な統計
ささっと基本的な統計を確認します。
>>> df_norm_data.describe()
data1 data2
count 1000.000000 1000.000000
mean 1.882876 4.891268
std 4.027441 3.085061
min -9.993403 -4.048162
25% -0.916317 2.745270
50% 1.850233 5.043616
75% 4.579636 6.874027
max 15.382466 14.683068
列数
>>> len(df_norm_data.columns) 2 >>> df_norm_data.shape[1] 2
列が省略されてしまう時、表示する列数を指定します。
>>> pd.set_option('display.max_columns', 50)
行数
>>> len(df_norm_data) 1000 >>> df_norm_data.shape[0] 1000
もうちょっと行を見たいとき、見たくないときは、表示する行数を指定します。
>>> pd.set_option('display.max_rows', 50)
データの可視化
さくっとグラフにする。
また、それぞれメソッドが準備されている場合もあります。
ちゃんとしたい時は、素直に matplotlib からいじった方が結局は仕事が速いです。
ヒストグラム
>>> data1.hist();
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x0000017318A22400>]],
dtype=object)

散布図
>>> df_norm_data.plot.scatter(x = 'data1', y = 'data2'); <atplotlib.axes._subplots.AxesSubplot object at 0x000001731685F780>

棒グラフ
>>> df_grade.plot.bar() <matplotlib.axes._subplots.AxesSubplot object at 0x00000173168A6080>
