CSV到多级JSON结构

时间:2017-07-24 23:02:24

标签: python json pandas dataframe

我有以下csv文件(1.csv):

"STUB_1","current_week","previous_week","weekly_diff"
"Crude Oil",1184.951,1191.649,-6.698

需要转换为以下json

json_body = [
    {
        "measurement":"Crude Oil",
        "fields":
            {
                "weekly_diff":-6.698,
                "current_week":1184.951,
                "previous_week":1191.649
                }
     }
]

df = pd.read_csv("1.csv")

df = df.rename(columns={'STUB_1': 'measurement'})

j = (df.groupby(['measurement'], as_index=True)
       .apply(lambda x: x[['current_week','previous_week', 'weekly_diff']].to_dict('r'))
       .reset_index()
       .rename(columns={0:'fields'})
       .to_json(orient='records'))

print j

输出:

[
  {
    "measurement": "Crude Oil",
    "fields": 
    [  #extra bracket
      {
        "weekly_diff": -6.698,
        "current_week": 1184.951,
        "previous_week": 1191.649
      }
    ] # extra bracket
  }
]

这几乎是我需要的,但有额外的[]。

任何人都可以帮我做错了吗?谢谢!

1 个答案:

答案 0 :(得分:1)

不要使用pandas - 您必须进行大量的手动解析才能将表数据转换为层次结构,所以为什么不跳过中间人并使用内置的{{} 1}}和csv模块为您完成任务,例如

json

你得到:

import csv
import json

with open("1.csv", "rU") as f:  # open your CSV file for reading
    reader = csv.DictReader(f, quoting=csv.QUOTE_NONNUMERIC)  # DictReader for convenience
    data = [{"measurement": r.pop("STUB_1", None), "fields": r} for r in reader]  # convert!
    data_json = json.dumps(data, indent=4)  # finally, serialize the data to JSON
    print(data_json)

但是,请注意,如果您有多个具有相同[ { "measurement": "Crude Oil", "fields": { "current_week": 1184.951, "previous_week": 1191.649, "weekly_diff": -6.698 } } ] 值的条目,则只保留最新的条目 - 否则您必须将字段存储为列表,这会将您带到原始问题与数据。

快速说明它是如何做的 - 首先我们创建一个STUB_1 - 它是一个方便的阅读器,它将每个行的条目与头字段映射。它还使用csv.DictReader确保自动转换为CSV中所有非引用字段的浮点数。然后,在列表解析中,它基本上从阅读器中逐行读取,并为每一行创建一个新的quoting=csv.QUOTE_NONNUMERIC - dict键包含measurement条目(立即删除STUB_1)和dict.pop()包含行中的其余条目。最后,fields模块用于将此列表序列化为您想要的JSON。

另外,请记住,JSON(和Python< 3.5)不保证元素的顺序,因此json条目可能会出现在measurement条目之后,并且同样适用于fields的条目。订单无论如何都不重要(除了一些非常特定情况)但是如果你想控制它,你可以使用fields按你喜欢的顺序构建你的内部词典一旦序列化为JSON。