关于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格式的数据后,如下所示**
{
u't_id': u'80740185.1558980000000.120184.121164',
u'c_id': 120184,
u'msg_type': 1,
u'dlr': u'1',
u'msisdn': u'xxxxxxxx',
u'amd': u'{
"msg":" \u0986\u099c \u09b0\u09be\u09a4 \u09e7\u09e8\u099f\u09be\u09b0 \u09ae\u09a7\u09cd\u09af\u09c7 *21291*609# \u09a1\u09be\u09df\u09be\u09b2\u09c7 \u0995\u09bf\u09a8\u09c1\u09a8 \u09e7\u099c\u09bf\u09ac\u09bf \u09ef\u099f\u09be\u0995\u09be\u09a4\u09c7 (\u09e9\u09a6\u09bf\u09a8)",
"mask":"1GB_OFFER",
"ec":"1",
"time-out":"0",
"validity":"30052019 000000"
}',
u'entity': 1,
u's_id': u'80740185',
u'ch_id': 1,
u'time': 1558960217731,
u'pt_slot': u'null:null',
u'o_id': 121164
}
我已经将非常简单的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"]])
答案 0 :(得分:0)
您的源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}]
经过编辑以提供完整的工作示例。
答案 1 :(得分:0)
问题出在循环上。 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"]])
获得所需的结果。
答案 2 :(得分:0)
看起来像问题在于您尝试通过键“ amd”访问的字典实际上是一个字符串。您可以通过导入ast
将其转换为实际的词典import ast
sub_dict = ast.literal_eval(dt['amd'])