【问题标题】:create a JSON file from a csv by grouping fields通过分组字段从 csv 创建 JSON 文件
【发布时间】:2018-01-12 23:18:08
【问题描述】:

我正在尝试从 csv 文件创建一个 json 文件。我还想将 csv 文件中的某些字段分组并在 json 文件中将它们组合在一起, 以下是我到目前为止的代码,但我不清楚如何对它们进行分组。

from csv import DictReader
import json
json_input_file="test.csv"
json_output_file="test.json"


# read csv for json conversion
def read_csv(file, json_file):
    csv_rows = []
    with open(json_input_file) as csvfile:
        _reader = csv.DictReader(csvfile)
        _title = _reader.fieldnames

        for _row in _reader:
            csv_rows.extend([{_title[i]:_row[_title[i]] for i in range(len(_title))}])
        write_json(csv_rows, json_file)
# write json file
def write_json(data, json_file):
    with open(json_file, "w") as F:
        F.write(json.dumps(data, sort_keys=False, indent=4, separators=(',', ': '),encoding="utf-8",ensure_ascii=False))
# exec the conversion
read_csv(json_input_file, json_output_file)

我的 csv 文件如下所示:

brand_x, x_type, x_color, brand_y, y_type,  y_color
x_code1, type1,  green,   y_code1, type200, orange
x_code1, type1,  red,     y_code1, type200, pink
x_code1, type1,  black,   y_code1, type200, yellow
x_code2, type20, blue,    y_code2, type201, blue
x_code2, type20, red,     y_code3, type202, black
x_code3, type1,  white,   y_code3, type202, black
x_code3, type1,  blue,    y_code3, type202, blue

我尝试对属于品牌和类型的颜色进行分组 例如 将所有属于brand_x的x_code1和x_type的type1的颜色分组,以此类推。

以下是我正在寻找的 json 输出:

[
    {
        "brand_x": "x_code1",
        "brand_y": "y_code1",
        "x_type": "type1",
        "y_type":"type200",
        "x_type1_color": [
          {
            "x_color": "green"
          },
          {
            "x_color": "red"
          },
          {
            "x_color": "black"
          }
        ],
        "y_type200_color":[
            {
                "y_color":"orange"
            },
            {
                "y_color": "pink"
            },
            {
                "y_color": "yellow"
            }
        ]
      }
]

【问题讨论】:

  • 简化您的问题。你都尝试了些什么? Python 具有读取 csv 文件和输出 JSON 的库
  • 请看看上面我试过的。如果我能得到一些指导,我将不胜感激,这样我就可以尝试构建解决方案。
  • 你得到了什么输出?
  • 您的 JSON 输出似乎缺少输入 csv 文件中的几项内容,例如 brand_x 列中的 x_code3brand_y 列下的 y_code3。如果没有其中的所有内容,就很难理解您希望如何分组。您发布的代码也存在问题,例如顶部有from csv import DictReader,但随后尝试使用reader = csv.DictReader(csvfile)。如果您希望其他人帮助您,请在您的问题中输入真实代码
  • 对。 JSON 输出似乎不完整。

标签: python


【解决方案1】:

熊猫似乎很适合这个。这是一个近似的解决方案

我没有尝试完全匹配您的输出,因为您似乎有一些自定义映射,例如 y_type200_color,这似乎只是 "y_type":"type200"y_color 列的组合。我也认为这种格式更整洁。

编辑通过扩展 for 循环使解决方案更加整洁

import pandas as pd
import tempfile
import csv
import os
import json

###############
#  CSV Setup  #
###############

tmp = tempfile.NamedTemporaryFile(delete=False)

raw_string =  """brand_x,x_type,x_color,brand_y,y_type,y_color
x_code1,type1,green,y_code1,type200,orange
x_code1,type1,red,y_code1,type200,pink
x_code1,type1,black,y_code1,type200,yellow
x_code2,type20,blue,y_code2,type201,blue
x_code2,type20,red,y_code3,type202,black
x_code3,type1,white,y_code3,type202,black
x_code3,type1,blue,y_code3,type202,blue"""

raw_data = [line.split(',') for line in raw_string.split()]
# Open the file for writing.
with open(tmp.name, 'w') as f:
    csv_writer = csv.writer(f)
    csv_writer.writerows(raw_data)
tmp.close()

##############
#  Solution  #
##############

# make a pandas data frame from csv
df = pd.read_csv(tmp.name)

# what columns will you use as index
index_columns = ["brand_x", "x_type"]
df = df.set_index(index_columns)

# select rows by index
df = df.loc[("x_code1", "type1")]

# reset index so that it will be included in our output
df = df.reset_index()

# messy line that matches columns to their values. The list(set(x) makes it so values are unique but also json serializable
output = dict()
for k, v in df.to_dict("list").items():
    # unique values only
    v = list(set(v))
    if len(v) <= 1:
        v = v[0]
    output[k] = v

print(json.dumps(output, indent=4))

##############
#  Clean up  #
##############
os.remove(tmp.name)

输出:

{
    "brand_x": "x_code1",
    "x_color": [
        "red",
        "green",
        "black"
    ],
    "brand_y": "y_code1",
    "x_type": "type1",
    "y_color": [
        "pink",
        "orange",
        "yellow"
    ],
    "y_type": "type200"
}

【讨论】:

  • 谢谢,对不起,我无法生成更好的 json 文件,因为我是手动编写的。尝试更详细地解释我想要实现的是如果brand_x,x_type具有相同的值,那么将x_colors分组为brand_y的相同逻辑
  • 顺便问一下,除了 pandas,还有什么替代方法?
  • Hierarchical dictionary ?一些变化可能会起作用。或者也许是安东答案的变体。 pandas 的好处是它通常可以节省代码时间
【解决方案2】:

我实现了一些 Alter 的代码,但做了一些重大更改:

import json
import io
import pandas as pd

csv = """brand_x,x_type,x_color,brand_y,y_type,y_color
x_code1,type1,green,y_code1,type200,orange
x_code1,type1,red,y_code1,type200,pink
x_code1,type1,black,y_code1,type200,yellow
x_code2,type20,blue,y_code2,type201,blue
x_code2,type20,red,y_code3,type202,black
x_code3,type1,white,y_code3,type202,black
x_code3,type1,blue,y_code3,type202,blue"""

df = pd.read_csv(io.StringIO(csv))

for item in list(df.groupby(by=[i for i in df.columns if not i.endswith("color")])):
    df_temp = item[1]
    # messy line that matches columns to their values. The list(set(x) makes it so values are unique but also json serializable
    a = {k : (list(set(v)) if len(set(v)) > 1 else list(set(v))[0]) for k, v in df_temp.to_dict("list").items()}
    print(json.dumps(a, indent=4))

打印:

{
    "y_type": "type200",
    "brand_y": "y_code1",
    "x_type": "type1",
    "y_color": [
        "pink",
        "orange",
        "yellow"
    ],
    "brand_x": "x_code1",
    "x_color": [
        "red",
        "green",
        "black"
    ]
}
{
    "y_type": "type201",
    "brand_y": "y_code2",
    "x_type": "type20",
    "y_color": "blue",
    "brand_x": "x_code2",
    "x_color": "blue"
}
{
    "y_type": "type202",
    "brand_y": "y_code3",
    "x_type": "type20",
    "y_color": "black",
    "brand_x": "x_code2",
    "x_color": "red"
}
{
    "y_type": "type202",
    "brand_y": "y_code3",
    "x_type": "type1",
    "y_color": [
        "black",
        "blue"
    ],
    "brand_x": "x_code3",
    "x_color": [
        "white",
        "blue"
    ]
}

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 2021-06-05
    • 2017-11-07
    • 1970-01-01
    • 2017-10-14
    • 2011-10-08
    相关资源
    最近更新 更多