【问题标题】:Converting Parse JSON output to CSV with large datasets使用大型数据集将 Parse JSON 输出转换为 CSV
【发布时间】:2015-06-24 21:58:23
【问题描述】:

Parse 允许用户使用他们的 Export 工具下载他们的数据,但只允许以 JSON 格式导出数据。我想用 CSV 格式在 Excel 中进行分析。

虽然一个简单的脚本足以处理较小的 JSON 对象,但我正在处理一个包含 670,000 行和超过 360MB 的数据集。在线转换器无法处理此文件大小,经常引用 PHP 超出其内存限制。

我尝试过基于 PHP CLI 的脚本和在线转换器,但它们似乎都超出了分配的内存。当ini_set('memory_limit', '4096M'); 仍然没有给我足够的内存时,我想我需要一种新方法。

我目前正在使用这个基于 CLI 的脚本来解析数据:

// flatten to CSV
function flatten2CSV($file){
    $fileIO = fopen($file, 'w+');
    foreach ($this->dataArray as $items) {
        $flatData = array();
        $fields = new RecursiveIteratorIterator(new RecursiveArrayIterator($items));
        foreach($fields as $value) {
            array_push($flatData, $value);
        }
        fputcsv($fileIO, $flatData, ";", '"');
    }
    fclose($fileIO);
}

// and $this->dataArray is created here
function readJSON($JSONdata){
    $this->dataArray = json_decode($JSONdata,1);
    $this->prependColumnNames();
    return $this->dataArray;
}

private function prependColumnNames(){
    foreach(array_keys($this->dataArray[0]) as $key){
        $keys[0][$key] = $key;
    }
    $this->dataArray = array_merge($keys, $this->dataArray);
}

如何使用 PHP 解决内存管理问题并通过这个大型数据集进行解析?对于大型数据集,有没有比 json_decode 更好的读取 JSON 对象的方法?

【问题讨论】:

  • 是否需要一次处理所有文件?如果可以批量导出 JSON,然后进行单独的转换,您可能不需要那么多的活动内存。你有你正在使用的代码吗? - 这个用例也需要 PHP 吗?
  • 可以将 Parse 中的数据导出到较小的数据集中,但这对于定期从数据库中提取数据变得很耗时。我添加了用于解析 JSON 的 JSON2CSV 类。
  • 我对 Parse 不熟悉。你能写一个脚本来拉下较小的文件集吗?此外,如果您在网页中运行此程序来进行转换,那么如果您不需要屏幕上的输入,那真的没有意义。在命令行、计划等上作为批处理作业执行此操作更有意义。您能澄清一下为什么要在浏览器中执行此操作吗?
  • 所以Parse 是用于移动应用程序开发的流行后端数据库和API 组合。我不是专门在浏览器中执行此操作 - 我对任何将 JSON 更改为 CSV 的方法持开放态度。编写脚本会产生 I/O,这是有问题的,因为 Parse 会限制 API 调用。

标签: php json csv parse-platform


【解决方案1】:

如果您能够在浏览器中运行脚本,请查看PapaParse JavaScript 库——它支持更大数据集的分块和多线程,并且可以转换JSON to CSV

可能相关的特定config options

  • worker
  • chunk
  • fastMode

另外,Node.js 有一个 fork of PapaParse,但没有 workerchunk 选项。

我与此库没有任何关系,但已成功将其用于大型数据集上的 CSV 到 JSON 转换。

【讨论】:

    【解决方案2】:

    您可以尝试使用: https://github.com/jehiah/json2csv

    转换:

    {"user": {"name":"jehiah", "password": "root"}, "remote_ip": "127.0.0.1", "dt" : "[20/Aug/2010:01:12:44 -0400]"}
    {"user": {"name":"jeroenjanssens", "password": "123"}, "remote_ip": "192.168.0.1", "dt" : "[20/Aug/2010:01:12:44 -0400]"}
    {"user": {"name":"unknown", "password": ""}, "remote_ip": "76.216.210.0", "dt" : "[20/Aug/2010:01:12:45 -0400]"}
    

    到:

    "jehiah","127.0.0.1"
    "jeroenjanssens","192.168.0.1"
    "unknown","76.216.210.0"
    

    你也可以

    json2csv -k user.name,remote_ip -i input.json -o output.csv
    

    【讨论】:

      【解决方案3】:

      事实证明,PHP 本身并不支持流式 JSON 解析器(基于我在做一些研究时发现的)。然而,Salsify 写信给an excellent blog post,讲述他们如何创建streaming JSON parser for PHP

      This is the link to the GitHub code

      使用他们的example.php 文件,我能够成功地将 JSON 文件读入 PHP 对象。

      为了完成这项工作,我必须做的其他一些事情:

      • 增加 PHP 的内存限制: 我将 php.ini 中的 memory_limit 改为 memory_limit=2048M
      • 修改 flatten2CSV() 函数: 我的新代码需要包含其 JSON 的 Parse 格式,即 { "results": [ objects ] }。新功能是:

        function flatten2CSV($file, $data){     
            $fileIO = fopen($file, 'w+');
            foreach ($data['results'] as $items) {
                $flatData = array();
                $fields = new RecursiveIteratorIterator(new RecursiveArrayIterator(new RecursiveArrayIterator($items)));
                foreach($fields as $value) {
                    array_push($flatData, $value);
                }
                fputcsv($fileIO, $flatData, ";", '"');
            }
            fclose($fileIO);
        }
        
      • 手动添加标题: 就本练习而言,以上代码足以解析我的文件。但是,我确实必须手动将标题行添加到我的 CSV 文件中。我建议编写代码来提取键并将它们添加为标题。

      YMMV 有这个功能。因为我必须专门为 Parse JSON 修改函数,所以您的 JSON 可能无法在其中工作。我的 Parse Object 并不太复杂,因此指针数组可能会破坏这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-13
        • 2021-01-01
        • 2022-01-11
        • 1970-01-01
        • 2018-07-14
        • 1970-01-01
        相关资源
        最近更新 更多