pandasは、データ解析を容易にする機能を提供するPythonのデータ解析用ライブラリです。
データ分析や機械学習の前処理でよく利用されています。
ここではpandasでSeriesやDataFrameを作成・変換する方法について解説していきます。
使用ライブラリ
pandasは外部ライブラリのため、インストールが必要です
インストール:必要
ライブラリのインストール
pip で pandas をインストールします。
Successfully installed ・・・・と表示されればインストールは成功です。(依存関係のある他のライブラリも同時にインストールされます)
・関連記事:Pythonライブラリのインストール(pipの使い方)
ライブラリの読み込み
pandas を pd
という名前でインポートします。pd
は広く使われていてスタンダードになっているので、この名前を利用する事をおすすめします。
1 | import pandas as pd |
SeriesとDataFrameの違い
Series(シリース)とDataFrame(データフレーム)の違いは以下のようになります。
・Series :1次元の配列のようなオブジェクト。(DataFrameの1列分)
・DataFrame:テーブル形式のスプレッドシート風のデータ構造で、順序付けられた列を持つ。
各列(カラム)は別々の型を持たせることができる。
Series(シリーズ)の作成
リストから作成
引数の index
, name
(インデックス、列名)は省略が可能です。
インデックスを省略すると 0 から始まる連番でインデックスが自動で付きます。
1 2 3 4 5 6 7 8 9 10 | import pandas as pd df = pd.Series([2, 7, 3, -5]) print(df) # 0 2 # 1 7 # 2 3 # 3 -5 # dtype: int64 |
インデックス、列名を指定する場合は以下のようになります。
1 2 3 4 5 6 7 8 | df = pd.Series([2, 7, 3, -5], index=['No1', 'No2', 'No3', 'No4'], name="data") print(df) # No1 2 # No2 7 # No3 3 # No4 -5 # Name: data, dtype: int64 |
辞書から作成
辞書データから Series を作成することもできます。
インデックスと列名は省略可能です。
1 2 3 4 5 6 7 8 | df = pd.Series({'No1':2, 'No2':7, 'No3':3, 'No4':-5}) print(df) # No1 2 # No2 7 # No3 3 # No4 -5 # dtype: int64 |
指定したインデックスと辞書のキーが一致しない場合は、欠損値となり NaN
(Not a Number:非数)が割り当てられます。
1 2 3 4 5 6 7 8 9 10 | df = pd.Series({'No1':2, 'No2':7, 'No3':3, 'No4':-5}, index=['No1', 'No2', 'No3', 'No4', 'No5']) print(df) # No1 2.0 # No2 7.0 # No3 3.0 # No4 -5.0 # No5 NaN # dtype: float64 |
Series は、isnull
関数と、notnull
関数をインスタンスメソッドとして持っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | df.isnull() # No1 False # No2 False # No3 False # No4 False # No5 True # dtype: bool df.notnull() # No1 True # No2 True # No3 True # No4 True # No5 False # dtype: bool |
DataFrame(データフレーム)の作成
DataFrameは、リスト型のデータを持つ辞書をDataFrame関数の引数に渡すことで作成できます。
辞書から作成
1 2 3 4 5 6 | data = {'支店CD' :['S01', 'S02', 'S03'], '支店名' : ['支店01', '支店02', '支店03'], '売上' : [1761, 6467, 9701]} id = [1, 2, 3] df = pd.DataFrame(data, index=id) print(df) |
指定した列がデータを持っていない場合は、その列の値は欠損値となり NaN
(Not a Number:非数)が割り当てられます。
1 2 3 4 5 6 7 | data = [['S01', '支店01', 1761], ['S02', '支店02', 6467], ['S03', '支店03', 9701]] id = [1, 2, 3] colname = ['支店CD', '支店名', '売上', '利益'] df = pd.DataFrame(data, index=id, columns=colname) print(df) |
配列(リスト)から作成
また、引数 data
index
columns
を指定する方法でも作成できます。
1 2 3 4 5 6 7 | data = [['S01', '支店01', 1761], ['S02', '支店02', 6467], ['S03', '支店03', 9701]] id = [1, 2, 3] colname = ['支店CD', '支店名', '売上'] df = pd.DataFrame(data, index=id, columns=colname) print(df) |
リストから作成する場合、指定した列がデータを持っていない時は ValueError
になります。
1 2 3 4 5 6 7 8 9 | data = [['S01', '支店01', 1761], ['S02', '支店02', 6467], ['S03', '支店03', 9701]] id = [1, 2, 3] colname = ['支店CD', '支店名', '売上', '利益'] df = pd.DataFrame(data, index=id, columns=colname) print(df) # ValueError: 4 columns passed, passed data had 3 columns |
ネスト構造の辞書からDataFrame作成
次のように辞書の中に辞書が入っているデータから、DataFrameを作成する方法です。{key_col: {key0: value0, key1: value1}}
1 2 3 4 | d_dict = {'支店CD':{1: 'S01', 2: 'S02', 3: 'S03'}, '支店名':{1: '支店01', 2: '支店02', 3: '支店03'}, '売上':{1: 1761, 2: 6467, 3: 9701}} df = pd.DataFrame(d_dict) |
このようなイメージでDataFrameが作成されます。
DataFrameとSeriesの変換
厳密には「変換」ではなく、DataFrameから一部をSeriesとして取得したり、SeriesからDataFrameを作成することになります。
例では、以下のDataFrameを使用します。
1 2 3 4 5 | data = {'支店CD' :['S01', 'S02', 'S03'], '支店名' : ['支店01', '支店02', '支店03'], '売上' : [1761, 6467, 9701]} id = [1, 2, 3] df = pd.DataFrame(data, index=id) |
DataFrameの列からSeriesを取得
DataFrame の1列のみを指定すると Series として抽出されます。
列名で取得
辞書型のように指定するか、属性指定することで取得できます。
1 2 3 4 5 6 7 8 9 10 11 | print(df['売上']) # 1 1761 # 2 6467 # 3 9701 # Name: 売上, dtype: int64 print(df.売上) # 1 1761 # 2 6467 # 3 9701 # Name: 売上, dtype: int64 |
抽出したSeriesは、DataFrameが持っていたインデックスと同じインデックスを持ち、Name属性も列名から設定されています。データ型は、元のDataFrame列の型を引き継ぎます。
loc, iloc で取得
loc[]
で列名、iloc[]
で列番号を指定してもSeriesとして取得できます。
1 2 3 4 5 6 7 8 9 10 11 | print(df.loc[:, '売上']) # 1 1761 # 2 6467 # 3 9701 # Name: 売上, dtype: int64 print(f.iloc[:, 2]) # 1 1761 # 2 6467 # 3 9701 # Name: 売上, dtype: int64 |
リストやスライスで特定の行を取得することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | print(df.loc[[2,3], '売上']) # 2 6467 # 3 9701 # Name: 売上, dtype: int64 print(df.loc[:2, '売上']) # 1 1761 # 2 6467 # Name: 売上, dtype: int64 print(df.iloc[[0,2], 2]) # 1 1761 # 3 9701 # Name: 売上, dtype: int64 print(df.iloc[:2, 2]) # 1 1761 # 2 6467 # Name: 売上, dtype: int64 |
DataFrameの行からSeriesを取得
loc, iloc で取得
loc[]
で行名、iloc[]
で行番号を指定すると Series として取得できます。
Name 属性は行名(インデックス)が設定され、データ型は object
になります。
※ pandas-1.0.0(2020年2月)から DataFrame の .ix
は廃止されています。
1 2 3 4 5 6 7 8 9 10 11 | print(df.loc[1]) # 支店CD S01 # 支店名 支店01 # 売上 1761 # Name: 1, dtype: object print(df.iloc[1]) # 支店CD S02 # 支店名 支店02 # 売上 6467 # Name: 2, dtype: object |
リストやスライスで特定の列を取得することができます。
1 2 3 4 5 6 7 8 9 | print(df.iloc[2, [1, 2]]) # 支店名 支店03 # 売上 9701 # Name: 3, dtype: object print(df.iloc[2, :2]) # 支店CD S03 # 支店名 支店03 # Name: 3, dtype: object |
Series 全体のデータ型は object になりますが、各要素は元のデータ型を保持しています。
1 2 3 4 5 6 7 8 9 10 | print(df.iloc[2, [1, 2]]) # 支店名 支店03 # 売上 9701 # Name: 3, dtype: object print(type(df.iloc[2, [1, 2]][0])) # <class 'str'> print(type(df.iloc[2, [1, 2]][1])) # <class 'numpy.int64'> |
DataFrameの列からDataFrameを取得
機械学習のライブラリを利用する際は、DataFrame型の方が扱いやすい事があります。
Series ではなく DataFrame で取得する方法を解説します。
列名で取得
DataFrame として取得したい場合は、1列分の列名をリストで指定する事で取得できます。
1 | df[['売上']] |
1 2 | print(type(df[['売上']])) # <class 'pandas.core.frame.DataFrame'> |
複数の列を取得する場合は以下のようになります。
1 | df[['支店名', '売上']] |
loc, iloc で取得
loc[]
で列名、iloc[]
で列番号をそのまま指定すると Series になりますが、リストを指定することでDataFrame として取得できます。
1 | df.loc[:, ['売上']] |
または
1 | df.iloc[:, [2]] |
複数の列を取得する場合は以下のようになります。
1 | df.loc[:, ['支店名', '売上']] |
または
1 | df.iloc[:, [1, 2]] |
DataFrameの行からDataFrameを取得
loc[]
で行名、iloc[]
で行番号をリストで指定すると DataFrame として取得できます。
1 | df.loc[[2]] |
または
1 | df.iloc[[1]] |
複数の列を取得する場合は以下のようになります。
1 | df.loc[[1,2]] |
または
1 | df.iloc[[0,1]] |
・関連記事:pandas DataFrameからデータを抽出