Period 类型的对象在 plotly 中不是 JSON 可序列化的

Rag*_* Kr 7 pandas plotly

我正在尝试绘制折线图。下面是我的代码

代码 :

import plotly.offline as pyo
import plotly.graph_objects as go
flag = determineFlag('2020-03-01','2020-03-30')

df_r = getDataForTrend(df,'2020-03-01','2020-03-30','d')

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}



data = [go.Scatter(x = df_r[df_r['S2PName-Category']==category]['S2BillDate'],
                    y = df_r[df_r['S2PName-Category']==category]['totSale'],
                    mode = 'lines',
                    name = category) for category in df_r['S2PName-Category'].unique()]


layout = {'title':'Category Trend',
         'xaxis':{'title':'Time Frame'},
         'yaxis':{'title':'Total Sales Amount','tickformat' : '.2f'}}

fig = go.Figure(data=data,layout=layout)

pyo.iplot(fig)
Run Code Online (Sandbox Code Playgroud)

当我运行上面的代码时,出现以下错误:

错误:

TypeError: Object of type Period is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

在调试时,我尝试执行以下代码

调试代码:

df_r[df_r['S2PName-Category']==category]['S2BillDate']
Run Code Online (Sandbox Code Playgroud)

操作:

3     2020-03-01
11    2020-03-02
21    2020-03-03
26    2020-03-04
41    2020-03-06
42    2020-03-05
46    2020-03-07
Name: S2BillDate, dtype: period[D]
Run Code Online (Sandbox Code Playgroud)

如何修复类型错误?对此有任何调整吗?任何帮助深表感谢!谢谢 !

Ner*_*xis 8

AFAIK 这仍然是一个问题,并且在这种情况下会失败。github 上仍然存在一个未解决的问题:Support for Pandas Time spans as index col

正如评论中提出的,解决方案之一是使用to_timestatmp转换,请参阅

  1. 创建 MWE(这只是为了重现性,因为问题中没有提供数据)
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.offline as pyo

df = pd.DataFrame({"one": np.random.random(10)}, index=pd.period_range("2020-03-01", freq="M", periods=10))
# Out:
#               one
# 2020-03  0.302359
# 2020-04  0.919923
# 2020-05  0.673808
# 2020-06  0.718974
# 2020-07  0.754675
# 2020-08  0.731673
# 2020-09  0.772382
# 2020-10  0.654555
# 2020-11  0.549314
# 2020-12  0.101696

data = [
    go.Scatter(
        x=df.index,
        y=df["one"],
    )
]
fig = go.Figure(data=data)
pyo.iplot(fig)
# -> will fail ("TypeError: Object of type Period is not JSON serializable")
Run Code Online (Sandbox Code Playgroud)
  1. 使用to_timestamp转换 (-> df.index.to_timestamp())
data = [
    go.Scatter(
        x=df.index.to_timestamp(), # period to datetime conversion
        y=df["one"],
    )
]
fig = go.Figure(data=data)
pyo.iplot(fig)

Run Code Online (Sandbox Code Playgroud)

或者,如果您不需要日期时间格式,也可以将其转换为字符串:

data = [
    go.Scatter(
        x=df.index.strftime("%Y-%m"),  # You can define your own format
        y=df["one"],
    )
]
fig = go.Figure(data=data)
pyo.iplot(fig)
Run Code Online (Sandbox Code Playgroud)

您当然可以直接在原始数据帧上执行此转换(因此您不需要在内部迭代执行此转换go.Scatter),但这只是小事。Period可能还有一种使用自定义编码器而不是默认编码器的方法,但我认为这不值得尝试,而且据我所知,没有比使用从todatetime或的可能转换之一更好的解决方案了string