「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>Python]] > [[Pythonセカンド・ステップ]] --[[NumPy]] --Pandas --[[Matplotlib]] *目次 [#wbc79557] #contents *概要 [#head536a] Pandas(パンダス)は数表の形式で保存されたデータを効率的に処理する機能を収録したライブラリ -[[Python]]に[[データ解析]]を支援する機能を提供する、 -BSDライセンスのもとで提供されているOSSライブラリ。 -特に、[[DML的な処理>高度午前 - 技術要素 - データベース#bffc1731]]で、 --数表および --時系列データを >操作するためのデータ構造と演算を提供~ ([[Python]]から簡単に利用できるSQLの代替) -[[ビッグデータ]]の対応は、~ ≒ な[[Spark SQLとDataFrame API>Spark SQL]]で。 *詳細 [#s10f848c] **準備 [#e255ef18] ***インストール [#cc3e74f6] >pip install pandas ***インポート [#ib05b2df] >>>import pandas as pd **型 [#b7c4273f] ***[[Series>#o1bd0dc9]] [#l7f71574] ***[[DataFrame>#w1afd0f6]] [#r59db362] *ファースト・ステップ(Series) [#o1bd0dc9] Series型は、一次元の配列のオブジェクト **生成 [#g1f81a8e] ***配列から [#l07b0e97] >>>pd.Series([3,7,10,13]) 0 3 1 7 2 10 3 13 dtype: int64 ***NumPyから [#h4b41273] NumPyの配列から >>>numpy_array = np.array([3,7,10,13]) >>>pd.Series(numpy_array) 0 3 1 7 2 10 3 13 dtype: int64 ***コピー [#weda88b2] >>>ss=pd.Series([3,7,10,13]) -以下は参照渡し >>>ss2=ss -コピーする場合は以下 >>>ss2=ss.copy() **アクセス [#n210fc00] >>>x=pd.Series([3,7,10,13]) ***インデックス [#w999ebe8] >>>x[1] 7 ***抽出 [#ec5f5fbc] -スライシング >>>x[1:3] -配列でインデックスを指定~ 以下ではnp.arrayを使っているが、普通の配列でも指定可能。 >>>x[np.array([1,2])] -比較演算 --5より大きい値を調査。 >>>x>=5 0 False 1 True 2 True 3 True dtype: bool --5より大きい値を抽出。 >>>x[x>=5] 1 7 2 10 3 13 dtype: int64 ※ インデックスにtrue, falseのSeriesが指定され抽出される。 ***配列 [#w5a4f2ef] 配列の取り出し >>>x.values array([ 3, 7, 10, 13], dtype=int64) *セカンド・ステップ(DataFrame1) [#w1afd0f6] DataFrame型は、テーブル形式のデータ構造 **生成 [#w8a12f28] ***辞書型から [#cb838988] >>> pd.DataFrame({ ... 'xxx': ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], # 長さ: 6 ... 'yyy': [20, 34, 50, 12, 62, 22], # 長さ: 6 ... 'zzz':['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF'] # 長さ: 6 ... }) xxx yyy zzz 0 aaa 20 AAA 1 bbb 34 BBB 2 ccc 50 CCC 3 ddd 12 DDD 4 eee 62 EEE 5 fff 22 FFF ***NumPyから [#k5c00526] NumPyの行列(2次配列)から → [[NP ⇔ DF型変換>#e3138f86]] ***CSVから [#g4ce83ce] >>>df = pd.read_csv('hoge.csv') ***Excelから [#x3aa6e93] -openpyxlが必要 >!pip install openpyxl -Excel読込 >>>df = pd.read_excel('hoge.xlsx') ***コピー [#pd42bb72] >>> df=pd.DataFrame({ ... 'xxx': ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], # 長さ: 6 ... 'yyy': [20, 34, 50, 12, 62, 22], # 長さ: 6 ... 'zzz':['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF'] # 長さ: 6 ... }) -以下は参照渡し >>>df2=df -コピーする場合は以下 >>>df2=df.copy() ***確認 [#s7ec1c19] → [[先頭・後尾>#t4526035]] **アクセス [#mea8020b] >>> df=pd.DataFrame({ ... 'xxx': ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], # 長さ: 6 ... 'yyy': [20, 34, 50, 12, 62, 22], # 長さ: 6 ... 'zzz':['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF'] # 長さ: 6 ... }) >>> df xxx yyy zzz 0 aaa 20 AAA 1 bbb 34 BBB 2 ccc 50 CCC 3 ddd 12 DDD 4 eee 62 EEE 5 fff 22 FFF ***先頭・後尾 [#t4526035] -先頭 --先頭5行を出力(既定値 >>>df.head() --先頭2行を出力(明示 >>>df.head(2) -後尾 --後尾5行を出力(既定値 >>>df.tail() --先頭2行を出力(明示 >>>df.tail(2) ***インデックス [#cda2ba3a] -行指定 >>>df.iloc[1] -列指定~ NumPyと同様にスライシングが可能 >>>df.iloc[:,1] -行列指定 --行列番号 >>>df.iloc[1,0] 'bbb' --行番号・列名 >df.loc[1,'xxx'] 'bbb' ***抽出 [#w2833341] -スライシング --行 >>>df.iloc[2:4] --列 >>>df.iloc[:,1] -配列でインデックスを指定~ 以下ではnp.arrayを使っているが、普通の配列でも指定可能。 >>>x[np.array([1,2])] --行インデックス >>>df.iloc[np.array([2,3])] --行&列インデックス >>>df.iloc[np.array([2,3]), np.array([1,2])] -比較演算 --30より大きいyyy列の値を調査。 >>>df.yyy >= 30 --30より大きいyyy列の値を抽出。 >>>df[df.yyy >= 30] >※ インデックスにname=yyyのtrue, falseのSeriesが指定され抽出される。 ***行列 [#o648963b] m行n列の二次元行列が取得できる。 >>>df.values ***行指定(≒ 選択) [#we3b0f09] -1行指定する場合は[[Series>#o1bd0dc9]]~ >>>df.iloc[2] xxx ccc yyy 50 zzz CCC Name: 2, dtype: object -複数行指定(行を配列で指定)する場合は[[DataFrame>#w1afd0f6]] >>>df.iloc[[2]] xxx yyy zzz 2 ccc 50 CCC ***列指定(≒ 射影) [#i27f3e18] -1列指定する場合は[[Series>#o1bd0dc9]]~ 行はスライシングで全行指定。 >>>df.loc[:,'yyy'] 0 20 1 34 2 50 3 12 4 62 5 22 Name: yyy, dtype: int64 -複数列指定(列を配列で指定)する場合は[[DataFrame>#w1afd0f6]] --行はスライシングで全行指定 >>>df.loc[:,['yyy']] yyy 0 20 1 34 2 50 3 12 4 62 5 22 --列名のみ指定しても結果は同じ >>>df[['yyy']] yyy 0 20 1 34 2 50 3 12 4 62 5 22 **編集 [#n20b174a] -行編集: axis=0 -列編集: axis=1 ***行追加 [#m24adbcb] -concatを使った例 >>>row=pd.DataFrame({ 'xxx': 'ggg', 'yyy': [45], 'zzz': 'GGG'}) >>> df=pd.concat([df,row],axis=0) >>> df xxx yyy zzz 0 aaa 20 AAA 1 bbb 34 BBB 2 ccc 50 CCC 3 ddd 12 DDD 4 eee 62 EEE 5 fff 22 FFF 0 ggg 45 GGG -インデックス再設定 >>>df.index=np.arange(len(df)) >>> df xxx yyy zzz 0 aaa 20 AAA 1 bbb 34 BBB 2 ccc 50 CCC 3 ddd 12 DDD 4 eee 62 EEE 5 fff 22 FFF 6 ggg 45 GGG ***列追加 [#if0f38cd] -簡単な例 >>>df['XXX']=['X1','X2','X3','X4','X5','X6'] >>>df xxx yyy zzz XXX 0 aaa 20 AAA X1 1 bbb 34 BBB X2 2 ccc 50 CCC X3 3 ddd 12 DDD X4 4 eee 62 EEE X5 5 fff 22 FFF X6 -concatを使った例 >>>col=pd.DataFrame({'YYY':['Y1','Y2','Y3','Y4','Y5','Y6']}) >>>df=pd.concat([df,col],axis=1) >>>df xxx yyy zzz XXX YYY 0 aaa 20 AAA X1 Y1 1 bbb 34 BBB X2 Y2 2 ccc 50 CCC X3 Y3 3 ddd 12 DDD X4 Y4 4 eee 62 EEE X5 Y5 5 fff 22 FFF X6 Y6 ***行削除 [#x5a26902] >>>df=df.drop(2,axis=0) >>> df xxx yyy zzz XXX YYY 0 aaa 20 AAA X1 Y1 1 bbb 34 BBB X2 Y2 3 ddd 12 DDD X4 Y4 4 eee 62 EEE X5 Y5 5 fff 22 FFF X6 Y6 ***列削除 [#v071a34e] >>>df=df.drop('yyy',axis=1) >>>df xxx zzz XXX YYY 0 aaa AAA X1 Y1 1 bbb BBB X2 Y2 3 ddd DDD X4 Y4 4 eee EEE X5 Y5 5 fff FFF X6 Y6 ***列名・行名の変更 [#e418e2c0] -列名の変更 >>>df.columns=['AAA','BBB','CCC','DDD'] >>>df AAA BBB CCC DDD 0 aaa AAA X1 Y1 1 bbb BBB X2 Y2 3 ddd DDD X4 Y4 4 eee EEE X5 Y5 5 fff FFF X6 Y6 -列名・行名の変更 >>>df=df.rename(columns={'DDD': 'XXX'}, index={5: 'hoge'}) >>>df AAA BBB CCC XXX 0 aaa AAA X1 Y1 1 bbb BBB X2 Y2 3 ddd DDD X4 Y4 4 eee EEE X5 Y5 hoge fff FFF X6 Y6 ***列値の一括変更 [#v08d90cf] 列値を%に単位変更する(100倍する)などの一括変更。 >>>pd.DataFrame({ ... 'xxx': ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], # 長さ: 6 ... 'yyy': [20, 34, 50, 12, 62, 22], # 長さ: 6 ... 'zzz':['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF'] # 長さ: 6 ... }) >>>df.iloc[:,1:2] = df.iloc[:,1:2] * 100 xxx yyy zzz 0 aaa 2000 AAA 1 bbb 3400 BBB 2 ccc 5000 CCC 3 ddd 1200 DDD 4 eee 6200 EEE 5 fff 2200 FFF 6 ggg 4500 GGG ***行列の入替(転置) [#j6e397c8] df=df.transpose() ***inplace=True [#n2c9a46b] inplace=Trueを設定すると、元を変更する。 >>>df.drop('yyy',axis=1,inplace=True) >>>df ※ drop、rename、dropnaなどメソッドに指定できる。 *サード・ステップ(DataFrame2) [#zbf6f336] **型変換 [#vf41a602] ***SS ⇔ DF型変換 [#e99f7559] -SS → DF~ [[アクセスの所>#mea8020b]]で幾らか説明済み。 -DF → SS >>>df = pd.DataFrame(pd.Series([3,7,10,13])) >>>df ***NP ⇔ DF型変換 [#e3138f86] -NP → DF --NP初期化 >>>np_arr=np.array([[1,2,3],[4,5,6]]) --要列名付与 >>>df=pd.DataFrame(np_arr,columns=['a','b','c']) -DF → NP --np.arrayメソッド >>>np_arr=np.array(df) --df.valuesプロパティ >>>np_arr=df.values **集計操作 [#a153932e] >>>df=pd.DataFrame({ ... '0': ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'], # 長さ: 10 ... '1': ['10', '11', '12', '13', '14', '15', '16', '17', '18', '19'], # 長さ: 10 ... '2': ['20', '21', '22', '23', '24', '25', '26', '27', '28', '29'] # 長さ: 10 }) >>>df=df.astype('int') ***行方向に集系 [#c835adf2] -m~n列を行集計 >>>ss_sum = df.iloc[:,[m:n]].sum(axis=0) >>>df_sum = pd.DataFrame(ss_sum) >>>df_sum = df_sum.rename(columns={0: 'sum'}) -集計列として追加 >>>df=pd.concat([df,df_sum.transpose()],axis=0) >>>df ***列方向に集計 [#ze46f902] -m~n列を列集計 >>>ss_sum = df.iloc[:,[1,2]].sum(axis=1) >>>df_sum = pd.DataFrame(ss_sum) >>>df_sum = df_sum.rename(columns={0: 'sum'}) -集計行として追加 >>>df=pd.concat([df,df_sum],axis=1) *4thステップ(DataFrame3) [#ff7127f8] **補完処理 [#y7d7000b] ***基本的な補完処理 [#a2f4b5de] は[[コチラ>データマイニング(DM)- Python#v8a8aa18]] ***Xを含む要素を一括置換 [#eca1dde4] -ハードコード -Xを含む要素をXで一括置換 >>>df['列名'] = df['列名'].str.replace('.*(置換前).*', '置換後', regex=True) -パターンを抽出して処理 -要素を要素中の[,]と[.]で囲まれた文字列で一括置換 list_col1 = [i.split(",")[1].split(".")[0].strip() for i in df["col1"]] df["col1"] = pd.Series(list_col1) nparr_col1 = df["col1"].unique() for cell in nparr_col1: df['col1'] = df['col1'].str.replace('.*({0}\.).*'.format(cell), cell, regex=True) ***グループの平均値で補完 [#y99d47fd] >>>df['補完対象列名'] = df.groupby('グループ化列名')['補完対象列名'].transform(lambda d: d.fillna(d.mean())) **特徴量の選択とエンジニアリング [#e1fa02e4] [[特徴量の選択とエンジニアリングとは?>機械学習(machine learning)#s2dc3704]] ***基本統計量 [#e0c771c0] -通常 >>>df.describe() -小数点以下、切捨 >>>df.describe().astype(int) ***相関係数行列 [#w67534e5] 説明変数の表(DataFrame)から相関係数行列を生成。 >>>df.corr() ※ ヒートマップで可視化する方法は[[コチラ>Matplotlib#eddbc4be]]。 ***散布図行列 [#g12330a4] 説明変数の表(DataFrame)を[[散布図行列>Matplotlib#a41dcf52]]として可視化。 ***DataFrameで標準化 [#i128d437] >>>X = (df.iloc[:, m:n] - df.iloc[:, m:n].mean()) / df.iloc[:, m:n].std() >>>X.describe() ※ 平均が ≒ 0、標準偏差 ≒ 1 になればOK。 ***One-Hotエンコーディング [#f4de2b7c] -カテゴリを列に展開(0・1化)など。 pd.get_dummies(df['カテゴリ列の列名']) -展開した列を表に追加する流れ df_dummy = pd.get_dummies(df['カテゴリ列の列名']) df = pd.concat([df, df_dummy], axis=1) df.head() *参考 [#hc6adae8] -pandas - Wikipedia~ https://ja.wikipedia.org/wiki/Pandas -pandas - Python Data Analysis Library~ https://pandas.pydata.org/ --pandas documentation — pandas 1.4.3 documentation~ https://pandas.pydata.org/docs/ -Qiita --データ分析で頻出のPandas基本操作~ https://qiita.com/ysdyt/items/9ccca82fc5b504e7913a --SQLでやるこの操作ってpandas.DataFrameではどうやるの!~ https://qiita.com/HiromuMasuda0228/items/d62a47cf9b83481929a7 --SQL と Pandas の対応表~ https://qiita.com/takaiyuk/items/5232442eaeb01299b265 -DxCommon/PandasTraining.ipynb at develop · OpenTouryoProject/DxCommon · GitHub~ https://github.com/OpenTouryoProject/DxCommon/blob/develop/Notebook/Jupyter/path/PandasTraining.ipynb