JavaScriptを有効にしてください

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

 ·   3 min read

はじめに

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

検証環境

  • Python 3.11.6
  • Pandas 2.1.3

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

1
2
3
4
5
6
7
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を作成します。

1
2
3
4
5
6
7
8
>>> 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に変換できます。

1
2
3
4
5
6
7
8
>>> 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行分のデータになります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> 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クラスの引数と一致している必要があります。

1
2
3
4
>>> 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の言語仕様を利用しています。

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

DataFrame

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> 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
WRITTEN BY
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

サイト内検索