pandas数据框架的yaml转储。

问题描述 投票:0回答:1

我想我应该分享一下,因为我在SO上搜索了一下,却没有找到我需要的东西。

我想甩一个 pd.DataFrame 到一个yaml文件中。

Timestamps 应该很好地显示出来,而不是像默认的那样。

  date: !!python/object/apply:pandas._libs.tslibs.timestamps.Timestamp
  - 1589241600000000000
  - null
  - null

另外,输出应该是正确的YaML格式,也就是说,它应该是可读的。yaml.load. 输出的数据应该相当简洁,即喜欢 "flow "格式。

作为一个例子,这里有一些数据。

df = pd.DataFrame([
    dict(
        date=pd.Timestamp.now().normalize() - pd.Timedelta('1 day'),
        x=0,
        b='foo',
        c=[1,2,3,4],
        other_t=pd.Timestamp.now(),
    ),
    dict(
        date=pd.Timestamp.now().normalize(),
        x=1,
        b='bar',
        c=list(range(32)),
        other_t=pd.Timestamp.now(),
    ),
]).set_index('date')
pandas pyyaml
1个回答
1
投票

这是我想出的办法。它有一些自定义的 Dumper 办理 Timestamp. 输出的结果更加清晰,而且还是有效的 yaml。加载后,yaml会识别有效的日期时间格式(我想是ISO格式),并将这些格式重新创建为 datetime. 事实上,我们可以把它读回一个 DataFrame其中,这些 datetime自动转换为 Timestamp. 在对指数进行小幅重设后,我们观察到,新的 df 与原来的相同。

import yaml
from yaml import CDumper
from yaml.representer import SafeRepresenter
import datetime


class TSDumper(CDumper):
    pass

def timestamp_representer(dumper, data):
    return SafeRepresenter.represent_datetime(dumper, data.to_pydatetime())

TSDumper.add_representer(datetime.datetime, SafeRepresenter.represent_datetime)
TSDumper.add_representer(pd.Timestamp, timestamp_representer)

有了这个,现在我们可以做。

text = yaml.dump(
    df.reset_index().to_dict(orient='records'),
    sort_keys=False, width=72, indent=4,
    default_flow_style=None, Dumper=TSDumper,
)
print(text)

输出比较干净。

-   date: 2020-05-12 00:00:00
    x: 0
    b: foo
    c: [1, 2, 3, 4]
    other_t: 2020-05-13 02:30:23.422589
-   date: 2020-05-13 00:00:00
    x: 1
    b: bar
    c: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
        19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
    other_t: 2020-05-13 02:30:23.422613

现在,我们可以把它装回去

df2 = pd.DataFrame(yaml.load(text, Loader=yaml.SafeLoader)).set_index('date')

现在,我们可以把这个装回去:

df2.equals(df)
# True
© www.soinside.com 2019 - 2024. All rights reserved.