详解Python如何实现压缩与解压缩数据

 更新时间:2024年02月25日 10:05:31   作者:古明地觉的编程教室  
当数据量大的时候,自然而然想到的就是对数据进行压缩,这篇文章主要为大家介绍了Python可以实现压缩与解压缩数据的相关模块的使用,希望对大家有所帮助

楔子

当数据量大的时候,自然而然想到的就是对数据进行压缩,下面来看看 Python 如何压缩数据。这里主要介绍三个模块,分别是 zlib、bz2、gzip,它们都是内置的,直接导入即可,不需要额外安装。

那么下面就开始吧。

zlib 模块

看一下 zlib 模块的用法。

import zlib

original_data = b"komeiji satori is a cute girl"
print(len(original_data))
"""
29
"""

# 对数据进行压缩
compressed_data = zlib.compress(original_data)
print(len(compressed_data))
"""
37
"""
# 我们看到当数据量很小的时候,压缩之后反而会增大


# 对数据进行解压
print(
    zlib.decompress(compressed_data) == original_data
)
"""
True
"""

在压缩的时候还可以指定压缩级别:

import zlib

original_data = b"komeiji satori is a cute girl" * 1024

# 压缩级别 0 ~ 9,值越大,压缩级别越高,默认压缩级别为 6
for i in range(0, 10):
    compressed_data = zlib.compress(original_data, i)
    print(f"压缩前数据长度: {len(original_data)}, "
          f"压缩后数据长度: {len(compressed_data)}")
"""
压缩前数据长度: 29696, 压缩后数据长度: 29707
压缩前数据长度: 29696, 压缩后数据长度: 245
压缩前数据长度: 29696, 压缩后数据长度: 245
压缩前数据长度: 29696, 压缩后数据长度: 245
压缩前数据长度: 29696, 压缩后数据长度: 122
压缩前数据长度: 29696, 压缩后数据长度: 122
压缩前数据长度: 29696, 压缩后数据长度: 122
压缩前数据长度: 29696, 压缩后数据长度: 122
压缩前数据长度: 29696, 压缩后数据长度: 122
压缩前数据长度: 29696, 压缩后数据长度: 122
"""

压缩级别越高,速度越慢,但压缩之后的数据体积也越小。

如果你要压缩的数据过大,那么还可以采用增量压缩。

from io import BytesIO
import zlib

# 用 buffer 模拟大文件
original_data = b"komeiji satori is a cute girl" * 1024
buffer = BytesIO()
buffer.write(original_data)
buffer.seek(0)

# 创建压缩器,压缩等级为 5
compressor = zlib.compressobj(5)
# 每次读取 1024 字节,进行压缩
while (data := buffer.read(1024)) != b"":
    compressor.compress(data)
# 循环结束之后,压缩结束,调用 flush 方法拿到压缩数据
compressed_data = compressor.flush()

# 这里我们进行解压,然后对比一下,看看和原始数据是否相等
# 注意:zlib 压缩之后是有一个头部信息的,否则会认为数据不是 zlib 压缩格式
# 但是增量压缩会将头部信息给去掉,所以解压的时候还要手动加上
# 这个头部信息是 b"x\x9c",转成十六进制就是 "789c"
decompressed_data = zlib.decompress(b"x\x9c" + compressed_data)
print(original_data == decompressed_data) 
"""
True
"""

压缩数据还可以和原始数据混在一起,举个例子:

import zlib

original_data = b"komeiji satori is a cute girl" * 1024
compressed_data = zlib.compress(original_data)
combined_data = compressed_data + original_data
# 创建一个解压缩器
decompressor = zlib.decompressobj()
# 对 combined_data 进行解压,只会得到对 compressed_data 解压之后的数据
# 由于 zlib 会在压缩数据前面加上一个头部信息,所以 combined_data 要求必须是压缩数据在前
decompressed_data = decompressor.decompress(combined_data)
# 和原始数据是相等的
print(decompressed_data == original_data)
"""
True
"""
# 还可以拿到未解压的数据,显然也是原始数据
print(decompressor.unused_data == original_data)
"""
True
"""

当然,zlib 还支持验证数据完整性。

import zlib

original_data = b"komeiji satori is a cute girl" * 1024
# 计算 Adler-32 校验和
print(zlib.adler32(original_data))
"""
4170046071
"""
# 计算 CRC-32 校验和
print(zlib.crc32(original_data))
"""
2627291461
"""

以上就是 zlib 模块的用法。

bz2 模块

bz2 模块和 zlib 的用法非常类似:

import bz2

original_data = b"komeiji satori is a cute girl" * 1024
# 也可以指定压缩等级,范围 1 ~ 9,注意:zlib 是 0 ~ 9
compressed_data = bz2.compress(original_data, 5)
print(len(original_data))
"""
29696
"""
print(len(compressed_data))
"""
103
"""
print(bz2.decompress(compressed_data) == original_data)
"""
True
"""

也可以增量压缩:

from io import BytesIO
import bz2

original_data = b"komeiji satori is a cute girl" * 1024
buffer = BytesIO()
buffer.write(original_data)
buffer.seek(0)

# 创建压缩器,压缩等级为 5
compressor = bz2.BZ2Compressor(5)
while (data := buffer.read(1024)) != b"":
    compressor.compress(data)
compressed_data = compressor.flush()
# 这里不需要额外补充头部信息
decompressed_data = bz2.decompress(compressed_data)
print(original_data == decompressed_data)
"""
True
"""

也可以同时包含压缩数据和未压缩数据:

import bz2

original_data = b"komeiji satori is a cute girl" * 1024
compressed_data = bz2.compress(original_data)
combined_data = compressed_data + original_data
# 创建一个解压缩器
decompressor = bz2.BZ2Decompressor()
decompressed_data = decompressor.decompress(combined_data)
# 和原始数据是相等的
print(decompressed_data == original_data)  # True
# 还可以拿到未解压的数据,显然也是原始数据
print(decompressor.unused_data == original_data)  # True
# 同样要求压缩数据在前

相比 zlib,bz2 还可以读写文件:

import os
import bz2

original_data = b"komeiji satori is a cute girl" * 1024
# 写入文件
with bz2.open("1.bz2", "wb", compresslevel=9) as f:
    f.write(original_data)
# 读取文件,判断两者是否相等
with bz2.open("1.bz2", "rb", compresslevel=9) as f:
    print(f.read() == original_data)  # True

os.unlink("1.bz2")

当然我们使用内置函数 open 打开文件,然后手动写入压缩数据或者读取数据再手动解压,也是可以的。

gzip 模块

首先 gzip 只有全量压缩,没有增量压缩。

import gzip

original_data = b"komeiji satori is a cute girl" * 1024
# 也可以指定压缩等级,范围 0 ~ 9
compressed_data = gzip.compress(original_data, 5)
print(len(original_data)) 
"""
29696
"""
print(len(compressed_data)) 
"""
134
"""
print(gzip.decompress(compressed_data) == original_data)  
"""
True
"""

还可以调用 gzip.open 函数:

import os
import gzip

original_data = b"komeiji satori is a cute girl" * 1024
# 写入文件
with gzip.open("1.gz", "wb", compresslevel=9) as f:
    f.write(original_data)
# 读取文件,判断两者是否相等
with gzip.open("1.gz", "rb", compresslevel=9) as f:
    print(f.read() == original_data)  #
    """
    True
    """

os.unlink("1.gz")

小结

以上就是 Python 压缩数据所使用的三个模块,之间是比较相似的。另外再补充一点,一般将数据压缩之后,会转成 16 进制进行传输,举个例子:

import binascii
import gzip

original_data = b"komeiji satori"
compressed_data = gzip.compress(original_data, 5)
# 转成 16 进制
hex_data = binascii.hexlify(compressed_data)
print(
    binascii.unhexlify(hex_data) == compressed_data
)  # True

还是比较简单的。

以上就是详解Python如何实现压缩与解压缩数据的详细内容,更多关于Python压缩与解压缩数据的资料请关注脚本之家其它相关文章!

相关文章

  • python基于tkinter制作下班倒计时工具

    python基于tkinter制作下班倒计时工具

    这篇文章主要介绍了python基于tkinter制作倒计时工具的方法,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-04-04
  • 利用Python将多张图片合成视频的实现

    利用Python将多张图片合成视频的实现

    这篇文章主要介绍了利用Python将多张图片合成视频的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Python数据分析matplotlib设置多个子图的间距方法

    Python数据分析matplotlib设置多个子图的间距方法

    今天小编就为大家分享一篇Python数据分析matplotlib设置多个子图的间距方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • Python实现基于KNN算法的笔迹识别功能详解

    Python实现基于KNN算法的笔迹识别功能详解

    这篇文章主要介绍了Python实现基于KNN算法的笔迹识别功能,结合实例形式详细分析了使用KNN算法进行笔迹识别的相关库引入、操作步骤与相关注意事项,需要的朋友可以参考下
    2018-07-07
  • 有关Tensorflow梯度下降常用的优化方法分享

    有关Tensorflow梯度下降常用的优化方法分享

    今天小编就为大家分享一篇有关Tensorflow梯度下降常用的优化方法分享,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • 基于Python写一个番茄钟小工具

    基于Python写一个番茄钟小工具

    最近听到朋友说在用番茄钟,有点兴趣也想下载一个来用用,后面仔细一想这玩意做起来也不难,索性自己顺手写一个算了,在这里也分享给大家了
    2022-12-12
  • Python中的哈希算法模块hashlib详解

    Python中的哈希算法模块hashlib详解

    这篇文章主要介绍了Python中的哈希算法模块hashlib详解,hashlib模块实现了多种哈希算法,包括MD5以及SHA家族的算法,通过algorithms_guaranteed可以查看hashlib中封装的所有算法,需要的朋友可以参考下
    2023-08-08
  • Python+pyaudio实现音频控制示例详解

    Python+pyaudio实现音频控制示例详解

    PyAudio 是语音处理的 Python 库,提供了比较丰富的功能。本文将利用pyaudio控制指定设备,实现录制音频、采集音频流、播放音频,感兴趣的可以了解一下
    2022-07-07
  • Django中reverse反转并且传递参数的方法

    Django中reverse反转并且传递参数的方法

    今天小编就为大家分享一篇Django中reverse反转并且传递参数的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • Python的进制转换和ASCLL转换你了解吗

    Python的进制转换和ASCLL转换你了解吗

    这篇文章主要为大家详细介绍了Python的进制转换和ASCLL转换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02

最新评论