2017-07-24 63 views
0

我有以下csv文件(1.csv):CSV到多层次的JSON结构

"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

为什么所有使用'pandas'编排这样简单的任务?你会得到'额外括号',因为你将它定义为一个索引,因此该索引下的所有内容都是序列化时列表中的一个元素。 – zwer

+0

谢谢。如果索引不是一个好的方法,我应该把它定义为什么适当的结构。 –

回答

1

不要使用pandas这个 - 你会做很多手工解体的把你的表数据为层级结构,因此为什么不干脆跳过中间人,并使用内置csvjson模块为你做任务,例如

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 - 这是一个方便的阅读器,它将每行的条目映射到标题字段。它还使用quoting=csv.QUOTE_NONNUMERIC确保自动转换为CSV中所有未引用字段的浮动内容。然后,在列表理解中,它实质上从阅读器中逐行读取,并为每一行创建新的dict - measurement键包含STUB_1条目(其立即被dict.pop()移除)并且fields包含该行中的其余条目。最后,使用json模块将此列表序列化为您需要的JSON。

而且,记住,JSON(和Python 3.5 <)并不能保证元素的顺序,那么你measurement条目可能在fields入境后出现,同样适用的fields的子项。顺序应该无所谓(除了几个非常特定情况),但如果你想控制它,你可以使用collections.OrderedDict建立你的内部字典,你希望看到一旦序列化到JSON的顺序。

+0

看起来很不错。非常清爽的想法!从来没有想过跳过熊猫。将在今天进行测试并发布反馈。非常感谢!!! –

+0

#测试上面的代码。很好地工作。我做了一些修改。 1.)我有一些领域有一千个分隔符和引号。如“1,428.897”,因此quoting = csv.QUOTE_NONNUMERIC不适用于这些字段。 2)我需要添加一个timstamp列。 #修改后的代码 导入CSV,JSON DEF CONV(S): S = s.replace( '', '') 尝试: S =浮子(S) 除了ValueError异常: 通 返回s –

+0

打开(“2.csv”,“rU”)为f:#打开您的CSV文件以阅读 阅读器= csv.DictReader(f)#DictReader为了方便 适用于阅读器中的r: r:r [i] = conv(r [i]) data = [{“time”:1499437800000,“measurement”:r.pop(“STUB_1”,None),“fields”:r}]#convert ! data_json = json.dumps(data,indent = 4)#finally,serialize the data to JSON print data_json –