[pandas超入門]DataFrameの情報(形状、要素数、要素のデータ型など)を調べてみよう:Pythonデータ処理入門(1/2 ページ)
DataFrameオブジェクトにはたくさんの属性やメソッドがあります。その中から今回はDataFrameオブジェクト自体に関する情報を調べたり、これを他のオブジェクトに変換したりするのに使えるものを紹介します。
本シリーズと本連載について
本シリーズ「Pythonデータ処理入門」は、Pythonの基礎をマスターした人を対象に以下のような、Pythonを使ってデータを処理しようというときに便利に使えるツールやライブラリ、フレームワークの使い方の基礎を説明するものです。
- NumPy(「NumPy超入門」の目次はこちら)
- pandas(本連載)
- Matplotlib
なお、本連載では以下のバージョンを使用しています。
- Python 3.12
- pandas 2.2.1
前回はpandasのDataFrameオブジェクトの生成とloc属性/iloc属性と軸ラベル/インデックスを組み合わせて要素を選択する方法について話しました。今回はDataFrameオブジェクトに関するさまざまな情報を調べたり、別の種類のオブジェクトに変換したりするのに使える属性やメソッドを紹介していきます。
DataFrameオブジェクトの要素の型/形状/次元数などを調べるには
本連載の第1回ではheadメソッドなどを紹介しましたが、ここではまずDataFrameオブジェクトそのものについての情報、例えばどんな種類のデータを格納しているのかや、その形状(何行何列のデータなのか)などを調べる方法を紹介します。ここでは以下に示すコードで生成したDataFrameオブジェクトを例に取りましょう。
df = pd.DataFrame([{'name': 'kawasaki', 'age': 80, 'weight': 88.8},
{'name': 'isshiki', 'age': 40, 'weight': 65.2},
{'name': 'endo', 'age': 52, 'weight': 78.5}])
print(df)
# 出力結果:
# name age weight
#0 kawasaki 80 88.8
#1 isshiki 40 65.2
#2 endo 52 78.5
dtypes属性
DataFrameオブジェクトには列ごとにさまざまな型のデータを格納できます。ある列には整数値のデータが、別の列には浮動小数点数値のデータが、また別の列には文字列データが格納されるといったこともよくあります。こうしたときに、DataFrameオブジェクトのどの列にどんな型のデータが含まれているかを知るのにdtypes属性を使えます(実際には、infoメソッドなど、他の方法もあります)。
調べるには単にオブジェクト名に続けて「.dtypes」と記述します。以下はその例です。
print(df.dtypes)
# 出力結果:
#name object
#age int64
#weight float64
#dtype: object
print(type(df.dtypes)) # <class 'pandas.core.series.Series'>
1行目ではdtypes属性により上で作成したDataFrameオブジェクトに格納されているデータの型情報を出力しています。最後の行ではdtypes属性の値が何かをtype関数で調べていますが、コメントを見れば分かる通り、Seriesオブジェクトです。
「print(df.dtypes)」の出力結果から'name'列には文字列がobject型のデータとして、'age'列にはint64型のデータが、'weight'列にはfloat64型のデータが格納されることが分かりました。
また、dtypes属性の値であるところのSeriesオブジェクトのデータ型(dtype属性)の値は「object」になっていることも分かります(「dtype: object」)。なぜ、このSeriesオブジェクトのdtype属性がobject型かといえば、ここではobject、int64、float64を表すクラスが格納されているからです。
s = df.dtypes
print(s.loc['name']) # object
print(s['age']) # int64
print(s['weight']) # float64
DataFrameオブジェクトにはdtypes属性があり各列のデータ型を取得できること、Seriesオブジェクトにはdtype属性がありその一次元配列の要素のデータ型を取得できることが分かりました。ということは次のようなことも可能です。
print(df['name'].dtype) # object
これは作成したDataFrameオブジェクトの'name'列を選択し、Seriesオブジェクトとして取り出して、そのdtype属性を調べるコードです。
shape属性
DataFrameオブジェクトでは2次元にデータが並んでいます。その形状(それが何行何列なのか)を調べるのに使うのがshape属性です。以下に例を示します。
df.shape # (3, 3)
先ほど作成したDataFrameオブジェクトは3行3列だったので、shape属性の値はそのことを表す「(3, 3)」というタプルになっています。
なお、Seriesオブジェクトにもshape属性があります。
df['name'].shape # (3, )
そうはいっても、Seriesオブジェクトは一次元配列を表すものなので、上のように要素が1つだけのタプルがshape属性の値となります(タプルの第0要素の値=Seriesオブジェクトの要素数)。
size属性
size属性はDataFrameオブジェクト(またはSeriesオブジェクト)に格納される全要素数を意味します。
print(df.size) # 9
print(df['name'].size) # 3
最初のコードはDataFrameオブジェクトの全要素数(3行3列なので9)を、次のコードは'name'列の要素数(3)を取得しています。
ndim属性
ndim属性はDataFrameオブジェクト(やSeriesオブジェクト)の次元数を調べるものです。といっても、NumPyの多次元配列とは異なり、DataFrameオブジェクトは二次元なのでその値は常に2です(Seriesオブジェクトでは常に1)。
print(df.ndim) # 2
print(df['name'].ndim) # 1
columns属性
columns属性は列ごとに付けられた軸ラベルを取得するものです。
c = df.columns
print(c) # Index(['name', 'age', 'weight'], dtype='object')
type(c) # pandas.core.indexes.base.Index
先ほど作成したDataFrameオブジェクトでは3つの列に'name'、'age'、'weight'という3つの軸ラベルを付与していたので、columns属性の値はそのようになっています。columns属性の値はpandas.Indexクラスのインスタンスであり、その要素は変更できません。なお、変数cに代入したcolumns属性の値は後で列の軸ラベルを復元するために使用します。
df.columns[0] = 'NAME' # TypeError
ただし、columns属性に新しい軸ラベルとなる値を代入することは可能です。
df.columns = ['NAME', 'AGE', 'WEIGHT']
print(df)
# 出力結果:
# NAME AGE WEIGHT
#0 kawasaki 80 88.8
#1 isshiki 40 65.2
#2 endo 52 78.5
print(df.columns) # Index(['NAME', 'AGE', 'WEIGHT'], dtype='object')
なお、以下のように軸ラベルを指定せずにDataFrameオブジェクトを生成した場合、columns属性の値は整数値を表すRangeIndexクラスのインスタンスになります。
df2 = pd.DataFrame([['kawasaki', 80, 88.8],
['isshiki', 40, 65.2],
['endo', 52, 78.5]])
df2.columns # RangeIndex(start=0, stop=3, step=1)
もし文字列の軸ラベルから整数値のラベルに変更したいのであれば、次のようにrangeオブジェクトをcolumns属性に代入すればよいでしょう。
df.columns = range(3)
print(df)
# 出力結果:
# 0 1 2
#0 kawasaki 80 88.8
#1 isshiki 40 65.2
#2 endo 52 78.5
print(df.columns) # RangeIndex(start=0, stop=3, step=1)
index属性
columns属性と同様に、index属性は行ごとに付けられた軸ラベルを取得するものです。
idx = df.index
print(idx) # RangeIndex(start=0, stop=3, step=1)
type(idx) # pandas.core.indexes.range.RangeIndex
ラベルを付与する対象が列か行かが異なりますが、それ以外の扱いはcolumns属性と同じと考えられます。以下に例を示します。ただし、先ほどはDataFrameオブジェクトの生成でインデックスを指定していなかったので、ここではindex属性の値については要素を変更できないことと、index属性に新しいラベルを代入可能であることを示すだけとしましょう。
# index属性の要素は変更できない
df.index[0] = 'a' # TypeError
# しかし、index属性に新しいラベルを代入することは可能
df.index = ['a', 'b', 'c'] # OK
print(df.index) # Index(['a', 'b', 'c'], dtype='object')
axes属性
今紹介したcolumns属性とindex属性の両者をまとめて取得するにはaxes属性を使います。axes属性の値は先頭要素を行ラベル、次の要素を列ラベルとするリストです。
df.columns = c # 最初の列名に戻す
ax = df.axes
print(ax)
# 出力結果:
# [Index(['a', 'b', 'c'], dtype='object'),
# Index(['name', 'age', 'weight'], dtype='object')]
注意が必要なのは、axes属性(axesプロパティ)は変更不可能(セッターを持たないプロパティ)であることと、axes属性の値であるリストの要素を変更しても軸ラベルには反映されない点です(axes属性の値は[df.index, df.columns]であり、「axes[0] = ……」のようなコードを実行してもリストの要素が変更されるだけで、行ラベルが変更されるわけではありません)。あくまでも読み取り目的で2つの軸ラベルを取得するものだと考えるべきです。
Copyright© Digital Advantage Corp. All Rights Reserved.