簡體   English   中英

gzip.open()的大小參數.read()

[英]The size parameter for gzip.open().read()

在Python中使用gzip庫時,我經常遇到使用.read()函數的代碼,其模式如下所示:

with gzip.open(filename) as bytestream:
    bytestream.read(16) 
    buf = bytestream.read(
        IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS
    )
    data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)

雖然我熟悉上下文管理器模式,但我很難真正理解with上下文管理器的第一行代碼在做什么。

這是read()函數的文檔:

從流中讀取最多n個字符。

從底層緩沖區讀取,直到我們有n個字符或我們點擊EOF。 如果n為負數或省略,則讀取直至EOF。

如果是這種情況,第一行bytestream.read(16)的功能角色必須是讀取並因此跳過前16個字符,可能是因為它們充當元數據或標題。 但是,當我有一些圖像時,我怎么知道使用16作為read調用的參數,而不是說32或8或64?

我記得有很多時間遇到完全相同的代碼,除了讓作者使用bytestream.read(8)而不是bytestream.read(16)或者其他任何值。 逐個字符地挖掘文件顯示沒有可識別的模式來確定標題字符的長度。

換句話說,如何確定在read函數調用中使用的參數? 或者如何知道gzip壓縮文件中標題字符的長度?

我的猜測是它與字節有關,但在搜索完文檔和在線參考后我無法確認。

可重復的細節

經過無數小時的故障排除后,我的假設是前16個字符代表某種標題或元數據。 因此,該代碼中的第一行是跳過16個字符並將剩余的存儲在名為buf的變量中。 然而,挖掘數據我發現無法確定選擇值16的原因或方式。 我已經np.float讀取了字節,並且嘗試將它們作為np.float讀取+鑄造,但是沒有可辨別的模式表明元數據在第16個字符處結束而實際數據在17日開始。

以下代碼從此網站讀取數據並提取前30個字符。 請注意,標題行“結束”(第16次顯然是在第二次出現\\ x1c`之后)並且數據開始時難以辨認:

import gzip
import numpy as np

train_data_filename = 'data_input/train-images-idx3-ubyte.gz'
IMAGE_SIZE = 28
NUM_CHANNELS = 1

def extract_data(filename, num_images):
    with gzip.open(filename) as bytestream:
        first30 = bytestream.read(30)
        return first30

first30= extract_data(train_data_filename, 10)
print(first30)
# returns: b'\x00\x00\x08\x03\x00\x00\xea`\x00\x00\x00\x1c\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

如果我們修改代碼將它們轉換為np.float32 ,這樣所有字符現在都是數字(浮點數),那么再次沒有明顯的模式可以區分標題/元數據的結束位置和數據的開始位置。

任何參考或建議將非常感謝!

從gzip的角度來看,它返回給你的一切都是數據。 沒有元數據或預先考慮到數據流的特定的gzip頭內容,所以沒有必要對任何一種算法找出多少內容gzip的是如何預先考慮到流:它預先考慮的字節數是零。


向下滾動到您鏈接的頁面底部; 有一個名為“MNIST DATABASE的文件格式”的標題

該格式規范確切地告訴您格式是什么,因此每個標頭使用了多少字節。 具體來說,每個文件中的前四項描述如下:

0000     32 bit integer  0x00000803(2051) magic number 
0004     32 bit integer  60000            number of images 
0008     32 bit integer  28               number of rows 
0012     32 bit integer  28               number of columns 

因此,如果您想跳過所有這四個項目,您將從頂部刪除16個字節。

從代碼片段中, bytestream.read(16)讀取或跳過字節流的前16個字節。 當你引用read()從流中讀取最多n個字符時,它會這樣做,但是看起來python在1個字節中存儲一個字符,使16個字符占用16個字節。

有關字符和字節的更多信息,請訪問https://pymotw.com/3/gzip/#reading-compressed-data

代碼片段主要對buf的內容感興趣,跳過流的前16個字節。 要了解如何確定進入第一個bytestream.read()的參數,AKA確定要跳過的壓縮圖像文件的字節數,我們必須了解其余代碼的作用。 特別是,我們正在閱讀什么文件以及我們嘗試使用numpy(?)庫(在1D numpy數組中保存rgb圖像?)。

我絕對不是圖像處理方面的專家,但似乎bytestream.read(16)是處理某些獨特壓縮圖像文件的獨特問題的獨特解決方案。 因此,很難說如何確定跳過多少字節而不看更多代碼並理解代碼片段背后的更多邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM