往返于 json 的 Pandas 时间戳

Posted

技术标签:

【中文标题】往返于 json 的 Pandas 时间戳【英文标题】:Pandas timestamp to and from json 【发布时间】:2019-08-07 21:08:51 【问题描述】:

对象无法序列化为 json,因此需要通过自定义的 JsonEncoder 类进行转换或解析。

pandas Dataframe 有很多方法,比如from_records 来读取 json 数据。然而,当您读取该 json 数据时,它会以 int64 而不是时间戳返回。

在 pandas 中有很多方法可以给猫剥皮。读取和写入 json 时保存数据结构的最佳方法是什么?

【问题讨论】:

Pandas 不是通用的 json 解码器。它只能(正确地)处理特定格式的 json 文件,并且在处理深度嵌套的 json 文件时被认为是不好的。恕我直言,您当前的问题是不清楚 @SergeBallesta 问题是,pandas 出于某种原因在将数据与 json 相互转换方面做了一些修改。尝试从 pandas df 写入 json 包含 pd.Timestamp 对象的内容,然后将其读回 df。你会有两个不同的对象 【参考方案1】:

为了它的价值,我将 pandas 数据帧保存到 Postgres 数据库,并且我想保留时区索引。我使用以下代码:

class db_JsonEncodedDataFrameWithTimezone(db.TypeDecorator):
    """Enables JSON storage by encoding and decoding on the fly."""
    impl = db.Text

    def process_bind_param(self, value, dialect):
        if value is not None and isinstance(value, pd.DataFrame):
            timezone = value.index.tz.zone
            df_json = value.to_json(orient="index")
            data = 'timezone': timezone, 'df': df_json, 'index_name': value.index.name
            value = json.dumps(data)
        return value

    def process_result_value(self, value, dialect):
        if value is not None:
            data = json.loads(value)
            df = pd.read_json(data['df'], orient="index")
            df.index = df.index.tz_localize('UTC')
            df.index = df.index.tz_convert(data['timezone'])
            df.index.name = data['index_name']
            value = df
        return value

    def compare_values(self, x, y):
        from pandas.util.testing import assert_frame_equal
        try:
            assert_frame_equal(x, y, check_names=True, check_like=True)
            return True
        except (AssertionError, ValueError, TypeError):
            return False

【讨论】:

似乎 json 不是序列化时间戳或其他对象的那个。感谢您的选择!【参考方案2】:

如果我正确理解了您的问题,那么您正在寻找一种保留数据帧数据类型的序列化方式。

问题在于 interchange 格式在内部使用了几种类型:csv 仅使用字符串,json 仅使用字符串和数字。当然,有一些方法可以在读取时提供格式提示(csv 中日期列的日期格式),并且通常很容易在提取后转换回正确的类型,我认为您希望更自然 方式。正如 Attack68 所建议的,您可以使用数据库,但例如 SQLite 数据库将被关闭,因为它没有内部日期类型。

恕我直言,一个简单的方法是依赖旧的 pickle 模块。毕竟,数据框是一个包含其他 Python 对象的 Python 对象,所以 pickle 擅长序列化它。唯一要记住的是,在反序列化时,必须先导入 pandas,然后再调用 pickle.load

但我刚刚测试了一个包含各种数据类型的(小)数据框,pickle 非常适合正确保存和恢复它们。

【讨论】:

以上是关于往返于 json 的 Pandas 时间戳的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 时间戳字符串转换为 pandas 数据框中的 python 日期

将一列时间戳转换为 pandas 中的句点

时间戳字符串(Unix 时间)到 datetime 或 pandas.Timestamp

Pandas 将多个数据帧与时间戳索引对齐

Pandas:如何添加两个时间戳值?

无法转换 Pandas 数据帧时间戳