为什么使用独立的 bzip2 和 pandas to_csv(, compression='bz2') 函数之间的文件大小不同?

Why is there a difference in filesize between using standalone bzip2 and pandas to_csv(, compression='bz2') function?

我使用 pandas 写出一个 csv,并按如下方式应用 bzip2 压缩:

df.to_csv('/home/user/file.bz2', index=False, mode=writemode, header=header)

根据documentationto_csv从文件名推断需要使用bzip2方法压缩它。

这确保我的 ~100 MB CSV 变成~23 MB。

但是,如果我解压缩那个 bz2 文件,并且 运行 通过 bzip2 在我的 Mac 上生成的 csv 文件:

bzip2 /home/user/file

我得到一个约 7 MB 的文件!如果我在 Debian 上 运行 bzip2,我会得到相同的结果。

是什么导致了这种差异?

不确定这是否是您的情况,但 bzip2 确实支持不同级别的压缩,在速度和大小之间进行权衡,并且通过 pandas 选择的级别可能与CLI 工具的默认值。使用 bz2 库:

In [118]: df = pd.DataFrame(np.random.randint(0, 100, [100000,5]))

In [119]: len(df.to_csv(None))
Out[119]: 2138880

In [120]: len(bz2.compress(df.to_csv(None).encode('ascii'), compresslevel=1))
Out[120]: 702709

In [121]: len(bz2.compress(df.to_csv(None).encode('ascii'), compresslevel=9))
Out[121]: 730415

这个有点奇怪,因为压缩 9 通常应该更慢但更小,但它是我在这里生成的一个非常简单的数据集,所以它可能只是一个退化的案例。

原来这不是过时的pandas,而是我这边不正确的预期造成的。

我实际上是通过在一天中(准确地说是每分钟)附加到 csv 来创建数据集的,这样:

if first_data_of_the_day:
    df.to_csv('/home/user/file.bz2', index=False, mode='w', header=True)
else:
    df.to_csv('/home/user/file.bz2', index=False, mode='a', header=False)

这会产生大约 23 MB 的文件。

如果我在一天中将数据帧存储在内存中(或在 csv 中),并且最后只将一次写入压缩文件,我得到较小的 ~7 MB 文件,无论 pandas版本。