【问题标题】:How to extract .zst files into a pandas dataframe如何将 .zst 文件提取到 pandas 数据框中
【发布时间】:2020-07-18 22:06:34
【问题描述】:

我在 Python 方面有点初学者,但我在学校的一个项目需要我在这个 reddit 流行数据集上执行分类算法。这些文件是巨大的 .zst 文件,可以在这里找到:https://files.pushshift.io/reddit/submissions/ 无论如何,我只是不确定如何将其提取到数据库中,因为到目前为止我们所做的任务只是使用了 .csv 数据集,我可以轻松地将其放入 pandas 数据框中。 我偶然发现了一个不同的帖子,我尝试使用代码:

    def transform_zst_file(self,infile):
        zst_num_bytes = 2**22
        lines_read = 0
        dctx = zstd.ZstdDecompressor()
        with dctx.stream_reader(infile) as reader:
            previous_line = ""
            while True:
                chunk = reader.read(zst_num_bytes)
                if not chunk:
                    break
                string_data = chunk.decode('utf-8')
                lines = string_data.split("\n")
                for i, line in enumerate(lines[:-1]):
                    if i == 0:
                        line = previous_line + line
                    self.appendData(line, self.type)
                    lines_read += 1
                    if self.max_lines_to_read and lines_read >= self.max_lines_to_read:
                        return
                previous_line = lines[-1]

但我不完全确定如何将其放入 pandas 数据框中,或者如果文件太大,则仅将一定百分比的数据点放入数据框中。 任何帮助将不胜感激!

以下代码只会在我每次尝试运行时使我的计算机崩溃:

import zstandard as zstd  
your_filename = "..." 
with open(your_filename, "rb") as f:     
    data = f.read()  

dctx = zstd.ZstdDecompressor() 
decompressed = dctx.decompress(data)

可能是因为文件太大,有没有办法将这个文件的一部分提取到 pandas 数据框中?

【问题讨论】:

    标签: python pandas dataframe zstd


    【解决方案1】:

    我偶然发现了一个类似的 Reddit 数据集,其中包含 zst 转储。 为了遍历您的 zst 文件的内容,我使用了以下代码,您可以将其作为脚本运行:

    import zstandard
    import os
    import json
    import sys
    from datetime import datetime
    import logging.handlers
    
    
    log = logging.getLogger("bot")
    log.setLevel(logging.DEBUG)
    log.addHandler(logging.StreamHandler())
    
    
    def read_lines_zst(file_name):
        with open(file_name, 'rb') as file_handle:
            buffer = ''
            reader = zstandard.ZstdDecompressor(max_window_size=2**31).stream_reader(file_handle)
            while True:
                chunk = reader.read(2**27).decode()
                if not chunk:
                    break
                lines = (buffer + chunk).split("\n")
    
                for line in lines[:-1]:
                    yield line, file_handle.tell()
    
                buffer = lines[-1]
            reader.close()
    
    
    if __name__ == "__main__":
        file_path = sys.argv[1]
        file_size = os.stat(file_path).st_size
        file_lines = 0
        file_bytes_processed = 0
        created = None
        field = "subreddit"
        value = "wallstreetbets"
        bad_lines = 0
        try:
            for line, file_bytes_processed in read_lines_zst(file_path):
                try:
                    obj = json.loads(line)
                    created = datetime.utcfromtimestamp(int(obj['created_utc']))
                    temp = obj[field] == value
                except (KeyError, json.JSONDecodeError) as err:
                    bad_lines += 1
                file_lines += 1
                if file_lines % 100000 == 0:
                    log.info(f"{created.strftime('%Y-%m-%d %H:%M:%S')} : {file_lines:,} : {bad_lines:,} : {(file_bytes_processed / file_size) * 100:.0f}%")
        except Exception as err:
            log.info(err)
    
        log.info(f"Complete : {file_lines:,} : {bad_lines:,}")
    

    【讨论】:

      【解决方案2】:

      该文件已使用压缩库 Zstandard (https://github.com/facebook/zstd) 进行了压缩。

      对您来说最简单的事情可能是安装 python-zstandard (https://pypi.org/project/zstandard/) 使用

      pip install zstandard
      

      然后在 python 脚本中运行类似

      的东西
      import zstandard as zstd
      
      your_filename = "..."
      with open(your_filename, "rb") as f:
          data = f.read()
      
      dctx = zstd.ZstdDecompressor()
      decompressed = dctx.decompress(data)
      
      

      现在您可以直接使用解压后的数据,也可以将其写入某个文件,然后将其加载到 pandas。祝你好运!

      【讨论】:

      • 嗨!非常感谢您的意见。我试过你的代码,但它给了我一个错误:ZstdError: could not determine content size in frame header
      • 嗯,你可以考虑直接在你的电脑上安装zstd。如果您使用的是 Mac,那么使用自制软件应该非常简单。你可以做brew install zstd。安装后,您可以使用zstd -d <filename>从命令行解压缩文件
      猜你喜欢
      • 2021-01-19
      • 2018-07-23
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2022-06-13
      相关资源
      最近更新 更多