データ型
サンプルデータ
df = pd.DataFrame([
{"column1": 1, "column2": 2},
{"column1": 3, "column2": 4},
])
型を確認する
column1 int64
column2 int64
dtype: object
結果はSeriesとなる。
型を変換する(一括)
_df = df.astype("str")
_df.dtypes
column1 object
column2 object
dtype: object
型を変換する(個別)
_df = df.astype({"column1": str, "column2": float})
_df.dtypes
column1 object
column2 float64
dtype: object
なお、文字列で指定しても解釈してくれる
_df = df.astype({"column1": "str", "column2": "float"})
_df.dtypes
NumPyの型も解釈可能。
import numpy as np
_df = df.astype({"column1": np.int32, "column2": np.float32})
_df.dtypespython
置換
df = pd.DataFrame([
{"column1": 1, "column2": 2},
{"column1": 3, "column2": 4},
])
辞書型で置換可能。
df.replace({1: "A", 2: "B", 3: "C", 4: "D"})
column1 column2
0 A B
1 C D
Seriesに対しても可能。
df["column1"].replace({1: "A", 2: "B", 3: "C", 4: "D"})
カラム名を置き換える場合は、キーワード引数でcolumnsを使用する。
df.rename(columns={"column1": "aaa"})
aaa column2
0 A B
1 C D
抽出(query)
user_idが重複しているレコードを抽出する例。
","で結合して、queryのinで抽出する。
user_id_str = ",".join(df[df.duplicated(['user_id'], keep='last')]['user_id'].astype(str))
df.query(f'user_id in ({user_id_str})')
カラムの並び替え
columns = df.columns.tolist()
columns = columns[-1:] + columns[:-1] # reorder example
df = df[columns] # do reorder!!
group集計して統計量を計算する。
# user_idで集計して、年齢の統計量を計算する例
age_stats_df = rowdata_df.groupby("user_id")["age"].agg(["mean"])
# 上記では、goupbyしたカラムがindexになってしまうので、嫌な場合はreset_index()する。
age_stats_df = rowdata_df.groupby("user_id")["age"].agg(["mean"]).reset_index()
# 自作関数を作る
def percentile(n):
def percentile_(x):
return np.percentile(x, n)
percentile_.__name__ = 'percentile_%s' % n
return percentile_
age_stats_df = rowdata_df.groupby("user_id")["age"].agg([percentile(80)]).reset_index()
時系列データを集計する場合
時刻情報がある場合、その列をindexにすることで、resampleが使えて集計できる。
購入量の時系列データのイメージで以下は'M'で月ごとの結果を集計する例。
timedomain_df.set_index("recorded_at", drop=True).sort_index().loc[:,["purchase_count"]].resample('M').agg(['sum', 'mean', "max"])
行を挿入する。
import pandas as pd
df = pd.DataFrame([], columns=['A', 'B', 'C'])
row_data = pd.Series(['0', '1', '2'], index=df.columns)
df = df.append(row_data, ignore_index=True)
df = df.append(row_data, ignore_index=True)
df = df.append({'A': 0, 'B': 1, 'C': 2}, ignore_index=True))
df = df.append({'A': 0, 'B': 1, 'C': 2}, ignore_index=True))
列毎の欠損数を求める。
applyの使用法まとめ
query記法を使った条件抽出
df_receipt.query('`sales ymd` == 20181103')
placeholderは、f-stringでもかけるが、@の方が汎用性が高い。
user_id = "1000"
df.query('user_id == @user_id')
時刻系のデータをquery記法で処理
timedelta_val = timedelta(days=1)
df.query('yyyymmdd_diff > @timedelta_val')
date_val = datetime(2022,6,15)
df.query('yyyymmdd > @date_val')
たとえばtimedeltaを数値として扱いたい場合などは、datetime.timedelta
と併せて使う。
from datetime import timedelta
df['yyyymmdd_diff'] / timedelta(days=1)
read_csvで型指定
read_dtype = {
'yyyymmdd': 'str'
, 'column1': 'int'
, 'column2': 'float'
}
df = pd.read_csv("sample.csv", dtype=read_dtype)
df['yyyymmdd'] = pd.to_datetime(df['yyyymmdd'])
抽出して新しい列を作る
df = pd.DataFrame([
['aaa','aaa.pptx'],
['bbb','bbb.pptx'],
['ccc','ccc.pptx'],
], columns=['name', 'file'])
df['file'].str.extract("(.*)\.pptx")
rank: 順位を付ける
# 値が高い順(降順)、同値は小さい順位(上位)に合わせる
df['column_name'].rank(ascending=False, method='min')
unique: 出現する種類を把握する
df['column_name'].unique()
value_counts: 内訳を知る
df.value_counts('column_name')
その他のオプション
sort_values: 並べ替え
# 値が高い順(降順)
df.sort_values('column_name', ascending=False)
isnull(): 欠損値かどうかを調べる
df.isnull()
df['column_name'].isnull()
dropna(): 欠損値を削除する
どこかの列に基づきたい場合は、subsetで指定する。
df.dropna(subset=['column1'])
欠損値を列毎に修正する
df.loc[rank_df.query('column1 != column1').index,'column1'] = 0
locとilocの違い
locはindex(いわゆるDataFrameのIndex), column名でアクセスする。
ilocは本当のindex番号で縦横ともにアクセスする。
なのでilocを使えば、reset_index(drop=True)しなくてもアクセスしたいものにアクセスできるかもしれない
merge: joinしたいとき
df\
.merge(df2[['column1', 'column2']], how='inner', on='column1')\
.merge(df3[['column1', 'column3']], how='left', on='column1')\
複数をキーにjoinしたい場合は、on=['column1', 'column2']
とすればOK。
join後に重複するカラム名は、suffixes=['_left', '_right']
と指定すれば末尾に目印をつけられる。
groupby + agg: 集約したいとき
def my_func(x):
return np.std(x)
stats_df = df.groupby('column1').agg(
new_column1 = ('org_column2', 'mean'),
new_column2 = ('org_column2', 'std'),
new_column3 = ('org_column3', my_func),
).reset_index()
grouby + transform: 集約したものを各行に割り当てる
集約となるmeanやsumは、transformにより行を元のDFに拡張することができる。
df['column2_mean'] = df.groupby(['column1'])['column2'].transform("mean")
groupby + shift, rank: 集約でない場合のgroupby + 各行割り当て
transformとかも選択肢にでてくるけど、使わなくても行ける。
集約ではなく、shiftやrankなどの場合はこの方法が使える。
df.groupby('column1')['column2'].shift(-1)
idxmin: 最小値の時のPandas Indexを得る
df['column1'].idxmin()
drop_duplicates: 重複を削除する
残すものをコントロールするためには、事前にsort_valuesしておく感じの使い方となる。
df.drop_duplicates(subset=['column1', 'column2'], keep='first') # 最初を残す
df.drop_duplicates(subset=['column1', 'column2'], keep='last') # 最後を残す
df.drop_duplicates(subset=['column1', 'column2'], keep=False) # 残さない
duplicated: 重複の判定
df.duplicated(['column1','column2'], keep='last')
df[df.duplicated(['column1','column2'], keep='last')]
より高度な最適化