pandas-python PR

【初心者向け】Python pandas 「DataFrame」の使い方をシンプルに解説

記事内に商品プロモーションを含む場合があります

はじめに

無料で使える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次元配列の縦方向を「列」、横方向を「行」として扱います。

DataFrameのデータ構造をイラストで説明した画
DataFrameの構成

行と列にはそれぞれ「Index」・「Columns」という名前の「軸ラベル」が存在しています。
軸ラベルにより、行や列に番号や名前を付けることができます。

名前機能
Colums「列軸」に対する軸ラベルです。列名・列番号とも呼びます。
Index「行軸」に対する軸ラベルです。行名・行番号とも呼びます。

Seriesとの対応

DataFrameはSeriesをベースに作成されている(Seriesの集まり)ため、DataFrameの行・列の全体や、一部をSeriesに分解(抽出)することができます。

DataFrameとSeriesとの対応をイラストで説明した画像
Seriesとの対応

Seriesへの分解(抽出)方法は、「要素の抽出」で説明します。

DataFrameの使い方

DataFrameについての解説内容は以下の通りです (クリックで各項目に移動できます)。

DataFrameの作成・名前を付ける

DataFrameの操作

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つの方法を紹介します。

  1. 新しい行名称(番号)に配列を代入する
  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を動かす方法などが特集されています。

編集:日経ソフトウエア
¥1,925 (2024/02/20 06:32時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場
\ポイント5%還元!/
Yahooショッピング

もうひとつのデータ形式「Series」

この記事では「DataFrame」について解説しましたが、pandasでは「Series」というデータ形式も存在し、DataFramの行を構成しています。「Series」については以下の記事をご覧ください。

質問・要望 大歓迎です

「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。

使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。

ABOUT ME
えす
現役のソフトウェアエンジニアです。 C++ C# Python を使ってます。10年ちょい設計/開発部門にいましたが、今はQAエンジニアっぽいことをしています。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です