gpt4 book ai didi

python - `pandas to_json` 和 `read_json` 之间的文件大小差异较大

转载 作者:行者123 更新时间:2023-12-01 04:32:07 25 4
gpt4 key购买 nike

设置

这个问题的基础是我正在使用 celeryrabbitmq创建一个分布式 HDFStore 消息传递应用程序,该应用程序将把 pandas DataFrame 传递给分布式进程(然后写入 HDFStore)。因为 jsontask serialization protocols 之一celery 接受的 pandasto_json()read_json() 功能非常适合完成此任务。

所以我的应用程序:

  • 点击 API 并拉取 pandas.DataFrame
  • 使用 to_json() 序列化 DataFrame
  • 将序列化值传递给 celery 工作线程
  • 使用 celery.group 方法在另一侧重新创建 DataFrame

问题

我发现当我创建 HDFStore 时,它​​们比我只执行 for 循环并且没有序列化/反序列化对象(使用 json)时大 50 倍以上。因此,我将 celery 从中取出,并用一个非常简单的函数重新创建了它,从而重现了这种现象:

import numpy
import pandas
import random


def test_store_size(n_dfs, f_path):
wj_store = pandas.HDFStore(f_path + 'from_json.h5', mode = 'w')
nj_store = pandas.HDFStore(f_path + 'from_dfrm.h5', mode = 'w')

ticks = []

for i in numpy.arange(n_dfs):

tag = _rnd_letters(5)
print "working on " + str(i)

index = pandas.DatetimeIndex(
start = '01/01/2000',
periods = 1000,
freq = 'b'
)

df = pandas.DataFrame(
numpy.random.rand(len(index), 3),
columns = ['a', 'b', 'c'],
index = index
)

nj_store[tag] = df

stream = df.to_json(
orient = 'index',
date_format = 'iso',
)

#stream = df.to_json(orient = 'values')
wj_df = pandas.read_json(
stream,
typ = 'frame',
orient = 'index',
dtype = _dtype_cols(df)
)

#wj_df = pandas.read_json(stream, convert_dates = False, orient = 'values')
wj_store[tag] = wj_df

wj_store.close()
nj_store.close()

def _rnd_letters(n_letters):
"""Make random tags for the DataFrames"""
s = 'abcdefghijklmnopqrstuvwxyz'
return reduce(lambda x, y: x + y, [random.choice(s) for i in numpy.arange(n_letters)])

def _dtype_cols(df):
"""map the types for dytpes"""
cols = df.columns.tolist()
return dict([(col, numpy.float) for col in cols])

因此,如果您运行以下函数:

In [1]: test_store_size(n_dfs = 10, f_path = '/Users/benjamingross/Desktop/tq-')

以下是 HDFStore 之间的差异:

size-diff

所以 21.4 MB 比 365 KB 大 59 倍!!!我正在处理 1,000 个 DataFrame,因此我的硬盘驱动器上看起来很小的空间 (400MB) 原来是 24 GB,这现在是一个“大数据”问题(并且不应该是)。

任何帮助使用 to_jsonread_json 进行序列化以“表现”(即序列化前后大小相同)将不胜感激。

我尝试过的

我已经尝试了to_json/read_json中的所有不同参数,包括orient =values,它几乎有效,但随后我需要序列化索引,当 re-created in very creative ways仍然最终变为原始尺寸的 60 倍。

最佳答案

如果您回顾一下程序的输出,您可能会收到如下消息:

In [7]: wj_df.to_hdf('test.h5', 'key')
PerformanceWarning:
your performance may suffer as PyTables will pickle object types that it cannot
map directly to c-types [inferred_type->unicode,key->axis0] [items->None]

这不是特别明显,但是您的列名被读回为 unicode 而不是 python 字符串 - PyTables 在 python2 中不能很好地处理,因此它会退回到 pickling。一个相对简单的解决方法是将列转换为字符串,如下所示。

wj_df.columns = wj_df.columns.astype(str)

GitHub 上有一个针对以下问题的问题。

https://github.com/pydata/pandas/issues/5743

关于python - `pandas to_json` 和 `read_json` 之间的文件大小差异较大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32238554/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com