PandasのDataFrameから特定の要素を抽出する方法はいく通りも方法があって混乱します。
一番ベストなのはloc属性またはiloc属性を使う事です。
DataFrameから特定要素を抽出する手法
pandasをインポートしておきます。
import pandas as pd
辞書から簡単なデータフレームを作成します。
data = {'name':['Nakajima', 'Hanazawa', 'Hama', 'Isono'], 'id':[1, 2, 3, 4], 'age':[48, 30, 28, 51], 'weight':[60, 78, 64, 58], 'height':[168, 173, 162, 172]} data_f1 = pd.DataFrame(data,index=['a', 'b', 'c', 'd']) data_f1
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Nakajima | 1 | 48 | 60 | 168 |
b | Hanazawa | 2 | 30 | 78 | 173 |
c | Hama | 3 | 28 | 64 | 162 |
d | Isono | 4 | 51 | 58 | 172 |
Pandas データから特定の列を抽出
まずは前回説明した内容の復習で辞書風の取り出し方です。
属性風の指定は日本語や特殊記号が混ざる場合はエラーの原因になりますのであまり推奨されません。
辞書風の取り出し方
辞書風の取り出し方は、まず列データを取り出すのが鉄則です。
そして取り出された列はSeries型となるため、さらに特定要素を取り出したい場合はSeriesのインデックスを指定して取り出します。
Series型で取り出す一般的な方法
print(data_f1['name']) print(type(data_f1['name']))
結果
a Nakajima
b Hanazawa
c Hama
d Isono
Name: name, dtype: object
<class ‘pandas.core.series.Series’>
二重のブラケットを付けて要素を取り出す方法
二重にブラケットが付いた指定方法は通常複数の列を指定する場合に使い、列をリストで指定した方法です。
data_f1[[‘name’]]の場合、内部括弧はリスト用であり、外部括弧はインデックス演算子です。
つまり、2つ以上の列を選択する場合は二重括弧を使用する必要があります。
そしてこの方法は、単一の列を指定する場合も使用可能です。
つまり、ブラケットが1つの場合は今まで紹介したようにシリーズを返しますが、二重ブラケットはデータフレームを返します。
単一ブラケットを使った例
data_f1['name']
結果
a Nakajima
b Hanazawa
c Hama
d Isono
Name: name, dtype: object
ダブルのブラケットを使った例
data_f1[['name']]
結果
name | |
---|---|
a | Nakajima |
b | Hanazawa |
c | Hama |
d | Isono |
ダブルのブラケットを使った時の型
print('型の確認:', type(data_f1[['name']]))
結果
型の確認: <class ‘pandas.core.frame.DataFrame’>
ダブルのブラケットを使用した時の行のスライス例
data_f1[['name']][0:3]
結果
name | |
---|---|
a | Nakajima |
ダブルのブラケットを使用した時の行のスライス例
data_f1[['name']][0:1]
結果
name | |
---|---|
a | Nakajima |
複数の列の取り出し例
# 複数列取り出す data_f1[['name', 'age']]
結果
name | age | |
---|---|---|
a | Nakajima | 48 |
b | Hanazawa | 30 |
c | Hama | 28 |
d | Isono | 51 |
複数の列と行を取り出し例
# 複数列取り出す data_f1[['name', 'age']][0:3]
結果
name | age | |
---|---|---|
a | Nakajima | 48 |
b | Hanazawa | 30 |
c | Hama | 28 |
列の値を変更する
列を指定して値を代入すると全てその値になります。
各行に別の値を代入したい場合は、リストで値を渡します。
列を指定しただけで単一の値を代入した例
data_f1['name'] = 'Sazae' data_f1 # 全てSazaeになる
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Sazae | 1 | 48 | 60 | 168 |
b | Sazae | 2 | 30 | 78 | 173 |
c | Sazae | 3 | 28 | 64 | 162 |
d | Sazae | 4 | 51 | 58 | 172 |
名前が全てSazaeになったことに注目です。
一旦データを初期化した上で、今度はname列の0行目を指定して値を代入した例
data_f1['name'][0] = 'Sazae' data_f1
例
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Sazae | 1 | 48 | 60 | 168 |
b | Hanazawa | 2 | 30 | 78 | 173 |
c | Hama | 3 | 28 | 64 | 162 |
d | Isono | 4 | 51 | 58 | 172 |
name列の値を全て別の名前に変更するにはリスト化した値を代入します。
name列の値を全て別名にする例
data_f1['name'] = ['Nakajima','Hanazawa','Hama','Isono'] data_f1 #個別にリストの値が入る
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Nakajima | 1 | 48 | 60 | 168 |
b | Hanazawa | 2 | 30 | 78 | 173 |
c | Hama | 3 | 28 | 64 | 162 |
d | Isono | 4 | 51 | 58 | 172 |
locとiloc
locとilocはNumpyのスライスのようにインデックス演算子[]で行と列をカンマ区切りで指定します。
カンマの前が行指定で後が列指定です。
んー、今度は行ありきなのです。。
- locはラベル名を指定したスライス表記で、終点に指定した端点は含みます
- ilocはNumPyのスライス表記と同様、終点に指定した端点は含まれない
終点の指定がlocとilocで違いますので注意。
簡単なサンプルDataFrameの作成
data = {'name':['Nakajima', 'Hanazawa', 'Hama', 'Isono'], 'id':[1, 2, 3, 4], 'age':[48, 30, 28, 51], 'weight':[60, 78, 64, 58], 'height':[168, 173, 162, 172]} data_f1 = pd.DataFrame(data,index=['a', 'b', 'c', 'd']) data_f1
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Nakajima | 1 | 48 | 60 | 168 |
b | Hanazawa | 2 | 30 | 78 | 173 |
c | Hama | 3 | 28 | 64 | 162 |
d | Isono | 4 | 51 | 58 | 172 |
locで特定行の特定列をスライスする例
# 行番号の範囲は通常のスライスと違うので注意 data_f1.loc['a':'c', 'name']
結果
a Nakajima
b Hanazawa
c Hama
Name: name, dtype: object
# Numpy方式 data_f1.iloc[:3, 0:3]
結果
name | id | age | |
---|---|---|---|
a | Nakajima | 1 | 48 |
b | Hanazawa | 2 | 30 |
c | Hama | 3 | 28 |
DataFrame作成の際に列の順番を変更しておく
DataFrame作成の際に列全体の並び順を変更したい場合は第2引数に `colums=[]` を指定します。
data_f2 = pd.DataFrame(data, columns=['id', 'name', 'age', 'weight', 'height']) data_f2
結果
id | name | age | weight | height | |
---|---|---|---|---|---|
0 | 1 | Nakajima | 48 | 60 | 168 |
1 | 2 | Hanazawa | 30 | 78 | 173 |
2 | 3 | Hama | 28 | 64 | 162 |
3 | 4 | Isono | 51 | 58 | 172 |
Seriesの代入
val = pd.Series([1.0, 1.2, 2.5],index=[0,1,3]) data_f2['eyesight'] = val data_f2
結果
id | name | age | weight | height | eyesight | |
---|---|---|---|---|---|---|
0 | 1 | Nakajima | 48 | 60 | 168 | 1.0 |
1 | 2 | Hanazawa | 30 | 78 | 173 | 1.2 |
2 | 3 | Hama | 28 | 64 | 162 | NaN |
3 | 4 | Isono | 51 | 58 | 172 | 2.5 |
列や行の削除
列や行の削除はPandasのdrop()が使えます。またPythonのdel文で削除することもできます。
drop関数の例
drop関数の削除処理はインプレースではありません。
本当に削除したいときは、inplace=True を追加します。
data_f2.drop(['eyesight'], axis=1)
結果
id | name | age | weight | height | |
---|---|---|---|---|---|
0 | 1 | Nakajima | 48 | 60 | 168 |
1 | 2 | Hanazawa | 30 | 78 | 173 |
2 | 3 | Hama | 28 | 64 | 162 |
3 | 4 | Isono | 51 | 58 | 172 |
data_f2
結果
id | name | age | weight | height | eyesight | |
---|---|---|---|---|---|---|
0 | 1 | Nakajima | 48 | 60 | 168 | 1.0 |
1 | 2 | Hanazawa | 30 | 78 | 173 | 1.2 |
2 | 3 | Hama | 28 | 64 | 162 | NaN |
3 | 4 | Isono | 51 | 58 | 172 | 2.5 |
del文はPythonのリストの要素を削除する仕組み。こちらは本当に削除します。
何度もセルを実行すると、すでに要素を削除しているのでそんな要素は無いとエラーが出ます。
del data_f2['eyesight'] data_f2
結果
id | name | age | weight | height | |
---|---|---|---|---|---|
0 | 1 | Nakajima | 48 | 60 | 168 |
1 | 2 | Hanazawa | 30 | 78 | 173 |
2 | 3 | Hama | 28 | 64 | 162 |
3 | 4 | Isono | 51 | 58 | 172 |
インデックスの並び順を変更
インデックスの並び順を変更するにはreindex()を使います。
data_f2.reindex(columns=['id', 'age', 'name', 'height', 'weight'])
結果
id | age | name | height | weight | |
---|---|---|---|---|---|
0 | 1 | 48 | Nakajima | 168 | 60 |
1 | 2 | 30 | Hanazawa | 173 | 78 |
2 | 3 | 28 | Hama | 162 | 64 |
3 | 4 | 51 | Isono | 172 | 58 |
インデックス名を変更
インデックスの要素の内容を変更する場合はrename()関数を使います。
旧要素と新要素を辞書形式で指定します。
上のreindex()関数と間違って使わないように注意してください。
data_f2.rename(columns={'id':'ID', 'age':'年齢', 'name':'名前', 'height':'身長', 'weight':'体重'})
結果
ID | 名前 | 年齢 | 体重 | 身長 | |
---|---|---|---|---|---|
0 | 1 | Nakajima | 48 | 60 | 168 |
1 | 2 | Hanazawa | 30 | 78 | 173 |
2 | 3 | Hama | 28 | 64 | 162 |
3 | 4 | Isono | 51 | 58 | 172 |
data_f2.columns = ['id', 'なまえ', 'ねんれい', 'たいじゅう', 'しんちょう'] data_f2
結果
id | なまえ | ねんれい | たいじゅう | しんちょう | |
---|---|---|---|---|---|
0 | 1 | Nakajima | 48 | 60 | 168 |
1 | 2 | Hanazawa | 30 | 78 | 173 |
2 | 3 | Hama | 28 | 64 | 162 |
3 | 4 | Isono | 51 | 58 | 172 |
追記 列を属性風に指定する場合の注意点
列を抽出する場合、属性風の指定をするとエラーになる場合があります。
実際にそのような例を試してみます。
Cityの前後に*を付けたり、名前を日本語にしてさらに全角スペースを含めています。
attri_data = {'ID':['100', '101', '102', '103', '104'], '*City*':['Tokyo', 'Osaka', 'Kyoto', 'Hokkaido', 'Tokyo'], 'Birth_year':[1990, 1989, 1992, 1997, 1982], '氏 名':['山田 ひろし', 'Hanako', 'Yuki', 'Satoru', 'Steve']} attri_data_frame1 = pd.DataFrame(attri_data) attri_data_frame1
結果
ID | *City* | Birth_year | 氏 名 | |
---|---|---|---|---|
0 | 100 | Tokyo | 1990 | 山田 ひろし |
1 | 101 | Osaka | 1989 | Hanako |
2 | 102 | Kyoto | 1992 | Yuki |
3 | 103 | Hokkaido | 1997 | Satoru |
4 | 104 | Tokyo | 1982 | Steve |
全角スペースを含む日本語を属性風の指定にしたらエラーになります。
attri_data_frame1.氏 名
結果
エラーになります。
変数名として使えないアスタリスクを含めてもエラーになります。
attri_data_frame1.*City*
結果
エラーになります。
辞書風の抽出なら問題ありません。
attri_data_frame1['氏 名']
結果
0 山田 ひろし
1 Hanako
2 Yuki
3 Satoru
4 Steve
Name: 氏 名, dtype: object
次の場合も、辞書風の抽出なら問題ありません。
attri_data_frame1['*City*']
結果
0 Tokyo
1 Osaka
2 Kyoto
3 Hokkaido
4 Tokyo
Name: *City*, dtype: object
参考になった書籍
Pandasを使いこなすための必携の本。Pandasの作者自ら書いた本でNumpyやPandasの使い方が詳細に書かれている。
Pythonサンプルのダウンロード
ここでダウンロードする「Pandas_video_dataframe1_2」ファイルは、このPandas動画で使用したものです。
コメントを投稿するにはログインしてください。