RigelのR言語メモであーる(R言語だけとは言っていない)

RigelのR言語メモであーる(主にpython)

興味あることや趣味、やったことについて書くよ

pandasのSeriesよりDataFrameの方が保存サイズが小さくなる

1列のpandasのデータをpickleで保存する場合。

そのとき、なぜかSeriesで保存するよりDataFrameで保存した方がサイズが小さくなることを確認した。

ちょっと条件いろいろ試して実験しメモ。

実験

以下の条件で、SeriesとDataFrameをpickleで保存しサイズを測る。

  • データ件数
    10000と10000000の2パターン。
  • indexの種類
    普通のIndexとRangeIndexの2パターン。
    普通のIndexの方のdtypeはstr型とする。
  • データのdtype
    bool型とstr型の2パターン。
    str型は"TRUE" or "FALSE"とし、どちらの型も割合は約半分ずつとする。

以上計8パターンで比較する。

結果

結果は以下の表。

データ件数 indexの種類 データのdtype Series DataFrame
10000 Index bool 129KB 80KB
10000 Index str 169KB 120KB
10000 RangeIndex bool 10.6KB 10.7KB
10000 RangeIndex str 20.6KB 20.7KB
10000000 Index bool 159MB 109MB
10000000 Index str 199MB 149MB
10000000 RangeIndex bool 10.0MB 10.0MB
10000000 RangeIndex str 20.0MB 20.0MB
  • DataFrameはSeriesと同等かそれより小さい。
  • indexの種類がRangeIndexの場合はどちらでも(ほぼ)変わらない。
  • データのdtypeがstrよりboolの方が変化率が大きい。

考察

Indexがなにかしてそう。
データのdtypeがstrよりboolの方がindexの影響度合いが大きくなるので、boolの方が変化率が大きいのかもしれない。
軽く調べた感じでは原因が分からなかった。

コード

import pandas as pd
import numpy as np

for N in [10 ** 4, 10 ** 7]:
    data = pd.DataFrame({"value": np.random.rand(N) > 0.5})
    data.to_pickle(f"{N}_RANGE_BOOL_DataFrame.pickle")
    data.value.to_pickle(f"{N}_RANGE_BOOL_Series.pickle")

    data.value = data.value.astype("str")
    data.to_pickle(f"{N}_RANGE_STR_DataFrame.pickle")
    data.value.to_pickle(f"{N}_RANGE_STR_Series.pickle")

    data.index = data.index.astype("str")
    data.to_pickle(f"{N}_STR_STR_DataFrame.pickle")
    data.value.to_pickle(f"{N}_STR_STR_Series.pickle")

    data.value = data.value.astype("bool")
    data.to_pickle(f"{N}_STR_BOOL_DataFrame.pickle")
    data.value.to_pickle(f"{N}_STR_BOOL_Series.pickle")