Pythonで文字列をgzip圧縮するにはどうすればよいですか?


86

Pythonで文字列をgzip圧縮するにはどうすればよいですか?

gzip.GzipFile 存在しますが、それはファイルオブジェクト用です-プレーンな文字列ではどうですか?


1
@KevinDTimm、そのドキュメントは言及しているだけで、StringIO実際にはその方法を説明していません。したがって、ここでその質問をすることは完全に有効です、私見。しかし、それらについて質問して私たちに話す前に、さらにいくつかの試行があれば良かったでしょう。
アルフェ2015年

@ Alfe-私のコメントとほぼ同じ理由で質問は4年前に閉じられました-OPは最初に検索する努力をしませんでした。
kevinDTimm 2015年

4
これはどのようにトピックから外れていますか?

2
この質問は現在グーグルでトップヒットでgzip string in pythonあり、非常に合理的なIMOです。再度開く必要があります。
ギャレット

2
上記のように、この質問はグーグル検索のトップの結果であり、答えの1つは正しいです-それは本当に閉じられるべきではないようです。
darkdan21 2018年

回答:


156

gzipヘッダーなどを使用gzip.GzipFileして完全に互換性のあるバイナリ文字列を生成する場合は、StringIO:と一緒に使用できます。

try:
    from StringIO import StringIO  # Python 2.7
except ImportError:
    from io import StringIO  # Python 3.x
import gzip
out = StringIO()
with gzip.GzipFile(fileobj=out, mode="w") as f:
  f.write("This is mike number one, isn't this a lot of fun?")
out.getvalue()

# returns '\x1f\x8b\x08\x00\xbd\xbe\xe8N\x02\xff\x0b\xc9\xc8,V\x00\xa2\xdc\xcc\xecT\x85\xbc\xd2\xdc\xa4\xd4"\x85\xfc\xbcT\x1d\xa0X\x9ez\x89B\tH:Q!\'\xbfD!?M!\xad4\xcf\x1e\x00w\xd4\xea\xf41\x00\x00\x00'

2
これの反対は次のとおりです。`defgunzip_text(text):infile = StringIO.StringIO()infile.write(text)with gzip.GzipFile(fileobj = infile、mode = "r")as f:f.rewind()f .read()return out.getvalue()
fastmultiplication 2014

3
@fastmultiplication:または短い:f = gzip.GzipFile(StringIO.StringIO(text)); result = f.read(); f.close(); return result
アルフェ

2
残念ながら、ご質問は、私は新しい答えをすることはできませんので、近くにあったが、している、ここではPython 3でこれを行う方法である
ギャレット

おそらく無関係ですが、最初にメモリでの圧縮が速くなりますか(ローカルディスクを使用)?
user3226167 2017

1
Python 3の場合:import zlib; my_string = "hello world"; my_bytes = zlib.compress(my_string.encode('utf-8')); my_hex = my_bytes.hex(); my_bytes2 = bytes.fromhex(my_hex); my_string2 = zlib.decompress(my_bytes); assert my_string == my_string2;
ostrokach 2017

64

最も簡単な方法はzlib エンコーディングです:

compressed_value = s.encode("zlib")

次に、次の方法で解凍します。

plain_string_again = compressed_value.decode("zlib")

1
@Daniel:はい、sタイプがPython2.xオブジェクトですstr
Sven Marnach 2012年

2
彼がそれを入手した場所については、標準エンコーディングを参照してください(「コーデック」までスクロールダウンします)。また利用可能:s.encode('rot13')s.encode( 'base64' )
bobobobo 2012

8
この方法は、gzipにヘッダーとチェックサムが含まれているという点でgzipコマンドラインユーティリティと互換性がないことに注意してください。このメカニズムは単にコンテンツを圧縮するだけです。
tylerl 2013

私は、これは古いです知っているが、解凍するためのコードのあなたの行は次のようになります plain_string_again = compressed_value.decode("zlib")
minillinim

6
@BenjaminToueg:Python 3は、Unicode文字列(strPython 3で入力)とバイト文字列(type bytes)の区別についてより厳密です。 strオブジェクトが持ってencode()返すメソッドbytes、オブジェクト、およびbytesオブジェクトが持ってdecode()返す方法strzlibそれから変換するにはコーデックが特別であるbytesbytes、それはこのような構造に適合しないので、。代わりに、オブジェクトにcodecs.encode(b, "zlib")andcodecs.decode(b, "slib")を使用できます。bytesb
Sven Marnach 2014年

22

Sven Marnachの2011年の回答のPython3バージョン:

import gzip
exampleString = 'abcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijmortenpunnerudengelstadrocksklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvabcdefghijklmnopqrstuv123'
compressed_value = gzip.compress(bytes(exampleString,'utf-8'))
plain_string_again  = gzip.decompress(compressed_value)

2
Python 3zlibではまだ使用されており、gzip実際に使用されていzlibます。docs.python.org / 3
library

私の最初の答えはzlibを使用することでした。元の質問だったのでgzipに変更しました。私の例では、gzipからzlib(検索と置換)に簡単に置き換えることができ、それは機能します。
Punnerud

2

PandasデータフレームをJSON形式で圧縮したい場合:

Python3.6とPandas0.23でテスト済み

import sys
import zlib, lzma, bz2
import math

def convert_size(size_bytes):
    if size_bytes == 0:
        return "0B"
    size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
    i = int(math.floor(math.log(size_bytes, 1024)))
    p = math.pow(1024, i)
    s = round(size_bytes / p, 2)
    return "%s %s" % (s, size_name[i])

dataframe = pd.read_csv('...') # your CSV file
dataframe_json = dataframe.to_json(orient='split')
data = dataframe_json.encode()
compressed_data = bz2.compress(data)
decompressed_data = bz2.decompress(compressed_data).decode()
dataframe_aux = pd.read_json(decompressed_data, orient='split')

#Original data size:  10982455 10.47 MB
#Encoded data size:  10982439 10.47 MB
#Compressed data size:  1276457 1.22 MB (lzma, slow), 2087131 1.99 MB (zlib, fast), 1410908 1.35 MB (bz2, fast)
#Decompressed data size:  10982455 10.47 MB
print('Original data size: ', sys.getsizeof(dataframe_json), convert_size(sys.getsizeof(dataframe_json)))
print('Encoded data size: ', sys.getsizeof(data), convert_size(sys.getsizeof(data)))
print('Compressed data size: ', sys.getsizeof(compressed_data), convert_size(sys.getsizeof(compressed_data)))
print('Decompressed data size: ', sys.getsizeof(decompressed_data), convert_size(sys.getsizeof(decompressed_data)))

print(dataframe.head())
print(dataframe_aux.head())

-4
s = "a long string of characters"

g = gzip.open('gzipfilename.gz', 'w', 5) # ('filename', 'read/write mode', compression level)
g.write(s)
g.close()

4
問題は、プロセス中に文字列をディスクに書き込まずに、メモリ内の文字列を圧縮することだったと思います。そうでなければあなたの答えは完全に正しいです。
アルフェ2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.