在Pandas中UnicodeDecodeError无法使用pandas.read_json()解码JSON文件中的Unicode Ascii

时间:2017-03-13 11:28:32

标签: python json pandas unicode ascii

提前感谢您的帮助。我试图将一个JSON文件读入一个pandas DataFrane并获得unicode / ascii错误的聚宝盆。 编辑:错误似乎在于JSON文件是多行的,每行都有自己的JSON对象。

使用如下所示的数据文件:

"data.json" = 

{"_i":{"$o":"5b"},"c_id":"10","p_id":"10","c_c":2,"l_c":59,"u":{"n":"J","id":"1"},"c_t":"2010","m":"Hopefully \n\nEDIT: Actually."}
{"_i":{"$o":"5b"},"p_id":"10","c_id":"10","p_id":"10","c_c":0,"l_c":8,"u":{"n":"S","id":"1"},"c_t":"2010","m":"in-laws?"}

编辑:在回复评论时,上面不是要运行的代码,它包含在我的数据文件的示例中,并保存为json文件。

由于这是一个多行文件,因此我尝试使用此链接Loading a file with more than one line of JSON into Python's Pandas

import pandas
df = pandas.read_json('data.json', lines = True)

给出错误:

    json = u'[' + u','.join(lines) + u']'
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 436: ordinal not in range(128)

根据GitHub https://github.com/pandas-dev/pandas/issues/15132上突出显示的这个问题,这是因为:

  

如果默认编码设置为ascii(检查sys.getdefaultencoding()),则可能会在Python 2.7中发生。当lines = True时,StringIO会将输入字符串转换为ascii,因为混合utf-8和ascii字符串会导致UnicodeDecodeError。

他们的解决方案是将系统编码从utf-8更改为ascii,但是,我知道这是不可取的 - 来源:Changing default encoding of Python?

我还尝试将编码更改为utf-8内的ascii / read_json(),但无济于事。

如何成功将此json文件读入pandas DataFrame,保留多行结构?

非常感谢!

2 个答案:

答案 0 :(得分:1)

人们有时会在这里胡思乱想。好吧,在python 2.7中,它默认为ascii,您可以使用以下行来查看:

encoding = sys.getdefaultencoding()
print encoding

看起来他们通过允许你设置如下的编码来解决这个问题:

pd.read_json(the_file, encoding = encoding)

不幸的是,这条线似乎也不起作用。

因此,我们可以自己做,而不是依靠大熊猫。所有“行”选项都在末尾用方括号括起来并用逗号连接(即[{},{},{}])。

首先,读入数据并剥离它:

with open(path+theFile, 'rb') as f:
    data = f.readlines()

data = map(lambda x: x.rstrip(), data)

Python读取行没有编码问题。然后我们可以使用pandas中的相同代码来执行这些行:

data_lines = "[" + ','.join(data) + "]"

然后像正常一样将这些行读入解析器:

df = pd.read_json(data_lines)

BTW,这在python 3中都不是问题

答案 1 :(得分:0)

最后,我最终使用https://stackoverflow.com/a/34463368/2254228的答案,使用json.loads()逐行保存文件的输出。

我的代码因此成了:

import pandas
import json

data=[]
with open('data.json') as f:
    for line in f:
        data.append(json.loads(line))
df = pd.DataFrame(data)