pandas メモ2022年11月6日 | |
はじめにpandas についてのメモ。Jupyter Notebook での利用を想定。 インストール$ pip install pandas 準備%matplotlib inline from matplotlib import pyplot as plt import numpy as np import pandas as pd データフレーム基本pandas の基本となるデータ構造はデータフレームである。 df = pd.DataFrame() Excel で作る表みたいなイメージである。列に名前をつけてデータを割り当てられる。 df["身長"] = [147.9, 163.5, 159.8, 155.1, 163.3, 158.7, 172.0, 161.2, 153.9, 161.6] df["体重"] = [41.7, 60.2, 47.0, 53.2, 48.3, 59.7, 58.5, 49.0, 46.7, 44.5] df の出力結果は以下のようになる。
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
5 158.7 59.7
6 172.0 58.5
7 161.2 49.0
8 153.9 46.7
9 161.6 44.5
ラベルを得たい場合は、次のようにする。 >>> df.columns Index(['身長', '体重'], dtype='object') データの個数が欲しい場合は、ふつうに len() でよい。 >>> len(df) 10 データにアクセスするには、次のようにする。 >>> df["身長"] 0 147.9 1 163.5 2 159.8 3 155.1 4 163.3 5 158.7 6 172.0 7 161.2 8 153.9 9 161.6 Name: 身長, dtype: int64 >>> df["身長"][0] 147.9 次のようにしてもよい。
>>> df.values[:, 0]
array([147.9, 163.5, 159.8, 155.1, 163.3, 158.7, 172. , 161.2, 153.9,
161.6])
NumPy のデータとして得られる。ラベルのインデックスは次のように得られる。
>>> df.columns.get_loc("身長")
0
データを抽出するには次のようにする。 >>> df[(df["身長"] > 160) & (df["体重"] < 50)] 身長 体重 4 163.3 48.3 7 161.2 49.0 9 161.6 44.5 計算総和や平均値を得ることができる。 >>> df["身長"].sum() 1597.0 >>> df["身長"].mean() 159.7 列ごとの平均をとるには次のようにできる。 >>> df.apply(lambda x: x.mean()) 身長 159.70 体重 50.88 dtype: float64 行ごとに計算したい場合は、次のようにできる。
>>> df["BMI"] = df.apply(lambda x: round(x["体重"]/(x["身長"]/100.)**2, 1), axis=1)
>>> df
身長 体重 BMI
0 147.9 41.7 19.1
1 163.5 60.2 22.5
2 159.8 47.0 18.4
3 155.1 53.2 22.1
4 163.3 48.3 18.1
5 158.7 59.7 23.7
6 172.0 58.5 19.8
7 161.2 49.0 18.9
8 153.9 46.7 19.7
9 161.6 44.5 17.0
要素ごとに処理を行いたい場合は、次のようにする。 >>> df["身長"].map(lambda x: x if x > 150 else 150) 0 150.0 1 163.5 2 159.8 3 155.1 4 163.3 5 158.7 6 172.0 7 161.2 8 153.9 9 161.6 Name: 身長, dtype: float64 データフレーム全体について要素ごとに処理したい場合は、df.applymap() を用いる。
>>> df.applymap(lambda x: round(x))
身長 体重 BMI
0 148 42 19
1 164 60 22
2 160 47 18
3 155 53 22
4 163 48 18
5 159 60 24
6 172 58 20
7 161 49 19
8 154 47 20
9 162 44 17
結合データフレームを結合する場合を考える。以下の 2 つのデータフレーム df, df2 があったとする。
>>> df = pd.DataFrame()
>>> df["身長"] = [147.9, 163.5, 159.8, 155.1, 163.3]
>>> df["体重"] = [41.7, 60.2, 47.0, 53.2, 48.3]
>>> df
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
>>> df2 = pd.DataFrame()
>>> df2["身長"] = [158.7, 172.0, 161.2, 153.9, 161.6]
>>> df2["体重"] = [59.7, 58.5, 49.0, 46.7, 44.5]
>>> df2
身長 体重
0 158.7 59.7
1 172.0 58.5
2 161.2 49.0
3 153.9 46.7
4 161.6 44.5
これを結合するには、pd.concat() を用いる。
>>> df3 = pd.concat([df, df2])
>>> df3
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
0 158.7 59.7
1 172.0 58.5
2 161.2 49.0
3 153.9 46.7
4 161.6 44.5
これだと元のインデックスが保持される。改めてインデックスを振り直す場合は、オプション "ignore_index=True" を指定して結合する。
>>> df3 = pd.concat([df, df2], ignore_index=True)
>>> df3
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
5 158.7 59.7
6 172.0 58.5
7 161.2 49.0
8 153.9 46.7
9 161.6 44.5
重複削除重複したデータを削除するには、drop_duplicates() を用いる。上の結合の例で示したデータで、次のようにあえて重複したデータを作る。
>>> df3 = pd.concat([df, df, df2], ignore_index=True)
>>> df3
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
5 147.9 41.7
6 163.5 60.2
7 159.8 47.0
8 155.1 53.2
9 163.3 48.3
10 158.7 59.7
11 172.0 58.5
12 161.2 49.0
13 153.9 46.7
14 161.6 44.5
重複を削除すると次のようになる。
>>> df3.drop_duplicates()
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
10 158.7 59.7
11 172.0 58.5
12 161.2 49.0
13 153.9 46.7
14 161.6 44.5
上の場合、重複した分の最初に出てきたデータを採用している。最後に出てきたデータを採用したい場合は、次のようにする。
>>> df3.drop_duplicates(keep="last")
身長 体重
5 147.9 41.7
6 163.5 60.2
7 159.8 47.0
8 155.1 53.2
9 163.3 48.3
10 158.7 59.7
11 172.0 58.5
12 161.2 49.0
13 153.9 46.7
14 161.6 44.5
ある列についてだけ重複削除を行うには、オプション subset で列を指定する。 >>> df3.drop_duplicates(subset="身長", keep="last") インデックスを振り直すには、reset_index() を用いる。
>>> df3.drop_duplicates().reset_index(drop=True)
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
5 158.7 59.7
6 172.0 58.5
7 161.2 49.0
8 153.9 46.7
9 161.6 44.5
並び替え
>>> df.sort_values(by="身長").reset_index(drop=True)
身長 体重
0 147.9 41.7
1 153.9 46.7
2 155.1 53.2
3 158.7 59.7
4 159.8 47.0
5 161.2 49.0
6 161.6 44.5
7 163.3 48.3
8 163.5 60.2
9 172.0 58.5
書き出すCSV として書き出すには次のようにする。
df.to_csv("data.csv", index=False)
index オプションに False を指定しておかないと、インデックスも出力される。 CSV を読み込む
df = pd.read_csv("data.csv")
デフォルトではヘッダーが想定される。ヘッダーが存在しないデータを読み込む場合は、次のようにする。
df = pd.read_csv("data.csv", header=None)
この場合、ラベルとして数字が割り当てられる。ラベルを指定したい場合は、次のようにする。
df = pd.read_csv("data.csv", names=("A", "B", "C"))
ヘッダーが存在するデータのラベルを書き換えるには、次のようにする。
df = pd.read_csv("data.csv", names=("A", "B", "C"), header=0)
あとからラベルを変えることもできる。
df2 = df.rename({"A": "a", "B": "b", "C": "c"})
列の 1 つをインデックスに指定したい場合は、index_col で指定する。
df = pd.read_csv("data.csv", index_col=0)
Excel を読み込む
df = pd.read_excel("data.xlsx", sheet_name="Sheet1", header=None)
欠損値の処理
>>> df = pd.DataFrame()
>>> df["身長"] = [147.9, 163.5, 159.8, 155.1, 163.3, 158.7, 172.0, 161.2, 153.9, 161.6]
>>> df["体重"] = [41.7, 60.2, 47.0, 53.2, 48.3, 59.7, 58.5, 49.0, np.nan, 44.5]
>>> df
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
5 158.7 59.7
6 172.0 58.5
7 161.2 49.0
8 153.9 NaN
9 161.6 44.5
単純に削除する
>>> df.dropna()
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
5 158.7 59.7
6 172.0 58.5
7 161.2 49.0
9 161.6 44.5
ある値で埋める
>>> df.fillna(0)
身長 体重
0 147.9 41.7
1 163.5 60.2
2 159.8 47.0
3 155.1 53.2
4 163.3 48.3
5 158.7 59.7
6 172.0 58.5
7 161.2 49.0
8 153.9 0.0
9 161.6 44.5
補間するたとえば、身長順に並べてから補間する。
>>> df.sort_values(by="身長")
身長 体重
0 147.9 41.7
8 153.9 NaN
3 155.1 53.2
5 158.7 59.7
2 159.8 47.0
7 161.2 49.0
9 161.6 44.5
4 163.3 48.3
1 163.5 60.2
6 172.0 58.5
線形補間
>>> df.sort_values(by="身長").interpolate()
身長 体重
0 147.9 41.70
8 153.9 47.45
3 155.1 53.20
5 158.7 59.70
2 159.8 47.00
7 161.2 49.00
9 161.6 44.50
4 163.3 48.30
1 163.5 60.20
6 172.0 58.50
前の値で埋める
>>> df.sort_values(by="身長").interpolate(method="ffill")
身長 体重
0 147.9 41.7
8 153.9 41.7
3 155.1 53.2
5 158.7 59.7
2 159.8 47.0
7 161.2 49.0
9 161.6 44.5
4 163.3 48.3
1 163.5 60.2
6 172.0 58.5
後ろの値で埋める
>>> df.sort_values(by="身長").interpolate(method="bfill")
身長 体重
0 147.9 41.7
8 153.9 53.2
3 155.1 53.2
5 158.7 59.7
2 159.8 47.0
7 161.2 49.0
9 161.6 44.5
4 163.3 48.3
1 163.5 60.2
6 172.0 58.5
日付の datetime への変換df = pd.DataFrame() df["時間"] = ["2021-1-1 01:00:00", "2021-2-2 02:00:00", "2021-3-3 03:00:00"] dt = pd.to_datetime(df["時間"]) 時間による抽出
from datetime import datetime
from dateutil.relativedelta import relativedelta
dt = pd.to_datetime(df["時間"])
dt0 = datetime.strptime("202201", "%Y%m")
dt1 = datetime.strptime("202207", "%Y%m")
dt1 += relativedelta(months=1)
df1 = df[(dt0 < dt) & (dt < dt1)]
| |
| PENGUINITIS | |