TLDR;的python中提供的各种压缩算法 gzip
,bz2
,lzma
,等,具有最佳的减压性能?
完整讨论:
Python 3 有各种用于压缩/解压缩数据的模块,
包括gzip
、bz2
和lzma
。gzip
并且bz2
还可以设置不同的压缩级别。
如果我的目标是平衡文件大小(/压缩比)和解压缩速度(压缩速度不是问题),哪个是最佳选择?解压缩速度比文件大小更重要,但由于有问题的未压缩文件每个大约 600-800MB(32 位 RGB .png 图像文件),而且我有十几个,我确实想要一些压缩。
我的用例是我从磁盘加载一打图像,对它们进行一些处理(作为一个 numpy 数组),然后在我的程序中使用处理过的数组数据。
pickle
)而不是每次加载原始的、未处理的图像来节省一些加载时间。最初的测试很有希望——加载原始/未压缩的腌制数据只需要不到一秒钟,而加载和处理原始图像则需要 3 或 4 秒——但如前所述导致文件大小约为 600-800MB,而原始 png 图像是只有大约 5MB。所以我希望通过以压缩格式存储选择的数据,我可以在加载时间和文件大小之间取得平衡。更新:情况实际上比我上面描述的要复杂一些。我的应用程序使用PySide2
,所以我可以访问这些Qt
库。
pillow
( PIL.Image
)转换为 numpy 数组,实际上我不需要做任何处理,但将图像读入数组的总时间约为 4 秒。QImage
读取图像,那么我必须对结果进行一些处理,以使其可用于我的程序的其余部分,因为QImage
加载数据的方式的字节序- 基本上我必须交换位顺序和然后旋转每个“像素”,使 alpha 通道(显然是由 QImage 添加的)出现在最后而不是第一个。这整个过程只需约3.8秒,所以稍微比只使用PIL更快。numpy
未压缩的数组,那么我可以在 0.8 …我通常使用.gz在Spark中读写文件,其中文件的数量应与RDD分区的数量相同.即一个巨大的.gz文件将读入单个分区.但是,如果我在一个单独的.bz2中读取,我还能获得一个单独的巨型分区吗?或者Spark会支持将.bz2自动拆分为多个分区吗?
另外,我如何知道Hadoop从一个bz2文件读取它时会有多少个分区.谢谢!
我有一个字符串:
'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
Run Code Online (Sandbox Code Playgroud)
而且我要:
b'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
Run Code Online (Sandbox Code Playgroud)
但我不断得到:
b'BZh91AY&SYA\\xaf\\x82\\r\\x00\\x00\\x01\\x01\\x80\\x02\\xc0\\x02\\x00 \\x00!\\x9ah3M\\x07<]\\xc9\\x14\\xe1BA\\x06\\xbe\\x084'
Run Code Online (Sandbox Code Playgroud)
语境
我从网页上刮下一个字符串并将其存储在变量中un
。现在我想用 BZip2 解压它:
bz2.decompress(un)
Run Code Online (Sandbox Code Playgroud)
但是,由于un
是一个str
对象,我收到此错误:
TypeError: a bytes-like object is required, not 'str'
Run Code Online (Sandbox Code Playgroud)
因此,我需要在un
不将单个反斜杠更改为转义反斜杠的情况下转换为类似字节的对象。
编辑1: 感谢您的所有帮助!@wim 我现在明白你的意思了,但我不知道如何从我的网页抓取方法中检索一个类似字节的对象:
r = requests.get('http://www.pythonchallenge.com/pc/def/integrity.html')
doc = html.fromstring(r.content)
comment = doc.xpath('//comment()')[0].text.split('\n')[1:3]
pattern = re.compile("[a-z]{2}: '(.+)'")
un = re.search(pattern, comment[0]).group(1)
Run Code Online (Sandbox Code Playgroud)
该包是我使用的是requests
,lxml.html
,re
,和bz2
。
再次,我的目标是解压un
使用bz2
,但我有困难,从我webscraping过程中得到一个字节状物体。
任何指针?
我试图从bz2文件中提取10'000个第一行.
import bz2
file = "file.bz2"
file_10000 = "file.txt"
output_file = codecs.open(file_10000,'w+','utf-8')
source_file = bz2.open(file, "r")
count = 0
for line in source_file:
count += 1
if count < 10000:
output_file.writerow(line)
Run Code Online (Sandbox Code Playgroud)
但我得到一个错误"'模块'对象没有属性'打开'".你有什么想法?或者可能是我可以用其他方式将10'000个第一行保存到txt文件中?我在Windows上.
该bz2
模块提供了open()
一种可以从中调用的标准方法readline()
。但是,我的情况是我有一个流(指向大量数据)想要动态解压缩行。我当前的实现如下,但是我知道必须有一种更简洁的方法来实现。
import bz2
import csv
BZ2_BUFFER = ''
BZ2_DECOMPRESSOR = None
BZ2_FILE = None
BZ2_READ_SIZE = 100 * 1024
def bz2_csv_rows(fp):
global BZ2_BUFFER, BZ2_DECOMPRESSOR, BZ2_FILE, BZ2_READ_SIZE
BZ2_BUFFER = ''
BZ2_DECOMPRESSOR = bz2.BZ2Decompressor()
BZ2_FILE = fp
for row in csv.reader(iter(bz2_line_reader, b'')):
yield row
def bz2_line_reader():
global BZ2_BUFFER, BZ2_DECOMPRESSOR, BZ2_FILE, BZ2_READ_SIZE
if BZ2_BUFFER is None:
return None
while '\n' not in BZ2_BUFFER:
bindata = BZ2_FILE.read(BZ2_READ_SIZE)
try:
data = BZ2_DECOMPRESSOR.decompress(bindata)
except EOFError:
break
except IOError:
pass
BZ2_BUFFER …
Run Code Online (Sandbox Code Playgroud) 我有一个 DNS 服务器,我想捕获 DNS 流量以获取使用我的 DNS 服务器的所有 IP。
为此,我开始使用以下tcpdump
命令并将它们捕获到文件中:
tcpdump -n -i eth0 dst port 53 >> dns_data.log
Run Code Online (Sandbox Code Playgroud)
但当我长时间运行时,文件大小会很大。我怎样才能将其捕获到压缩文件中?我尝试了下面的命令,但它不起作用。
tcpdump -n -i eth0 dst port 53 | bzip2 -c >> dns_data.bz2
Run Code Online (Sandbox Code Playgroud) 我使用此命令列出存档中的所有文件:
tar jtvf blah.tar.bz2
Run Code Online (Sandbox Code Playgroud)
如何列出它们按大小排序?还是仅列出最大的文件(即大于10MB的文件)?
有由 bz2 文件压缩的文本图块。文本文件中的数据如下所示。
1 x3, x32, f5
0 f4, g6, h7, j9
.............
Run Code Online (Sandbox Code Playgroud)
我知道如何通过以下代码加载文本文件
rf = open('small.txt', 'r')
lines = rf.readlines()
lst_text = []
lst_label = []
for line in lines:
line = line.rstrip('\n')
label, text = line.split('\t')
text_words = text.split(',')
lst_text.append(text_words)
lst_label.append(int(label))
Run Code Online (Sandbox Code Playgroud)
但是txt被压缩成small.txt.bz2文件后。我想用下面的数据读取bz2文件,但是有错误。
import bz2
bz_file = bz2.BZ2File("small.txt.bz2")
lines = bz_file.readlines()
for line in lines:
line = line.rstrip('\n')
label, text = line.split('\t')
text_words = text.split(',')
print(label)
Run Code Online (Sandbox Code Playgroud)
错误:
line = line.rstrip('\n')
TypeError: a bytes-like object is required, not 'str'
Run Code Online (Sandbox Code Playgroud)
你能给我提示如何处理它,代码是最好的。谢谢!
>>> import bz2
>>> bz2.compress('hi')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/ryan/anaconda/lib/python3.4/bz2.py", line 498, in compress
return comp.compress(data) + comp.flush()
TypeError: 'str' does not support the buffer interface
Run Code Online (Sandbox Code Playgroud)
我看过使用字符串作为输入的示例,但对我来说不起作用
我最近发现了这个解决方案,可以根据可用的内核并行压缩 gz 文件。
find . -name "*.gz" | xargs -n 1 -P 3 zgrep -H '{pattern to search}'
Run Code Online (Sandbox Code Playgroud)
PS 3 是核心数
我想知道是否也有办法对 bz2 文件执行此操作。目前我正在使用这个命令:
find -type f -name '*.bz2' -execdir bzgrep "{text to find}" {} /dev/null \;
Run Code Online (Sandbox Code Playgroud) bz2 ×11
python ×6
python-3.x ×3
gzip ×2
apache-spark ×1
archive ×1
bzip2 ×1
compression ×1
csv ×1
grep ×1
json ×1
linux ×1
lxml ×1
lxml.html ×1
lzma ×1
performance ×1
python-2.7 ×1
rdd ×1
sorting ×1
tar ×1
tcpdump ×1
unix ×1
wikidata ×1