【问题标题】:How do I merge hundreds of columns in a CSV file with python如何使用 python 合并 CSV 文件中的数百列
【发布时间】:2017-08-24 20:29:52
【问题描述】:

假设我有一个包含数百列(逗号分隔)的 CSV 文件:

ID,Column1,Column2,...,Column700
1,data,,...,
2,,data,...,
...
700,,,...,data

如何合并列,以便将所有“数据”放在一列中? CSV 文件是从此处的 JSON 文件创建的:https://nvd.nist.gov/vuln/data-feeds#JSON_FEED

这是我正在使用(来自另一个 SO 帖子)从 JSON 转换为 CSV 的代码:

def to_string(s):
    try:
        return str(s)
    except:
        #Change the encoding type if needed
        return s.encode('utf-8')

def reduce_item(key, value):
    global reduced_item

    #Reduction Condition 1
    if type(value) is list:
        i=0
        for sub_item in value:
            reduce_item(key+'_'+to_string(i), sub_item)
            i=i+1

    #Reduction Condition 2
    elif type(value) is dict:
        sub_keys = value.keys()
        for sub_key in sub_keys:
            reduce_item(key+'_'+to_string(sub_key), value[sub_key])

    #Base Condition
    else:
        reduced_item[to_string(key)] = to_string(value)

if __name__ == "__main__":
    if len(sys.argv) == 4: #original was !=
        print ("\nUsage: python json_to_csv.py <node_name> <json_in_file_path> <csv_out_file_path>\n")
        #print ("Trying this without command line arguments")
    else:
    #Reading arguments
        #node = sys.argv[1]
        #json_file_path = sys.argv[2]
        #csv_file_path = sys.argv[3]

        node = "CVE_Items"
        json_file_path = "some\file.json"
        csv_file_path = "some\file.csv"

        fp = open(json_file_path, 'r')
        json_value = fp.read()
        raw_data = json.loads(json_value)

        try:
            data_to_be_processed = raw_data[node]
        except:
            data_to_be_processed = raw_data

        processed_data = []
        header = []
        for item in data_to_be_processed:
            reduced_item = {}
            reduce_item(node, item)

            header += reduced_item.keys()

            processed_data.append(reduced_item)

        header = list(set(header))
        header.sort()

        with open(csv_file_path, 'w', newline='') as f:
            writer = csv.DictWriter(f, header, quoting=csv.QUOTE_ALL)
            writer.writeheader()
            for row in processed_data:
                writer.writerow(row)

以下是 JSON 文件中的一个示例条目:

{
  "CVE_data_type" : "CVE",
  "CVE_data_format" : "MITRE",
  "CVE_data_version" : "4.0",
  "CVE_data_numberOfCVEs" : "6208",
  "CVE_data_timestamp" : "2017-08-14T18:06Z",
  "CVE_Items" : [ {
    "cve" : {
      "CVE_data_meta" : {
        "ID" : "CVE-2003-1547"
      },
      "affects" : {
        "vendor" : {
          "vendor_data" : [ {
            "vendor_name" : "francisco_burzi",
            "product" : {
              "product_data" : [ {
                "product_name" : "php-nuke",
                "version" : {
                  "version_data" : [ {
                    "version_value" : "6.5"
                  }, {
                    "version_value" : "6.5_beta1"
                  }, {
                    "version_value" : "6.5_rc3"
                  }, {
                    "version_value" : "6.5_rc2"
                  }, {
                    "version_value" : "6.5_rc1"
                  } ]
                }
              } ]
            }
          } ]
        }
      },
      "problemtype" : {
        "problemtype_data" : [ {
          "description" : [ {
            "lang" : "en",
            "value" : "CWE-79"
          } ]
        } ]
      },
      "references" : {
        "reference_data" : [ {
          "url" : "http://secunia.com/advisories/8478"
        }, {
          "url" : "http://securityreason.com/securityalert/3718"
        }, {
          "url" : "http://www.securityfocus.com/archive/1/archive/1/316925/30/25250/threaded"
        }, {
          "url" : "http://www.securityfocus.com/archive/1/archive/1/317230/30/25220/threaded"
        }, {
          "url" : "http://www.securityfocus.com/bid/7248"
        }, {
          "url" : "https://exchange.xforce.ibmcloud.com/vulnerabilities/11675"
        } ]
      },
      "description" : {
        "description_data" : [ {
          "lang" : "en",
          "value" : "Cross-site scripting (XSS) vulnerability in block-Forums.php in the Splatt Forum module for PHP-Nuke 6.x allows remote attackers to inject arbitrary web script or HTML via the subject parameter."
        } ]
      }
    },
    "configurations" : {
      "CVE_data_version" : "4.0",
      "nodes" : [ {
        "operator" : "OR",
        "cpe" : [ {
          "vulnerable" : true,
          "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5",
          "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5:*:*:*:*:*:*:*"
        }, {
          "vulnerable" : true,
          "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_beta1",
          "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_beta1:*:*:*:*:*:*:*"
        }, {
          "vulnerable" : true,
          "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_rc1",
          "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc1:*:*:*:*:*:*:*"
        }, {
          "vulnerable" : true,
          "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_rc2",
          "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc2:*:*:*:*:*:*:*"
        }, {
          "vulnerable" : true,
          "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_rc3",
          "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc3:*:*:*:*:*:*:*"
        } ]
      } ]
    },
    "impact" : {
      "baseMetricV2" : {
        "cvssV2" : {
          "vectorString" : "(AV:N/AC:M/Au:N/C:N/I:P/A:N)",
          "accessVector" : "NETWORK",
          "accessComplexity" : "MEDIUM",
          "authentication" : "NONE",
          "confidentialityImpact" : "NONE",
          "integrityImpact" : "PARTIAL",
          "availabilityImpact" : "NONE",
          "baseScore" : 4.3
        },
        "severity" : "MEDIUM",
        "exploitabilityScore" : 8.6,
        "impactScore" : 2.9,
        "obtainAllPrivilege" : false,
        "obtainUserPrivilege" : false,
        "obtainOtherPrivilege" : false,
        "userInteractionRequired" : true
      }
    },
    "publishedDate" : "2003-12-31T05:00Z",
    "lastModifiedDate" : "2017-08-08T01:29Z"
  } ]
}

【问题讨论】:

  • 如果您放置一个简单的输入和输出示例会有所帮助,当然在示例中省略了 700 列事实;)
  • 您是否有任何 Python 代码已经开始使用该解决方案?为什么要将 JSON 转换为 CSV,您可以将 JSON 数据直接作为 PHP 中的对象,并在短短几行内将其转储为 CSV 格式,顺便说一句。你也许可以在 Python 中做同样的事情。
  • @Aron - 按要求添加样本。我目前没有使用 PHP 的选项。
  • 这听起来像是一个“编写我的代码”问题,因为您没有告诉我们您现有代码的问题是什么。你能指定它,这样我们就不必去寻找(即使它可能很明显,很高兴知道我们在寻找什么,它可以更快地提出解决方案)

标签: python json csv


【解决方案1】:

如果我理解正确,您有一个包含许多列的 CSV 文件,但每条记录仅填充了 ID 和一个(非 ID)列,并且没有两条记录具有相同的(非 ID)列填充。所以基本上你想将所有 700 条记录“折叠”成一条。

由于 ID 值都不同,我不确定您希望如何将它们合并到一条记录中。我假设你知道在这种情况下该怎么做,所以我不会费心去尝试把这部分做好。

假设您的数据位于名为 nist.csv 的文件中,您可以将记录读入 merged_record,如下所示:

import csv
reader = csv.reader(open('nist.csv'))

# Extract the header:
header = next(reader)

# Initialize an empty merged_record:
merged_record = [''] * len(header)

# Populate the merged_record with data from the CSV file:
for record in reader:
    for i,value in enumerate(record):
        if value:  # only overwrite if the value is non-empty
            merged_record[i] = value

获得headermerged_record 后,您可以将它们输出到名为nist_merged.csv 的新CSV 文件中,如下所示:

with open('nist_merged.csv', 'w') as outputfile:
    writer = csv.writer(outputfile)
    writer.writerow(header)
    writer.writerow(merged_record)

你可以像这样把它减少到一行:

csv.writer(open('nist_merged.csv', 'w')).writerows([header, merged_record])

同样,ID 字段可能不是您想要的,但由于这个新的 CSV 文件中只有两行,您应该很容易将其更改为您想要的任何内容。

【讨论】:

    猜你喜欢
    • 2018-11-29
    • 2020-07-11
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 2021-05-27
    • 2020-02-22
    相关资源
    最近更新 更多