メインコンテンツへスキップ

【Python】dataclassとPandasのSeries, DataFrameを変換する

·1012 文字·3 分
目次

はじめに
#

Pythonのdataclassオブジェクトと、PandasのSeries, DataFrameをそれぞれ変換する方法を備忘録として残します。

検証環境

  • Python 3.11.6
  • Pandas 2.1.3

以降のこの記事では、以下の通りライブラリをインポートしているものとします。また、Personというdataclassを定義します。

from dataclasses import dataclass, asdict
import pandas as pd

@dataclass
class Person:
    name: str
    age: int

dataclassからPandasに変換
#

dataclassをPandasのSeriesやDataFrameに変換する方法を示します。まず、以下のようにPersonクラスのオブジェクトalice, bobを作成します。

>>> alice = Person("Alice", 20)
>>> bob = Person("Bob", 21)

>>> print(alice)
Person(name='Alice', age=20)

>>> print(bob)
Person(name='Bob', age=21)

Series
#

PandasのSeriesの引数は辞書形式で与えることができるため、dataclasses.asdict()関数でPersonオブジェクトを辞書に変換することで、Seriesに変換できます。

>>> print(asdict(alice))
{'name': 'Alice', 'age': 20}

>>> alice_sr = pd.Series(asdict(alice))
>>> print(alice_sr)
name    Alice
age        20
dtype: object

DataFrame
#

DataFrameに変換する場合、pd.DataFrame()にリストで与えます。1個のPersonオブジェクトが1行分のデータになります。

>>> alice_df = pd.DataFrame([alice])
>>> print(alice_df)
    name  age
0  Alice   20

>>> persons_df = pd.DataFrame([alice, bob])
>>> print(persons_df)
    name  age
0  Alice   20
1    Bob   21

Pandasからdataclassに変換
#

PandasのSeriesやDataFrameをdataclassに変換する方法を示します。

Series
#

PandasのSeriesをdataclassに変換するには、以下のようにto_dict()メソッドで辞書形式にして先頭に**を付け、Personクラスの引数に与えます。ただし、SeriesのインデックスがPersonクラスの引数と一致している必要があります。

>>> alice_sr = pd.Series({"name": "Alice", "age": 20})
>>> alice_person = Person(**alice_sr.to_dict())
>>> print(alice_person)
Person(name='Alice', age=20)

簡単に解説すると、辞書に**を付けるとキーワード引数 (keyword argument) を受け取れるPythonの言語仕様を利用しています。

>>> Person(**{"name": "Alice", "age": 20})
Person(name='Alice', age=20)

DataFrame
#

DataFrameの1行が1つのPersonオブジェクトに対応するものとします。複数行からなるDataFrameは1個のPersonオブジェクトにそのまま変換できないため、ここではPersonオブジェクトのリストに変換します。

>>> persons_df = pd.DataFrame({"name": ["Alice", "Bob"],
                               "age": [20, 21]})
>>> print(persons_df)
    name  age
0  Alice   20
1    Bob   21

>>> persons = [Person(**row.to_dict()) for _,row in persons_df.iterrows()]
>>> print(persons)
[Person(name='Alice', age=20), Person(name='Bob', age=21)]

簡単に解説すると、iterrows()メソッドでDataFrameを1行ずつSeries形式で取り出しています。また、リスト内包表記でfor文の処理を1行にまとめています。

Helve
著者
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

関連記事

PandasのTimestampでタイムゾーンを扱う
·1568 文字·4 分
PandasのTimestampオブジェクトにタイムゾーンを設定する方法や、異なるタイムゾーンに変換する方法について述べる。
PandasのTimestampで時刻を扱う
·2140 文字·5 分
PandasのTimestampを使った時刻の生成や、時刻オブジェクトからの属性の取得、任意形式の文字列での出力について述べる。
辞書内包表記でPandasのSeries, DataFrameを作成
·1056 文字·3 分
辞書内包表記を使って、PandasのSeries, DataFrameを少ないコード量で作成する。
pandas.Seriesのcorrメソッドで時系列データの相関係数を求める際の注意点
·1294 文字·3 分
pandas.Seriesのcorrメソッドで時系列データの相関係数を求めるときにはshiftメソッドで時刻をずらします。
PandasのSeriesとDataFrameの作成
·1427 文字·3 分
Pandasの基本データ構造であるSeriesとDataFrameの作成方法について述べる。
Pythonのyield文を使って処理の進捗状況を返す
·973 文字·2 分
Pythonの関数内でfor文を使って重たい処理を回すときに、yield文を使って進捗状況を呼び出し元に返す方法を解説します。