Python中JSON到CSV的转换

2024-05-14 20:40:25 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中有很多关于JSON到CSV转换的问题,但是不幸的是不能解决我的问题。在

我有一个简单的JSON数据,它在一个文件中,加载后看起来像这样。在

以单行形式显示的原始数据[我将其结构化以更好地理解]:

{
    "t_id":"80740185.1558980000000.120184.121164",
    "s_id":"80740185",
    "pt_slot":"null:null",
    "ch_id":1,"o_id":121164,"c_id":120184,
    "msg_type":1,
    "amd":"{
                \"msg\":\" some Bengali text\",
                \"mask\":\"1GB_OFFER\",
                \"ec\":\"1\",
                \"time-out\":\"0\",
                \"validity\":\"30052019 000000\"
           }",
    "time":1558960217731,
    "dlr":"1",
    "msisdn":"xxxxx",
    "entity":1
}

**加载到JSON后,格式化数据如下所示**

^{pr2}$

上面有一个非常简单的JSON数据,我正试图将其转换为CSV数据。但要低于错误。在

这是我的代码

#!/usr/bin/python

import json
import csv

def write_sms_dat_to_csv_file():
    f = csv.writer(open('csv_data.txt','wb+'),delimiter = '|')
    with open('test.dat') as fh:
            data = json.load(fh)

    for dt in data:
            f.writerow([dt['c_id'],dt['msisdn'],dt["amd"]["mask"]])

if __name__=="__main__":
    write_sms_dat_to_csv_file()

错误消息

Traceback (most recent call last):
File "./sms_data_read.py", line 16, in <module>
write_sms_dat_to_csv_file()
File "./sms_data_read.py", line 13, in write_sms_dat_to_csv_file
f.writerow([dt['c_id'],dt['msisdn'],dt['amd']['mask']])
TypeError: string indices must be integers

使用以下语句删除for循环会产生相同的错误:

f.writerow([data['c_id'],data['msisdn'],data['amd']["mask"]])

Tags: csvto数据idjsondata错误dt
3条回答

源JSON编码有点奇怪,但是如果结构与您提供的一致,那么您只需要解析dt['amd']中的值:

$ python
Python 3.7.2 (default, Dec 27 2018, 07:35:06) 
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> json_string = '''
... [
...     {
...         "t_id": "80740185.1558980000000.120184.121164",
...         "s_id": "80740185",
...         "pt_slot": "null:null",
...         "ch_id": 1,
...         "o_id": 121164,
...         "c_id": 120184,
...         "msg_type": 1,
...         "amd": "{\\"msg\\": \\" some Bengali text\\", \\"mask\\": \\"1GB_OFFER\\", \\"ec\\": \\"1\\", \\"time-out\\": \\"0\\", \\"validity\\": \\"30052019 000000\\"}",
...         "time": 1558960217731,
...         "dlr": "1",
...         "msisdn": "xxxxx",
...         "entity": 1
...     }
... ]
... '''
>>> json_data = json.loads(json_string)
>>> for row in json_data:
...     row['amd'] = json.loads(row['amd'])
...     # Write row to CSV
... 
>>> json_data
[{'amd': {'ec': '1',
          'mask': '1GB_OFFER',
          'msg': ' some Bengali text',
          'time-out': '0',
          'validity': '30052019 000000'},
  'c_id': 120184,
  'ch_id': 1,
  'dlr': '1',
  'entity': 1,
  'msg_type': 1,
  'msisdn': 'xxxxx',
  'o_id': 121164,
  'pt_slot': 'null:null',
  's_id': '80740185',
  't_id': '80740185.1558980000000.120184.121164',
  'time': 1558960217731}]

编辑以提供完整的工作示例。在

问题出在循环上。json.load返回一个字典,用for...in循环遍历。您将dt视为循环体中的字典,但它实际上是一个字符串,即字典data中的键。看起来,原始JSON数据的某些原因导致json.load无法将amd映射到的值解析为JSON对象,因此data["amd"]是字符串而不是字典。您可以通过单独解析这个字符串来解决这个问题。将这两个东西放在一起,您应该能够用

amd = json.load(data["amd"])
f.writerow([data['c_id'],data['msisdn'],amd["mask"]])

为了得到你想要的结果。在

看起来问题是你试图通过键'amd'访问的字典实际上是一个字符串。您可以通过导入ast将其转换为实际字典

import ast

sub_dict = ast.literal_eval(dt['amd'])

相关问题 更多 >

    热门问题