Pandasはざっくりと言うと、エクセルでやっていたことをpythonで簡単に行えて、さらに至れり尽くせりの機能が手に入るものです。
エクセルのような表を作成するにはDataFrame型(オブジェクト)を使うことになります。
今回はDataFrameの作り方から簡単な取り扱い方法を学習します。
PandasのDataFrameについて
DataFrameコンストラクターで作成されたオブジェクトがデータフレームです。
データフレームは行と列で構成されるテーブル形式のデータ構造を持ち、列ごとに別々の型の要素を持たせることができます。
次のようなエクセルの表を思い出してください。
列ごとにデータの型は日付であったり、数字だったり、文字列などとそれぞれ違っています。
データフレームはデフォルトで行と列に0から始まるシーケンスのインデックスを持っていますが、別途自分でインデックスを設定することも可能です。
DataFrameコンストラクターについて
DataFrameの作成はDataFrameコンストラクターで作成します。引数の使い方は以下のとおりです。
class pandas.DataFrame(data=None, index: Optional[Collection] = None, columns: Optional[Collection] = None, dtype: Optional[Union[str, numpy.dtype, ExtensionDtype]] = None, copy: bool = False)
パラメーター
data: ndarray(構造化または同種)、Iterable、dict、またはDataFrame
Dictには、シリーズ、配列、定数、またはリストのようなオブジェクトを含めることができます。
バージョン0.23.0で変更:データがdictの場合、列の順序はPython 3.6以降の挿入順序に従います。
バージョン0.25.0で変更:データが辞書のリストである場合、列の順序はPython 3.6以降の挿入順序に従います。
index: または配列のような
結果のフレームに使用するインデックス。入力データのインデックス情報部分がなく、インデックスが提供されていない場合、デフォルトでRangeIndexになります。
columns: インデックスまたは配列のような
結果のフレームに使用する列ラベル。列ラベルが指定されていない場合、デフォルトでRangeIndex(0、1、2、…、n)になります。
dtype: dtype、デフォルトはなし
強制するデータ型。許可されるdtypeは1つだけです。なしの場合、推測します。
copy: ブール値をコピー、デフォルトはFalse
入力からデータをコピーします。DataFrame / 2d ndarray入力のみに影響します。
DataFrameの具体的な作成方法
DataFrame作成には、同じ長さをもつリスト型のバリューを持ったディクショナリか、Numpy配列を使用します。
作成されたデータフレームの行と列には自動的に0から始まるシーケンスのインデックスが付与されます。
Pandasのインポート
まず最初にPandasをインポートしておきます。
import pandas as pd
Pythonの辞書から作成する方法
まず、Pythonの辞書を用意しておいて、あとはDataFrameコンストラクターの引数に作成した辞書を指定します。
元データは辞書でも2次元リスト、またはNumpy配列でも構いませんが、辞書を使うメリットはキーに指定した要素が列のインデックスになります。
その他の引数は省略可能です。(デフォルト値が入ります)
次のコードは、インデックスを明示的に指定せずに、データフレームを作成した例
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) data_f1
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
0 | Nakajima | 1 | 48 | 60 | 168 |
1 | Hanazawa | 2 | 30 | 78 | 173 |
2 | Hama | 3 | 28 | 64 | 162 |
3 | Isono | 4 | 51 | 58 | 172 |
行のインデックスを明示的に指定する方法
行に明示的にインデックスを指定したい場合は、indexキーワード引数で指定します。
次の例は、インデックスを明示的に設定してデータフレームを作成した例
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 |
行、列共にインデックスなしの例
辞書を使わずに、元データをリストやnumpy配列にした場合、明示的にインデックスを付けない限り0からのシーケンス番号が付与されます。
2次元のリストでデータフレームを作成した例
data_noindex = [['Nakajima', 'Hanazawa', 'Hama', 'Isono'], [1, 2, 3, 4], [48, 30, 28, 51], [60, 78, 64, 58], [168, 173, 162, 172]] data_f1_noindex = pd.DataFrame(data_noindex) data_f1_noindex
結果
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | Nakajima | Hanazawa | Hama | Isono |
1 | 1 | 2 | 3 | 4 |
2 | 48 | 30 | 28 | 51 |
3 | 60 | 78 | 64 | 58 |
4 | 168 | 173 | 162 | 172 |
インデックスを明示的に指定して転置した例
インデックスを明示的に設定して、尚且つ転置を利用して行と列を入れ替えた例
data_noindex = [['Nakajima', 'Hanazawa', 'Hama', 'Isono'], [1, 2, 3, 4], [48, 30, 28, 51], [60, 78, 64, 58], [168, 173, 162, 172]] data_f1_noindex = pd.DataFrame(data_noindex,index=['name', 'id', 'age', 'weight', 'height']) data_f1_noindex.T
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
0 | Nakajima | 1 | 48 | 60 | 168 |
1 | Hanazawa | 2 | 30 | 78 | 173 |
2 | Hama | 3 | 28 | 64 | 162 |
3 | Isono | 4 | 51 | 58 | 172 |
Pandasの便利なメソッドを活用
行数の多い表の場合には、先頭(最初)と末尾(最後)の行を返すメソッドhead()とtail()を使います。
このメソッドは、DataFrameとSeriesでも使用可能です。
head()の使い方
head()を使うと先頭から指定した行を表示できます。
引数を指定をしないと5件表示されます。
最初から5件表示
data_f1.head()
結果
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 |
tail()メソッドは最後の3件を表示します。(降順ではありません)
最後の3件を表示する例
data_f1.tail(3)
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
b | Hanazawa | 2 | 30 | 78 | 173 |
c | Hama | 3 | 28 | 64 | 162 |
d | Isono | 4 | 51 | 58 | 172 |
shape属性について
行列の形態を確認するのは「shape」プロパティを使います。
data_f1.shape
結果
(4, 5)
Pandas データから特定の要素を抽出
PandasのdataFrameで一番悩ましいのは特定要素の抽出方法です。
最も重要なデータ抽出が悩ましいため、挫折する場合もあるかもしれませんが、これは最も簡単に直感的に取り出す方法をいくつも揃えているための結果かもしれません。そのため、誰にもわかりやすいというPythonの思想を受け継いで、できるだけどんな人にもわかりやすい手法はどれか考えて、抽出方法を決めておくのが良いかもしれません。
列の取り出し
特定の列の抽出は列のキーを辞書のように指定するか属性指定することで、シリーズとして取り出せます。
属性指定する場合は日本語や特殊記号が混ざる場合はエラーの原因になりますので注意が必要です。
列の取り出しは列名を辞書風に取り出す例
print(data_f1['name']) print(type(data_f1['name']))
結果
a Nakajima
b Hanazawa
c Hama
d Isono
Name: name, dtype: object
複数の列を取得したい場合は抽出したい列をリストで指定します。
print(data_f1[['name','age']])
結果
name age
a Nakajima 48
b Hanazawa 30
c Hama 28
d Isono 51
属性風取り出し方
列を属性のように取り出す方法もあります。
ただし、属性のようにドットでつないで取り出す方法はJupyter Notebook特有の記述です。日本語だったり変数で使用できない記号などが含まれていると正しく動作しないので積極的に使わない方が良いでしょう。
属性風の取り出し例
print(data_f1.name)
結果
a Nakajima
b Hanazawa
c Hama
d Isono
Name: name, dtype: object
列を取り出しておいて特定の行を取り出す方法
取り出した値はSeries型ですから、Seriesのインデックス番号を指定することで特定の行の要素が取れます。
ここで重要なのは、列を指定して取り出した値はSeries型だという事です。
data_f1['name'][0]
結果
‘Nakajima’
もちろん、取得した列の特定行をスライスすることもできます。
data_f1['name'][0:3]
結果
a Nakajima
b Hanazawa
c Hama
Name: name, dtype: object
行の取り出し方 混乱するので注意
行だけを取得する場合、スライスで指定します。スライスはインデックス番号でも明示的に付けた名前でも可能です。
ただし、単一の行名や行番号ではエラーになります。単一行でもスライスの記述をする必要があります。
結果はdataframe型で取得されます。
この方法は推奨されていませんので注意してください。次回紹介するlocやilocを使った方がスッキリすると思います。
スライスする事でインデックス名で行を取り出す例
data_f1['a':'c']
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Nakajima | 1 | 48 | 60 | 168 |
b | Hanazawa | 2 | 30 | 78 | 173 |
c | Hama | 3 | 28 | 64 | 162 |
スライスの指定をインデックス番号にして複数の行を取り出す例
data_f1[0:3]
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Nakajima | 1 | 48 | 60 | 168 |
b | Hanazawa | 2 | 30 | 78 | 173 |
c | Hama | 3 | 28 | 64 | 162 |
1行だけ取り出す例
data_f1[0:1]
結果
name | id | age | weight | height | |
---|---|---|---|---|---|
a | Nakajima | 1 | 48 | 60 | 168 |
型の確認
type(data_f1[0:1])
結果
pandas.core.frame.DataFrame
行を取り出してから列の値を取り出す
インデックス番号1の行のnameの列を取り出し例
data_f1[1:2]['name']
結果
b Hanazawa
Name: name, dtype: object
型を確認するとSeriesが返ってきます。
type(data_f1[1:2]['name'])
結果
pandas.core.series.Series
全ての行のname列の取り出し例
data_f1[:]['name']
結果
a Nakajima
b Hanazawa
c Hama
d Isono
Name: name, dtype: object
抽出のまとめ
DataFrame型のデータから特定要素を抽出する方法は次の手順
- DataFrameの抽出方法は色々用意されているが、まず列を指定して列データを取り出す
- 列の指定は辞書のように列名で指定する
- 属性風の列取り出しは使わない方が無難
- 複数の列を指定するにはリストで指定する
- 取り出した列はSeries型だから、要素をインデックス名あるいはインデックス番号で取得する
- 行を指定したい場合は、スライスで指定できるが、この方法は推奨されてないので次回紹介するloc,ilocにする
参考になった書籍
Pandasを使いこなすための必携の本。Pandasの作者自ら書いた本でNumpyやPandasの使い方が詳細に書かれている。
Pythonサンプルのダウンロード
ここでダウンロードする「Pandas_video_dataframe1_1」ファイルは、このPandas動画で使用したものです。
コメントを投稿するにはログインしてください。