Hướng dẫn does python pickle compress data? - python có nén dữ liệu không?

Chỉ cần thêm một giải pháp thay thế dễ dàng cung cấp cho tôi tỷ lệ nén cao nhất và trên hết đã làm điều đó nhanh đến mức tôi chắc chắn rằng tôi đã phạm sai lầm ở đâu đó (tôi đã không). Phần thưởng thực sự là việc giải nén cũng rất nhanh, vì vậy, bất kỳ chương trình nào đọc trong nhiều dữ liệu được xử lý trước, chẳng hạn, sẽ được hưởng lợi rất nhiều từ điều này. Một cảnh báo tiềm năng là có đề cập đến "các mảng nhỏ (

Một số cookie thông minh đã đưa ra Python-Blosc. Đó là một "máy nén hiệu suất cao", theo tài liệu của họ. Tôi đã dẫn đến nó từ một câu trả lời cho câu hỏi này.

Sau khi được cài đặt thông qua, ví dụ:

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
0 hoặc
with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
1, bạn có thể nén dữ liệu ngâm khá dễ dàng như sau:

import blosc
import numpy as np
import pickle

data = np.random.rand(3, 3, 1e7)

pickled_data = pickle.dumps(data)  # returns data as a bytes object
compressed_pickle = blosc.compress(pickled_data)

with open("path/to/file/test.dat", "wb") as f:
    f.write(compressed_pickle)

Và để đọc nó:

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data

Tôi đang sử dụng Python 3.7 và thậm chí không nhìn vào tất cả các tùy chọn nén khác nhau, tôi có tỷ lệ nén khoảng 12 và đọc + giải nén + tải tệp dưa chuột nén mất một phần nhỏ hơn một phần thứ hai so với tải tệp dưa chua không nén.

Tôi đã viết điều này nhiều hơn như một tài liệu tham khảo cho chính mình, nhưng tôi hy vọng người khác sẽ thấy điều này hữu ích.

Hòa bình oot

Pickle là một thư viện tuần tự hóa mạnh mẽ trong Python, có khả năng tuần tự hóa các đối tượng (pickling) cho các tệp để sử dụng sau. Thông thường khi làm việc với các bộ dữ liệu lớn, kích thước của các tệp này có thể khá lớn. Điều này cũng làm chậm việc tải và đổ dữ liệu, khiến bạn phải chờ đợi lâu hơn. Để giải quyết vấn đề này, chúng tôi nén các kết xuất tệp Pickle của chúng tôi, giúp giảm đáng kể kích thước.

Trong hướng dẫn này, chúng tôi sẽ sử dụng thư viện nén BZ2. Ngoài ra còn có thư viện GZIP nhanh hơn một chút, nhưng không tốt khi giảm kích thước tệp.


Nén dữ liệu

Trước tiên, hãy để một cái nhìn vào dữ liệu mà chúng ta sẽ bỏ vào một tệp.

Chúng tôi đã đưa ra một đoạn mã tốt tạo ra 1000 đối tượng từ lớp tùy chỉnh của chúng tôi. Để đưa một số chủ nghĩa hiện thực vào mã của chúng tôi, tôi cũng đã sử dụng thư viện ngẫu nhiên để thêm một số loại vào dữ liệu của các đối tượng sinh viên bằng cách chọn một kết hợp ngẫu nhiên giữa tên và giới tính.

# Data to be Compresssed
import pickle
import bz2
import random
import os

class Student:
    def __init__(self, ID, Name, Gender):
        self.ID = ID
        self.Name = Name
        self.Gender = Gender

    def display(self):
        print("Name:", self.Name,
              "ID:", self.ID,
              "Gender:", self.Gender)

data = []
names = ["Bob", "Rob", "Sam", "Jane", "Sally", "John", "Emilia"]
genders = ["M", "F", "O"]

for x in range(1000):
    data.append(Student(x, random.choice(names), random.choice(genders)))

Bây giờ chúng tôi có danh sách của chúng tôi có tên là Dữ liệu, có 1000 đối tượng sinh viên. Hãy cùng thử bỏ việc đổ nó vào một tập tin và xem điều gì sẽ xảy ra.

# Writing data normally to a file (pickle)

ofile = open("BinaryData",'wb')
pickle.dump(data, ofile)
ofile.close()

print(os.path.getsize("BinaryData"))  # Return file size

Mã trên trả về đầu ra sau:

30155

Nén dữ liệu tệp pickle

Bây giờ, hãy để chúng tôi thấy chúng tôi có thể nén tệp đó bằng cách sử dụng

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
2 bao nhiêu. Chúng tôi sẽ thực hiện một quy trình tương tự một lần nữa, nhưng lần này thông qua các chức năng
with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
3S.

Về cơ bản, tất cả những gì chúng ta phải làm, là sử dụng lớp

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
4, thay vì hàm
with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
5 tiêu chuẩn được thấy trong xử lý tệp thông thường. Tương tự như vậy, bạn cũng có thể sử dụng hàm
with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
6, sẽ cung cấp hiệu ứng nén tương tự.

Đối với phần mềm, tham số đầu tiên là FilePath hoặc FileName, và thứ hai là chế độ mà nó đã mở. Vì chúng tôi đang xử lý dữ liệu nhị phân, chúng tôi cần sử dụng WB WB.

# Compressing Data

ofile = bz2.BZ2File("BinaryData",'wb')
pickle.dump(data,ofile)
ofile.close()

print(os.path.getsize("BinaryData"))

Ở đây, kích thước tệp mới, mà chúng tôi thu được bằng cách sử dụng hàm

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
7 từ thư viện HĐH.

5653

Nói chung, chúng tôi đã quan sát thấy một cải tiến 5X đẹp so với kích thước tệp Pickle ban đầu. Và tất cả chỉ cần thêm vào một vài dòng mã. Trong phần tiếp theo, chúng tôi sẽ khám phá cách đọc nội dung này trở lại Python để chúng tôi có thể sử dụng nó.

Kiểm tra hướng dẫn BZ2 để biết các cách nén dữ liệu thay thế hoặc hướng dẫn GZIP để nén nhanh hơn!


Giải nén dữ liệu dưa chua trong python

Giải nén dữ liệu tệp Pickle Python khá dễ dàng và có thể được thực hiện theo hai cách. Phương thức đầu tiên được hiển thị bên dưới, trong đó chúng tôi sử dụng phương thức

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
8 để trả về một đối tượng luồng tệp.

Giống như trước đây, cú pháp là như nhau, trong đó tham số đầu tiên là tên tệp (sử dụng filepath nếu trong một thư mục khác) và tham số thứ hai là RB RB để đọc các tệp nhị phân.

Khi chúng tôi đã sẵn sàng đối tượng BZ2File của mình, chúng tôi chỉ cần chuyển nó vào

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
9, lấy một đối tượng luồng tệp làm tham số.
with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
9 sẽ trả lại dữ liệu ngâm trong cùng một hình thức khi nó được bỏ.

# Reading the compressed data 

ifile = bz2.BZ2File("BinaryData4",'rb')
newdata = pickle.load(ifile)
ifile.close()

for x in newdata:
    x.display()

Dưới đây là 6 kết quả đầu tiên từ đầu ra của mã trên.

Name: Sally ID: 0 Gender: O
Name: Emilia ID: 1 Gender: F
Name: Sam ID: 2 Gender: M
Name: Sam ID: 3 Gender: O
Name: Bob ID: 4 Gender: O
Name: Rob ID: 5 Gender: F

Phương pháp luân phiên

Đây là một phương pháp đọc dữ liệu thay thế.

Thay vì chuyển một đối tượng luồng tệp cho

with open("path/to/file/test.dat", "rb") as f:
    compressed_pickle = f.read()

depressed_pickle = blosc.decompress(compressed_pickle)
data = pickle.loads(depressed_pickle)  # turn bytes object back into data
9, chúng ta có thể chọn chuyển dữ liệu ngâm dưới dạng chuỗi sang
# Data to be Compresssed
import pickle
import bz2
import random
import os

class Student:
    def __init__(self, ID, Name, Gender):
        self.ID = ID
        self.Name = Name
        self.Gender = Gender

    def display(self):
        print("Name:", self.Name,
              "ID:", self.ID,
              "Gender:", self.Gender)

data = []
names = ["Bob", "Rob", "Sam", "Jane", "Sally", "John", "Emilia"]
genders = ["M", "F", "O"]

for x in range(1000):
    data.append(Student(x, random.choice(names), random.choice(genders)))
2. Tất nhiên, chúng tôi sẽ phải giải nén nó trước (hoặc pickle won nhận ra nó) bằng cách sử dụng hàm
# Data to be Compresssed
import pickle
import bz2
import random
import os

class Student:
    def __init__(self, ID, Name, Gender):
        self.ID = ID
        self.Name = Name
        self.Gender = Gender

    def display(self):
        print("Name:", self.Name,
              "ID:", self.ID,
              "Gender:", self.Gender)

data = []
names = ["Bob", "Rob", "Sam", "Jane", "Sally", "John", "Emilia"]
genders = ["M", "F", "O"]

for x in range(1000):
    data.append(Student(x, random.choice(names), random.choice(genders)))
3, lấy dữ liệu chuỗi. Và chúng tôi sẽ phải sử dụng chức năng
# Data to be Compresssed
import pickle
import bz2
import random
import os

class Student:
    def __init__(self, ID, Name, Gender):
        self.ID = ID
        self.Name = Name
        self.Gender = Gender

    def display(self):
        print("Name:", self.Name,
              "ID:", self.ID,
              "Gender:", self.Gender)

data = []
names = ["Bob", "Rob", "Sam", "Jane", "Sally", "John", "Emilia"]
genders = ["M", "F", "O"]

for x in range(1000):
    data.append(Student(x, random.choice(names), random.choice(genders)))
4 trên đối tượng luồng tệp.

Nhìn chung, nó rất nhiều phương pháp được sử dụng, nhưng nó chỉ là một chương trình giới thiệu thú vị và một cách xử lý mọi thứ thay thế.

# Reading the compressed data

ifile = open("BinaryData",'rb')
newdata = pickle.loads(bz2.decompress(ifile.read()))
ifile.close()

for x in newdata:
    x.display()

Và tất nhiên, đầu ra của mã trên sẽ giống như mã trước.


Điều này đánh dấu sự kết thúc của Hướng dẫn nén tệp Python Pickle. Bất kỳ đề xuất hoặc đóng góp cho Coderslegacy đều được chào đón nhiều hơn. Các câu hỏi liên quan đến nội dung hướng dẫn có thể được hỏi trong phần bình luận bên dưới.

Các tệp Python Pickle có được nén không?

Từ tài liệu Python: Theo mặc định, định dạng dữ liệu Pickle sử dụng biểu diễn nhị phân tương đối nhỏ gọn. Nếu bạn cần các đặc điểm kích thước tối ưu, bạn có thể nén dữ liệu ngâm một cách hiệu quả.you can efficiently compress pickled data.

Pickle có nhỏ hơn JSON không?

Pickle là chất kém rõ ràng ở đây.Ngay cả phần mở rộng 'CPickle' được viết bằng C cũng có tỷ lệ tuần tự khoảng một phần tư so với JSON hoặc Thrift.Pickle cũng tạo ra các giá trị nối tiếp có kích thước gấp đôi kích thước của Thrift hoặc MessagePack.about a quarter that of JSON or Thrift. Pickle also produces serialized values that are around double the size of Thrift or MessagePack.

Pickle có đóng tệp không?

Sau đó, bạn mở tệp Pickle để đọc, tải nội dung vào một biến mới và đóng tệp.Tải được thực hiện thông qua dưa chua.close up the file. Loading is done through the pickle.

Tệp Pickle có nhỏ hơn CSV không?

Các tệp CSV đã chiếm khoảng cùng một không gian, khoảng 40 MB, nhưng tệp Pickle nén chỉ chiếm 1,5 MB.Đó là rất nhiều không gian lưu.Một sự khác biệt lớn khác là trong thời gian tải.Nếu bạn đang tìm kiếm tải nhanh hơn, một trong hai chức năng sẽ hoạt động, nó chỉ phụ thuộc vào nhu cầu không gian của bạn.. That's a lot of saved space. Another big difference is in the load times. If you're looking for faster loading, either function will work, it just depends on your space needs.