u++の備忘録

csv化で文字列になったlistやdictを元に戻す

csv化すると文字列になってしまう仕様があるのでpickle形式などで保存するのが良いですが、諸般の事情でcsvで読み込む想定の場合の一つの解決策として、ast.literal_eval() *1*2 を使う方法を紹介します。

具体例

冒頭でastとpandasをimportします。astは標準ライブラリに含まれているので、pip installなどは不要です。

import ast
import pandas as pd

今回は次のような単純なDataFrameを題材にします。

df = pd.DataFrame({
    'sample': [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
})
df

f:id:upura:20190903190136p:plain

要素を確認すると、list型になっています。

df['sample'][0], type(df['sample'][0])
([1, 2, 3], list)

このDataFrameを一旦csvに吐き出した後に改めて読み込むと、要素は文字列型に変換されています。

df.to_csv('sample.csv', index=False)
df2 = pd.read_csv('sample.csv')
df2['sample'][0], type(df2['sample'][0])
('[1, 2, 3]', str)

文字列を split() して分割する方法もありますが、ここでは ast.literal_eval() を使うことで list 型から文字列型に変換しました。ast.literal_eval() はdict型への変換にも対応しています。

df2['sample_list'] = [ast.literal_eval(d) for d in df2['sample']]
df2

f:id:upura:20190903190804p:plain

df2['sample_list'][0], type(df2['sample_list'][0])
([1, 2, 3], list)

おわりに

本記事では、ast.literal_eval() を用いて csv 化で文字列になった list や dict を元に戻す方法を紹介しました。実装はNotebook形式でGitHubでも公開しています*3