はじめに
無料で使えるPythonのデータ解析ライブラリ 「pandas」のデータ型について解説します。
pandas では以下2つのデータ型がよく使われます。
名前 | 機能 |
---|---|
Series | 配列のようなデータ形式です。表の縦・横の一方向(一次元)に対応します |
DataFrame | 表のようなデータ形式です。表の縦・横両方(二次元)に対応します |
DataFrame
極簡単に言ってしまうと「Series」が集まったデータ型です。表などの二次元のデータを扱いやすくする機能を搭載しています。
Series
DataFrameのベースとなるデータ型です。行などの、一次元のデータを扱いやすくする機能を搭載しています。
今回の記事の内容
今回は上記pandasの2つのデータ型の内、「DataFrame」について紹介します。
Pythonやpandasの初心者の方でもなるべく分かりやすいように、シンプルなコードで解説します。
Seriesについては以下のの記事をご覧ください。
環境
この記事は以下の環境で作成しています。
環境 | バージョンなど |
Python | 3.9.6 |
pandas | 4.7.2 |
OS | Wiindows10 |
「Windows10 + Python + pandas + venv」の環境で作成しています。(AnacondaやJupiterNotebookは使用していません)
「環境やインストール方法が知りたい」という方は、以下の記事をご覧ください。
DataFrameの概要
DataFrameの構成
DataFrameは以下のようなデータ構成をしています。2次元配列の縦方向を「列」、横方向を「行」として扱います。
行と列にはそれぞれ「Index」・「Columns」という名前の「軸ラベル」が存在しています。
軸ラベルにより、行や列に番号や名前を付けることができます。
名前 | 機能 |
---|---|
Colums | 「列軸」に対する軸ラベルです。列名・列番号とも呼びます。 |
Index | 「行軸」に対する軸ラベルです。行名・行番号とも呼びます。 |
Seriesとの対応
DataFrameはSeriesをベースに作成されている(Seriesの集まり)ため、DataFrameの行・列の全体や、一部をSeriesに分解(抽出)することができます。
Seriesへの分解(抽出)方法は、「要素の抽出」で説明します。
DataFrameの使い方
DataFrameについての解説内容は以下の通りです (クリックで各項目に移動できます)。
DataFrameの作成・名前を付ける
DataFrameの操作
DataFrameからSeriesを作る
- DataFrameからSeriesを作る
DataFrameの機能は非常に多く、ここですべての機能は紹介しきれません。他の機能が気になる方は、是非公式ドキュメントも参照してみてください。
DataFrameの作成・名前をつける
配列から作成
作成した配列を、DataFrame関数(コンストラクタ)に渡します。
配列には名称(ラベル)の情報がないため、行には配列の行番号が、列に0からの連番が自動的に設定されます。
import pandas as pd
# 配列からDataFrameを作成します
list = ["taro","jiro","saburo"]
df = pd.DataFrame( list )
print(df)
"""
# 実行結果:
# 行に配列の要素番号、列に0からの値が設定されます
0
0 taro
1 jiro
2 saburo
"""
辞書(Dictionary)から作成
作成した辞書を、DataFrame関数(コンストラクタ)に渡します。
“name”などの辞書のキーは、DataFrameの「列方向の情報」として使用されます。
キーを「行方向の情報」として使用したい場合は、from_dict関数を使用してください。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
"color" :["Red", "Blue", "Green"],
"flag" :["True", "True", "False"],
}
df = pd.DataFrame( dict )
# 辞書の要素名を 行 に使う場合はfrom_dict()を使います
df2 = pd.DataFrame.from_dict(dict, orient="index")
print(df)
print(df2)
"""
# 実行結果:
name age color flag
0 taro 11 Red True
1 jiro 21 Blue True
2 saburo 22 Green False
0 1 2
name taro jiro saburo
age 11 21 22
color Red Blue Green
flag True True False
"""
軸ラベルを設定する
index関数、Columns関数を使用します。
配列からDataFrameを作成した場合など、後から行名称・列名称を設定したい場合に使います。
import pandas as pd
# 配列からDataFrameを作成します
list = ["taro","jiro","saburo"]
df = pd.DataFrame( list )
# indexに名前を設定します
df.index = ["No.0","No.1","No.2"]
# columnsに名前を付けます
df.columns = ["name",]
print(df)
"""
# 実行結果:
name
No.0 taro
No.1 jiro
No.2 saburo
"""
DataFrameの操作
要素の取得・変更・追加などの、Seriesの操作方法は以下の通りです。
データの取得
「at・iat・loc・iloc」プロパティを使って、要素の番号・名称を指定して取得します。
指定の順番は、「行名称(番号)」、「列名称(番号)」です。
下記コードはどれも同じ”taro”を取得しています。
「at・iat・loc・iloc」は要素名称(番号)で、Seriesのデータへアクセスするプロパティです、[]で指定します。 「iあり」は番号、「iなし」は名称指定に使用します。
プロパティの説明や効能などはやや難しくなるので、ここでは「データへアクセスするための、特別な変数のようなもの」として見てください。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
"color" :["Red", "Blue", "Green"],
"flag" :["True", "True", "False"],
}
df = pd.DataFrame( dict )
# atで取得
valueAt = df.at[0,"name"]
# iatで取得
valueIAt = df.iat[0,0]
# locで取得
valueLoc = df.loc[0,"name"]
# ilocで取得
valueILoc = df.iloc[0,0]
print(valueAt)
print(valueIAt)
print(valueLoc)
print(valueILoc)
"""
# 実行結果:
taro
taro
taro
taro
"""
データの変更
「at・iat・loc・iloc」プロパティで、要素の番号・名称を指定してデータを代入します。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
"color" :["Red", "Blue", "Green"],
"flag" :["True", "True", "False"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age color flag
0 taro 11 Red True
1 jiro 21 Blue True
2 saburo 22 Green False
"""
# atで設定
df.at[0,"name"] = "shiro"
# iatで設定
df.iat[0,1] = "31"
# locで設定
df.at[0,"color"] = "Yellow"
# ilocで設定
df.iat[0,3] = False
print(df)
"""
# 実行結果:
name age color flag
0 shiro 31 Yellow False # <-変更されている
1 jiro 21 Blue True
2 saburo 22 Green False
"""
行の追加
DataFrameに行を追加する方法は、複数存在しますが、ここでは以下2つの方法を紹介します。
- 新しい行名称(番号)に配列を代入する
- append関数でDataFrameを結合する
① 新しい行名称(番号)に配列を代入
「at・loc」で、新しい行名称(番号)に配列を代入することで、行を追加できます。
「iat・iloc」プロパティを使うと、対象のオブジェクトを拡大できないとして、IndexErrorになります。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro"],
"age" :[10],
"color" :["Red"],
"flag" :["True"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age color flag
0 taro 10 Red True
"""
# atで行を追加(番号)
df.at[ 1] = ["jiro" ,11,"Blue" ,True ]
# locで行を追加(番号)
df.loc[ 2] = ["sabro",12,"Green",False ]
# atで行を追加(名称)
df.at["No.3"] = ["shiro",13,"Yellow",False ]
# locで行を追加(名称)
df.loc["No.4"] = ["goro",14,"Purple",False ]
# NG
# df.iat = ["shiro",13,"Yellow",False ]
# df.iloc = ["shiro",13,"Yellow",False ]
print(df)
"""
# 実行結果:
name age color flag
0 taro 10 Red True
1 jiro 11 Blue True
2 sabro 12 Green False
No.3 shiro 13 Yellow False
No.4 goro 14 Purple False
"""
※ 2021/11/10修正 19,22行目の要素番号が消えていたため修正しました。
② append関数でDataFrameを結合する
append関数を使って、DataFrameを追加することで、行を追加することができます。
以下の点に注意してください。
デフォルトで使用するとインデックスが重複します。
インデックスを残さない(連番にしたい)場合は、「ignore_index = True」を指定してください。
結合したDataFameは、(別のDataFrameが作成されて)戻り値で返されます。
呼び出したDataFrame自体を変更したときは、以下のようにしてください。
# append関数を呼び出したDataFrameを変更する方法(自身に代入)
df = df.append(df2)
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = { "name":["taro"], "age":[10], "color":["Red"], "flag":["True"] }
dict2 ={ "name":["jiro"], "age":[11], "color":["Blue"], "flag":["True"] }
df = pd.DataFrame( dict )
df2 = pd.DataFrame( dict2 )
# DataFrame内容
"""
name age color flag
0 taro 10 Red True
name age color flag
0 jiro 11 Blue True
"""
# append関数で追加します
df_not_ignore = df.append(df2)
# index情報を無視する設定にします
df_ignore = df.append(df2,ignore_index=True)
print(df_not_ignore)
print(df_ignore)
"""
# 実行結果:
name age color flag
0 taro 10 Red True
0 jiro 11 Blue True # <-- indexに0が二つ
name age color flag
0 taro 10 Red True
1 jiro 11 Blue True # <-- indexが連番
"""
列の追加
行と同様に、「at・loc」で、新しい行名称(番号)に配列を代入することで、行を追加できます。
「iat・iloc」プロパティを使うと、対象のオブジェクトを拡大できないとして、IndexErrorになります。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro"],
"age" :[10],
"color" :["Red"],
"flag" :["True"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age color flag
0 taro 10 Red True
"""
# atで列を追加(番号)
df.at[0,4] = [100]
# locで列を追加(番号)
df.loc[0,5] = [200]
# atで列を追加(名称)
df.at[0,"etc1"] = [300]
# locで列を追加(名称)
df.loc[0,"etc2"] = [400]
# NG
#df.iat[0,4] = [100]
#df.iloc[0,5] = [200]
print(df)
"""
# 実行結果:
name age color flag 4 5 etc1 etc2
0 taro 10 Red True 100.0 200.0 300.0 400.0
"""
要素の抽出
loc・ilocを使って、名称・番号を「始点:終点」の形で範囲指定します。抽出したデータは行・列のどちらか(一次元)場合はSeries型、行・列の範囲を指定(二次元)した場合は、DataFrame型になります。
“番号”を使う場合、スライスの終点より「ひとつ少ない番号」までが取得されます。注意してください。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
"color" :["Red", "Blue", "Green"],
"flag" :["True", "True", "False"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age color flag
0 taro 11 Red True
1 jiro 21 Blue True
2 saburo 22 Green False
"""
# 行を抽出(loc)
series_row = df.loc[0, "name":"flag"]
# 行を抽出(iloc)
#series_row = df.iloc[0, 0:4]
print( type(series_row) )
print(series_row)
# 列を抽出(loc)
series_col = df.loc[0:, "name"]
# 列を抽出(iloc)
#series_col = df.iloc[0:, 0]
print( type(series_col) )
print(series_col)
# 範囲を抽出(loc)
df_range = df.loc[0:, "name":"age"]
# 範囲を抽出(iloc)
#df_range = df.iloc[0:, 0:4]
print(df_range)
"""
# 実行結果:
<class 'pandas.core.series.Series'>
name taro
age 11
color Red
flag True
Name: 0, dtype: object
<class 'pandas.core.series.Series'>
0 taro
1 jiro
2 saburo
Name: name, dtype: object
name age
0 taro 11
1 jiro 21
2 saburo 22
"""
行・列の削除
drop関数を使って削除したい対象を配列で指定します。「行」「列」での指定の違いは以下の通りです。
使用時は以下に注意してください。
削除したDataFameは、(別のDataFrameが作成されて)戻り値で返されます。
呼び出したDataFrame自体を変更したときは、以下のようにしてください。
# drop関数を呼び出したDataFrameを変更する方法(自身に代入)
df = df.drop([0],)
行を削除
引数に「削除したい行番号(名称)を指定した配列」を渡します。
列を削除
引数に、「削除したい列番号(名称)を指定した配列」を「Columns= 」付きで渡します。
配列の指定の後に、「axis=1」と付けても列の削除が可能です。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
"color" :["Red", "Blue", "Green"],
"flag" :["True", "True", "False"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age color flag
0 taro 11 Red True
1 jiro 21 Blue True
2 saburo 22 Green False
"""
# 行を配列で指定して削除
df_delRow = df.drop([0],)
# 列名称を指定して削除
df_delCol1 = df.drop( columns=["name","age","color"] )
# 列名称を配列で指定して削除
df_delCol2 = df.drop( ["name","age","color"], axis=1)
print(df_delRow)
print(df_delCol1)
print(df_delCol2)
"""
# 実行結果:
name age color flag
2 saburo 22 Green False
# df_delCol2も同じ表示です
flag
0 True
1 True
2 False
"""
DataFrameから辞書・配列を作る
辞書の作成
「to_dict関数」を使用して作成します。戻り値として「二次元の辞書」が返されます。
デフォルトは「列名」がキーとなるので、「行名」にしたい場合は、引数に「”index”」を指定します。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age
0 taro 11
1 jiro 21
2 saburo 22
"""
# 列名をキーにした、2次元の辞書を作成
dict = df.to_dict()
# 行名をキーにした、2次元の辞書を作成
dict2 = df.to_dict("index")
print(dict)
print(dict2)
"""
# 実行結果:
{
'name': {0: 'taro', 1: 'jiro', 2: 'saburo'},
'age': {0: '11', 1: '21', 2: '22'}
}
{
0: {'name': 'taro', 'age': '11'},
1: {'name': 'jiro', 'age': '21'},
2: {'name': 'saburo', 'age': '22'}
}
"""
配列の作成
DataFrameから直接作成する方法はありません。一度Series型などを経由する必要があります。
変換方法は様々ありますが、比較的シンプルな「locプロパティと、Seriesのto_list関数を使う方法」を紹介します。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age
0 taro 11
1 jiro 21
2 saburo 22
"""
# 行をSeriesとして抽出
series_row = df.loc[0, "name":"age"]
# Seriesから配列を作成
list_row = series_row.to_list()
print(type(series_row))
print(series_row)
print(type(list_row))
print(list_row)
"""
# 実行結果:
<class 'pandas.core.series.Series'>
name taro
age 11
Name: 0, dtype: object
<class 'list'>
['taro', '11']
"""
DataFrameからSeriesを作る
「要素の抽出」で解説したとおり、 loc・ilocを使って、名称・番号を「始点:終点」の形で範囲指定します。データが行・列のどちらか一方(一次元)である場合はSeriesが作成されます。
import pandas as pd
# 辞書(Dictionary)からDataFrameを作成します
dict = {
"name" :["taro", "jiro", "saburo"],
"age" :["11", "21", "22"],
"color" :["Red", "Blue", "Green"],
"flag" :["True", "True", "False"],
}
df = pd.DataFrame( dict )
# DataFrame内容
"""
name age color flag
0 taro 11 Red True
1 jiro 21 Blue True
2 saburo 22 Green False
"""
# 行を抽出(loc)
series_row = df.loc[0, "name":"flag"]
# 行を抽出(iloc)
#series_row = df.iloc[0, 0:4]
print( type(series_row) )
print(series_row)
# 列を抽出(loc)
series_col = df.loc[0:, "name"]
# 列を抽出(iloc)
#series_col = df.iloc[0:, 0]
print( type(series_col) )
print(series_col)
"""
# 実行結果:
<class 'pandas.core.series.Series'>
name taro
age 11
color Red
flag True
Name: 0, dtype: object
<class 'pandas.core.series.Series'>
0 taro
1 jiro
2 saburo
Name: name, dtype: object
"""
まとめ
無料で使えるPythonのデータ解析ライブラリ 「pandas」でよく使われるデータ型の内、DataFrameの使い方について解説しました。参考になればうれしいです。
お知らせ
3月号の『日経ソフトウェア』はPythonの特集。穴埋め式クイズで学ぶPython入門や、PythonでExcelを動かす方法などが特集されています。
もうひとつのデータ形式「Series」
この記事では「DataFrame」について解説しましたが、pandasでは「Series」というデータ形式も存在し、DataFramの行を構成しています。「Series」については以下の記事をご覧ください。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。