質問: values ws.update_cells(cell_list) ``` ### エラー内容 TypeError: Object of type datetime is not JSON serializable 日付データがJSONで定義されていないため、エラーが発生しているようです ※df1.dtypesで確認すると全ての情報がobjectとなっております 発売日と発送日の日付に”未定”というテキストもが入っているのですが、 うまくスプレッドシートに移行させることは可能でしょうか。 df1で読み込んだエクセル内容を変更することはできません。 ### 試してみたこと 日付の形式を変えてみようと思ったのですがテキストが入っているため変換などもできず・・。 ``` df1['発売日']=pd.to_datetime(df1['発売日']) df1['発送日']=pd.to_datetime(df1['発送日']) **エラー** Unknown string format: 未定 ``` 何かアドバイスなどいただけると大変助かります。 お忙しいところ恐縮ですが、よろしくお願いいたします。
回答: エラーの解釈が間違っています。 > > TypeError: Object of type datetime is not JSON serializable > > > というエラーは、datetime型をJSONに変換できない(シリアライズできない)ということです。すなわち`df1['発売日']`もしくは`df1['発送日']`もしくはその両方に`datetime型`(あるいはそれに相当する型)が含まれているということです。したがって型をシリアライズ可能な文字列型に変換すれば良いです。おそらく日付が未定のところはNaTもしくはNaNとなっていてこれらもシリアライズできませんので一緒に変換する必要があります。 ``` df1['発売日']=df1['発売日'].dt.strftime('%Y/%m/%d %H:%M') df1['発送日']=df1['発送日'].dt.strftime('%Y/%m/%d %H:%M') df1.fillna("未定", inplace=True) ``` [追記] 上記の回答は日付がpandasのTimestamp型を想定しましたが、エラーの内容からdatetime型が直接代入されているようです。シリアライズするためには全てをstr型にする必要があります。一旦下記のような関数を定義して下さい。 ``` def datetime_to_str(d): """datetime型は指定文字列に、それ以外はそのまま返す""" if isinstance(d, datetime): return d.strftime("%Y/%m/%d %H:%M") return d ``` 上記の関数を適用するためにapplyを使用します。 ``` df1["発売日"] = df1["発売日"].apply(datetime_to_str) df1["配送"] = df1["配送"].apply(datetime_to_str) ``` 参考までにソースコードの全体を示します。 ``` import pandas as pd from datetime import datetime def datetime_to_str(d): """datetime型は指定文字列に、それ以外はそのまま返す""" if isinstance(d, datetime): return d.strftime("%Y/%m/%d %H:%M") return d def main(): # 想定されるデータ構造を持ったデータフレームを作成 df1 = pd.DataFrame( { "商品名": ["A", "B", "C"], "発売日": [ datetime.strptime("2020/7/10 12:00", "%Y/%m/%d %H:%M"), datetime.strptime("2020/7/18 12:00", "%Y/%m/%d %H:%M"), "未定", ], "配送日": [ datetime.strptime("2020/7/20 12:00", "%Y/%m/%d %H:%M"), datetime.strptime("2020/7/24 12:00", "%Y/%m/%d %H:%M"), "未定", ], "配送": ["A社", "A社", "A社"], } ) # 全てを文字列型に変換 df1["発売日"] = df1["発売日"].apply(datetime_to_str) df1["配送"] = df1["配送"].apply(datetime_to_str) # あとはSpreadsheetを更新する処理 if __name__ == "__main__": main() ```