1
3

More than 1 year has passed since last update.

pandasでデータ分析する時によく使う手法覚書き(初学者用)

Last updated at Posted at 2020-04-29

#はじめに
pandasでデータ分析する時によく使う手法をまとめました。随時、加筆修正していきます。

#1.DataFrameの作成

#DataFrameを作成し、リストを格納
pd_sample = pd.DataFrame(リスト)

#DataFrameを作成し、辞書で複数のリストを格納
pd_sample = pd.DataFrame({"列A":リストA, "列B":リストB})

#空のDataFrameを作成し、後続処理で別のDataFrameを結合
pd_sampleA = pd.DataFrame()
pd_sampleA = pd.concat([pd_sampleA, pd_sampleB])

#列の追加
B = {a:b for a in A for b in B if x[a,b].value() == 1}
pd_sample['列B'] = pd_sample['列A'].map(B)

#2.データの結合(ユニオン)

#pandas.concat()関数
pd_sampleAll = pd.concat([pd_sampleA, pd_sampleB], ignore_index=True)

pd_sampleA

列A  列B  列C 
0 a b c

pd_sampleB

列C  列D 
0 y z

pd_sampleAll = pd.concat([pd_sampleA, pd_sampleB], ignore_index=True)

列A  列B  列C  列D 
0 a b c NaN
1 NaN NaN y z

#3.データの結合(ジョイン)

#pandas.merge()関数
pd_sampleAll = pd.merge(pd_sampleA, pd_sampleB, on="列ラベル", how="left")

#pandas.DataFrameのmerge()メソッド
pd_sampleAll = pd_sampleA.merge(pd_sampleB, on="列ラベル", how="left")

#複数の列をキーに結合
pd_sampleAll = pd.merge(pd_sampleA, pd_sampleB, on=["列A", "列B"], how="left")

#キーの列名が異なる場合の結合
pd_sampleAll = pd.merge(pd_sampleA, pd_sampleB, left_on="列A", right_on="列AAA", how="left")

pd_sampleA

列A  列B  列C 
0 a b c
1 aaa bbb ccc

pd_sampleB

列A  列D 
0 a x
1 aa y

pd_sampleAll = pd.merge(pd_sampleA, pd_sampleB, on="列A", how="left")

列A  列B  列C  列D 
0 a b c x
1 aaa bbb ccc NaN

#4.データの抽出

#列名指定でpandas.DataFrameを抽出
pd_sampleA = pd_sampleAll[["列A", "列B"]]

#pandas.loc()関数で行ラベルと列ラベルの位置を指定して抽出
#単一行取り出す時はSeries型、複数行取り出した時はDataFrame型が返る
#行ラベルには行名のほかにboolean型を返す条件式を指定することもできる
#複数列、行をスライスすることもできる
pd_sampleA = pd_sampleAll["列ラベル"].loc["行ラベル"]
pd_sampleA = pd_sampleAll.loc["行ラベル", "列ラベル"]
pd_sampleA = pd_sampleAll.loc[pd_sampleAll["列ラベル"]!=9999]

#pandas.iloc()関数で行番号と列番号の位置を指定して抽出
#単一行取り出す時はSeries型、複数行取り出した時はDataFrame型が返る
#複数列、行をスライスすることもできる
pd_sampleA = pd_sampleAll.iloc["行番号", "列番号"]

#pandas.isin()メソッドで引数に渡したリストの要素と一致する行を抽出
pd_sampleA = pd_sampleAll["列ラベル"].isin([ "A", "B"])

pd_sampleAll

列A  列B  列C  列D 
0 a b c d
1 aaa bbb ccc ddd

pd_sampleA = pd_sampleAll.loc[pd_sampleAll["列A"]=="aaa", ["列B", "列C"]]

列B  列C 
1 bbb ccc

#5.欠損値の確認

#pandas.Series.isnull()メソッドで欠損値の存在する行を取得
pd_sample = pd_sample["列A"].isnull()

#isnull()メソッドにany()を用いて欠損値を含む列の有無を確認
pd_sample["列A"].isnull().any(axis=0)

#isnull()メソッドにsum()を用いて欠損値を含む列の数を確認
pd_sample["列A"].isnull().sum()

#pandas.DataFrame.dropna()メソッドで特定の列が欠損している行を削除
pd_sample = pd_sample.dropna(subset=["列A"])

#pandas.DataFrame.fillna()メソッドで欠損値を任意の値に置換
pd_sample = pd_sample.fillna({"列A": "AAA", "列B": "BBB"}))
pd_sample["age"] = pd_sample["age"].fillna(pd_sample["age"].mean())

#6.日付変換

#pandas.to_datetime()関数で文字列(object型)をdatetime型に変換
import datetime
pd_sample["日付"] = pd.to_datetime(pd_sample["日付"])

#datetime型に対してdtアクセサを用いて年月日、時分秒、曜日などを取得
pd_sample[""] = pd_sample["日付"].dt.month

#datetime型のstrftime()メソッドで日時を任意の書式の文字列に変換
pd_sample["年月"] = pd_sample["日付"].dt.strftime("%Y%m")

#datetime型のtimedeltaオブジェクトのtotal_seconds()メソッドを用いて2つの時間の差を取得
pd_sample["経過時間"] = (pd_sample["日付1"] - pd_sample["日付2"]).map(lambda x: x.total_seconds()/3600)
#applyを使った場合
#def calc_delta(t):
#    t1, t2 = t
#    delta = t2 - t1
#    return delta.total_seconds()/3600
#pd_sample["経過時間"] = pd_sample[["日付1"], ["日付2"]].apply(calc_delta, axis=1)

#datetime型のtimedeltaオブジェクトの days()メソッドを用いて2つの日付の日数差を取得
pd_sample["経過日数"] = (pd_sample["日付1"] - pd_sample["日付2"]).map(labda x: x.days)

#dateutilモジュールのrelativedeltaオブジェクトを用いて2つの日付の月数差を取得
#戻り値に2つの日付の差が(years=+1, months=+10, days=+8)という形で格納される
from dateutil.relativedelta import relativedelta
delta = relativedelta(pd_sample["日付1"], pd_sample["日付2"])
pd_sample["経過月数"] = delta.years*12 + delta.months

#dateutilモジュールのrelativedeltaオブジェクトを用いて任意の時間差のデータを取得
pd_sample["1ヶ月前"] = pd_sample['日付'].map(lambda x: x - relativedelta(months=1))

#7.集計

#DataFrame型同士の演算
pd_ratio = (pd_sampleA / pd_sampleAll) * 100

#pandas.DataFrame.groupby()関数でまとめたい列と集計方法を指定して集計
#デフォルトではグループラベルがindexになるため、そうしたくない場合はas_index=Falseを指定する。
pd_count = pd_sample.groupby("まとめたい列").count()
pd_sum = pd_sample.groupby(["まとめたい列1", "まとめたい列2"], as_index=False).sum()[["合計したい列1", "合計したい列2"]]

#pandas.DataFrame.resample()メソッドで時系列データを集約
#引数にD(日)、W(週)などの頻度を指定し、sum()、count()、mean()などのメソッドを呼び出すことで集約した値を算出
pd_resampled = pd_sample.resample('D').sum()

#pandas.unique()関数で重複を除外したユニークなデータ件数を取得
pd_unique = pd.unique(pd_sample["列A"])
pd_unique = pd_sample["列A"].unique()

#8.その他の手法

#pandas.agg()関数で特定の列の平均値、中央値、最大値、最小値を出力
pd_sample = pd_sample.agg(["mean", "median", "max", "min"])["集計したい列"]

#pandas.DataFrame.describe()関数でデータ件数、平均値、標準偏差、最小値、四分位数、中央値、最大値を出力
#デフォルトでは数値(整数型int、浮動小数点型float)の列のみが選択される
pd_sample.describe()

#DateFrame型に対してstrアクセサを用いて文字列を操作
pd_sample["列A"] = pd_sample["列A"].str.replace(" ", "")

#pandas.DataFrameのwhere()メソッドで条件に応じて値を代入する
#Trueの場合は呼び出し元のオブジェクト、Falseの場合は第二引数が適用される
pd_sample["列A"] = pd_sample["列A"].where(pd_sample["列B"]>3, 0)

#pandas.DataFrameのmask()メソッドで条件に応じて値を代入する
#Trueの場合は第二引数、Falseの場合は呼び出し元のオブジェクトが適用される
pd_sample["列A"] = pd_sample["列A"].mask(pd_sample["列B"]>3, 0)

#DataFrame型をリスト型に変換
pd_sample_columns = pd_sample.columns.tolist()

#pivotをmeltする
pd_sample_vertical = pd_sample.melt(id_vars=['列A'], value_vars=['列B', '列C', '列D'], var_name='列BCD', value_name='列BCD値')
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3