pandasによるデータ加工メモ
Python pandasを利用したデータ加工方法をメモしておきます。
pandasのロード
pandasをpdという名前でimportする。
import pandas as pd
CSVデータの読み込み
read_csv()でCSVファイルを読み込み、DataFrame型に格納する。
>>> pd.read_csv('test.csv')
作成日時 地域ID 売上日 残高
0 20190517 6 20190502 23933698
1 20190517 6 20190504 23868717
2 20190517 6 20190505 23880357
3 20190517 6 20190511 23952177
4 20190517 6 20190512 25113212
文字コードを指定して読み込む
UTF-8以外のファイルを読み込む場合、encodingパラメタに文字コードを指定する。
>>> pd.read_csv("test_sjis.csv", encoding="SHIFT-JIS")
データタイプを指定して読み込む
CSVファイルを読み込む際、カラムのデータ型を明に指定できる。
- dtypeパラメタでデータタイプを指定
- parse_datesパラメタで日付データのカラムを指定
>>> pd.read_csv('test.csv', parse_dates=[0,2], dtype={'残高':float})
作成日時 地域ID 売上日 残高
0 2019-05-17 6 2019-05-02 23933698.0
1 2019-05-17 6 2019-05-04 23868717.0
2 2019-05-17 6 2019-05-05 23880357.0
3 2019-05-17 6 2019-05-11 23952177.0
4 2019-05-17 6 2019-05-12 25113212.0
データタイプを後付で変更する
CSVの読み込み後にデータタイプを変更することも可能。
>>> df = pd.read_csv('test.csv')
>>> df['作成日時'] = pd.to_datetime(df['作成日時'], format='%Y%m%d')
>>> df['売上日'] = pd.to_datetime(df['売上日'], format='%Y%m%d')
>>> df['残高'] = df['残高'].astype(float)
DatetimeIndexの操作(日時配列)
時系列データに使用する日時配列を作成する。
>>> pd.date_range('2019-05-01', '2019-05-08')
DatetimeIndex(['2019-05-01', '2019-05-02', '2019-05-03', '2019-05-04',
'2019-05-05', '2019-05-06', '2019-05-07', '2019-05-08'],
dtype='datetime64[ns]', freq='D')
日時の間隔について
date_range()のfreqパラメタで間隔を変更できる。
- freq='D': 1日単位(デフォルト)
- freq='2D': 2日単位
- freq='H': 1時間単位
- freq='2D5H': 2日と5H単位
DataFrameの操作
読み込んだデータの参照
データ全体を参照
>>> df = pd.read_csv('test.csv')
>>> df.values
>>> df.values
array([[20190517, 6, 20190502, 23933698],
[20190517, 6, 20190504, 23868717],
[20190517, 6, 20190505, 23880357],
[20190517, 6, 20190511, 23952177],
[20190517, 6, 20190512, 25113212]], dtype=int64)
行を指定して参照
>>> df.values[0]
array([20190517, 6, 20190502, 23933698], dtype=int64)
行列を指定して参照
>>> df.values[0][0]
20190517
カラム名を指定して参照
>>> df['作成日時']
0 20190517
1 20190517
2 20190517
3 20190517
4 20190517
Name: 作成日時, dtype: int64
カラム名の変更
カラム名「作成日時」を「Date」に変更する例。
>>> df.rename(columns={'作成日時': 'Date'})
Date 地域ID 売上日 残高
0 20190517 6 20190502 23933698
1 20190517 6 20190504 23868717
2 20190517 6 20190505 23880357
3 20190517 6 20190511 23952177
4 20190517 6 20190512 25113212
DatetimeIndexからDataFrameへの変換
DatetimeIndexからDataFrameに変換する際にカラム名を付ける場合、columnsパラメタを指定する。
>>> didx = pd.date_range('2019-05-01', '2019-05-05')
>>> pd.DataFrame(didx, columns=['売上日'])
売上日
0 2019-05-01
1 2019-05-02
2 2019-05-03
3 2019-05-04
4 2019-05-05
ソート
sort_values()でbyパラメタにカラム名を指定することでソートできる。
>>> df = pd.read_csv('test.csv', parse_dates=[0,2], dtype={'残高':float})
>>> df.sort_values(by='残高')
作成日時 地域ID 売上日 残高
1 2019-05-17 6 2019-05-04 23868717.0
2 2019-05-17 6 2019-05-05 23880357.0
0 2019-05-17 6 2019-05-02 23933698.0
3 2019-05-17 6 2019-05-11 23952177.0
4 2019-05-17 6 2019-05-12 25113212.0
マージ
2つのDataFrameをマージして時系列データを作成する。
マージ後に値が埋まらないフィールドには欠損値(NaN)が格納される。
>>> df1 = pd.DataFrame(pd.date_range('2019-05-01', '2019-05-13'), columns=['売上日'])
>>> df2 = pd.read_csv('test.csv', parse_dates=[0,2], dtype={'残高':float})
>>> pd.merge(left=df1, right=df2, how='outer', left_on='売上日', right_on='売上日')
売上日 作成日時 地域ID 残高
0 2019-05-01 NaT NaN NaN
1 2019-05-02 2019-05-17 6.0 23933698.0
2 2019-05-03 NaT NaN NaN
3 2019-05-04 2019-05-17 6.0 23868717.0
4 2019-05-05 2019-05-17 6.0 23880357.0
5 2019-05-06 NaT NaN NaN
6 2019-05-07 NaT NaN NaN
7 2019-05-08 NaT NaN NaN
8 2019-05-09 NaT NaN NaN
9 2019-05-10 NaT NaN NaN
10 2019-05-11 2019-05-17 6.0 23952177.0
11 2019-05-12 2019-05-17 6.0 25113212.0
12 2019-05-13 NaT NaN NaN
欠損値の処理
欠損値の判定
isnull()でTrueを返すものが欠損値である。
>>> df = pd.merge(left=df1, right=df2, how='outer', left_on='売上日', right_on='売上日')
>>> df.isnull()
売上日 作成日時 地域ID 残高
0 False True True True
1 False False False False
2 False True True True
3 False False False False
4 False False False False
5 False True True True
6 False True True True
7 False True True True
8 False True True True
9 False True True True
10 False False False False
11 False False False False
12 False True True True
どのカラムに欠損値が含まれるかはany()で判定できる。
>>> df.isnull().any()
売上日 False
作成日時 True
地域ID True
残高 True
dtype: bool
前行の値を設定
前行がNaNの場合、欠損値のままとなる。
>>> df.fillna(method='ffill')
売上日 作成日時 地域ID 残高
0 2019-05-01 NaT NaN NaN
1 2019-05-02 2019-05-17 6.0 23933698.0
2 2019-05-03 2019-05-17 6.0 23933698.0
3 2019-05-04 2019-05-17 6.0 23868717.0
4 2019-05-05 2019-05-17 6.0 23880357.0
5 2019-05-06 2019-05-17 6.0 23880357.0
6 2019-05-07 2019-05-17 6.0 23880357.0
7 2019-05-08 2019-05-17 6.0 23880357.0
8 2019-05-09 2019-05-17 6.0 23880357.0
9 2019-05-10 2019-05-17 6.0 23880357.0
10 2019-05-11 2019-05-17 6.0 23952177.0
11 2019-05-12 2019-05-17 6.0 25113212.0
12 2019-05-13 2019-05-17 6.0 25113212.0
指定された値を設定
欠損値NaNのフィールドを指定された値に置き換える。
>>> df = df.fillna(method='ffill')
>>> df.fillna(0)
売上日 作成日時 地域ID 残高
0 2019-05-01 0 0.0 0.0
1 2019-05-02 2019-05-17 00:00:00 6.0 23933698.0
2 2019-05-03 2019-05-17 00:00:00 6.0 23933698.0
3 2019-05-04 2019-05-17 00:00:00 6.0 23868717.0
4 2019-05-05 2019-05-17 00:00:00 6.0 23880357.0
5 2019-05-06 2019-05-17 00:00:00 6.0 23880357.0
6 2019-05-07 2019-05-17 00:00:00 6.0 23880357.0
7 2019-05-08 2019-05-17 00:00:00 6.0 23880357.0
8 2019-05-09 2019-05-17 00:00:00 6.0 23880357.0
9 2019-05-10 2019-05-17 00:00:00 6.0 23880357.0
10 2019-05-11 2019-05-17 00:00:00 6.0 23952177.0
11 2019-05-12 2019-05-17 00:00:00 6.0 25113212.0
12 2019-05-13 2019-05-17 00:00:00 6.0 25113212.0
欠損値を削除
欠損値を含むデータを削除する関数。
>>> df = pd.merge(left=df1, right=df2, how='outer', left_on='売上日', right_on='売上日')
>>> df.dropna()
売上日 作成日時 地域ID 残高
1 2019-05-02 2019-05-17 6.0 23933698.0
3 2019-05-04 2019-05-17 6.0 23868717.0
4 2019-05-05 2019-05-17 6.0 23880357.0
10 2019-05-11 2019-05-17 6.0 23952177.0
11 2019-05-12 2019-05-17 6.0 25113212.0
データの削除
行の削除
>>> df.drop(10, axis=0)
- axis=0は省略できる
- 削除対象は配列で指定できる
列の削除
>>> df.drop('売上日', axis=1)
作成日時 地域ID 残高
0 NaT NaN NaN
1 2019-05-17 6.0 23933698.0
2 NaT NaN NaN
3 2019-05-17 6.0 23868717.0
4 2019-05-17 6.0 23880357.0
5 NaT NaN NaN
6 NaT NaN NaN
7 NaT NaN NaN
8 NaT NaN NaN
9 NaT NaN NaN
10 2019-05-17 6.0 23952177.0
11 2019-05-17 6.0 25113212.0
12 NaT NaN NaN
その他
オリジナルデータの変更
通常、DataFrameの操作はオリジナルデータを破壊しないが、「inplace=True」を指定することでオリジナルデータを直接変更できる。
>>> df.drop(index=0, axid=0, inplace=True)