高效压缩/序列化/操作大量数据的方法

4
我有一个包含25,000个浮点数的文件(用,分隔),大约有100K这样的行。文件的一行看起来像这样:
1689.97,-9643.39,-82082.1,9776.09,-33974.84,-67247.38,32997.34,72811.53,31642.87,-949.6,9340.68,-85854.48,-17705.36,187.74,-3002.6,-35812.21,37382.32,22770.78,40893.09,45743.99,-6500.92,26243.85,13975.95,0,56669.47,-25865.36,-17066.78,26788.57,0,-36554.86,-3687.19,18933.93

我有两个问题:
  1. 是否有一种方法(在Java或Python中)可以高效地压缩数据,而不会对性能产生太大影响。压缩将每天进行一次,但数据必须经常读取。
  2. 可以在压缩形式下操作数据吗?例如,我想聚合前10行的前10列而无需解压缩。这样,我就不必担心频繁读取压缩数据。其中一个挑战是将25,000个字符串转换为浮点数进行加法运算。
我已经查看了gzip和zcat,它们是不错的选择。但我想找到一些压缩或序列化算法来通过Java/Python存储数据,并执行读取而不需要解压缩。

1
请看:https://dev59.com/_EXRa4cB1Zd3GeqPpi-n - David
文件必须是ASCII文件,或者您可以考虑使用二进制文件?浮点数是单精度还是双精度?如果它们是单精度,则最简单的方法可能是将浮点数的二进制表示存储在文件中。 - Bakuriu
对于撤销问题更改的人:1)标签不属于标题,因此“在Java中”不应在标题中提到。有一个标签(而且OP正在使用它)。另外,我给出的格式是正确的。 OP想要一个枚举列表,现在它已经有了,并且那个巨大的行必须绝对显示为代码。 - Bakuriu
@David:谢谢。我会看一下映射的字节缓冲区。 - Ashu
@Bakuriu:我考虑将它们存储为二进制。唯一的问题是当我需要读取时,我必须进行反序列化。希望有一种方法可以将其作为二进制读取并进行操作,然后将其转换回ASCII码。 - Ashu
3个回答

3

在Java中,您可以使用GZIPOutputStreamOutputStream包装起来,使用GZIPInputStreamInputStream包装起来,以便使用GZIP算法即时压缩/解压缩数据。


0
使用DataOutPutStream并使用writeFloat即可,无需使用逗号分隔符。

这并不意味着生成的文件会更小。浮点数可能需要占用8个字节来表示,如果ASCII表示较小,则文件大小可能会增加,或者可能会减少一小部分。 - Bakuriu
DataOutputStream out = <br>new DataOutputStream(new FileOutputStream("out.dat"));<br> // out.writeFloat(0F); // 4bytes<br> //out.writeChars("0,"); // 4 bytes<br> out.close();` <br> 最坏的情况下,大小相同。 - Edgard Leal
没有 0,两个 字节,因为它是 ASCII。另外,如果它们是双精度浮点数,则 12345.67 占用 8 个字节,这与其二进制表示相同。很有可能大小会减小,但这取决于浮点数在 ASCII 中的表示方式。此外,对 ASCII 文件进行 gzip 压缩可以将其大小减少一半,而二进制文件可能会被压缩更少(再次强调,并不保证最终的二进制表示会更小)。 - Bakuriu

0

你可以将它写成字节而不是文本。你需要将原始数据类型转换为字节数组,但我认为这并不难。我知道你可以使用Float.floatToRawIntBits()将其转换为int,使用Float.intBytesToFloat()从int返回。将int转换为byte[]只需要进行一些位移即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接