在pandas中使用read_json导入单个记录

时间:2015-07-27 14:36:35

标签: python json pandas

我正在尝试使用以下函数导入json文件:

object["-color"]["descendant"]["etc"]

但是,我一直收到以下错误

  

ValueError:数组必须全长相同

如何将其正确导入数据框?

这是json的结构:

sku = pandas.read_json('https://cws01.worldstores.co.uk/api/product.php?product_sku=125T:FT0111')

}

4 个答案:

答案 0 :(得分:6)

The pandas.read_json function采用多种格式。

由于您没有指定json文件所在的格式(orient=属性),因此pandas默认会认为您的数据是柱状的。大熊猫期望的不同格式将在下面讨论。

试图从https://cws01.worldstores.co.uk/api/product.php?product_sku=125T:FT0111解析的数据 似乎不符合任何支持的格式,因为它似乎只是一个“记录”。熊猫期待某种收藏。

您可能应该尝试将多个条目收集到一个文件中,然后使用read_json函数对其进行解析。

编辑:

获取多行并使用pandas.read_json函数解析它的简单方法:

import urllib2
import pandas as pd


url_base = "https://cws01.worldstores.co.uk/api/product.php?product_sku={}"
products = ["125T:FT0111", "125T:FT0111", "125T:FT0111"]

raw_data_list = []

for sku in products:
    url = url_base.format(sku)
    raw_data_list.append(urllib2.urlopen(url).read())

data = "[" + (",".join(raw_data_list)) + "]"
data = pd.read_json(data, orient='records')
data

/ EDIT

我对pandas.read_json函数格式的看法。

The pandas.read_json function是熊猫试图将尽可能多的功能集成到单个功能中的又一个光辉典范。这当然导致了一个非常复杂的功能。

系列

如果您的数据是Series,则pandas.read_json(orient=)默认为'index'

解析Series时允许的方向值为:{'split','records','index'}

请注意,系列索引必须是orient='index'唯一的。

数据帧

如果您的数据是DataFrame,则pandas.read_json(orient=)默认为'columns'

解析DataFrame时允许的Orient值是: {'split','records','index','columns','values'}

请注意,orient='index'orient='columns'的系列索引必须是唯一的,而orient='index'orient='columns'orient='records'的DataFrame列必须是唯一的

格式

无论您的数据是DataFrame还是Seriesorient=都会预期数据格式相同:

分割

期望dict的字符串表示形式,如DataFrame构造函数所需:

{"index":[1,2,3,4], "columns":["col1","col2"], "data":[[8,7,6,5], [5,6,7,8]]}

记录

预期字典列表的字符串表示形式如:

[{"col1":8,"col2":5},{"col1":7,"col2":6},{"col1":6,"col2":7},{"col1":5,"col2":8}]

注意这里没有设置索引。

索引

期望嵌套dict dict的字符串表示形式,如:

{"1":{"col1":8,"col2":5},"2":{"col1":7,"col2":6},"3":{"col1":6,"col2":7},"4":{"col1":5,"col2":8}}

值得注意的是,它不会接受除字符串以外的其他类型的指示。可以在以后的版本中修复。

期望嵌套字典的字符串表示形式,如:

{"col1":{"1":8,"2":7,"3":6,"4":5},"col2":{"1":5,"2":6,"3":7,"4":8}}

期望列表的字符串表示形式如:

[[8, 5],[7, 6],[6, 7],[5, 8]]

产生的数据框

在大多数情况下,您获得的数据框将如下所示,上面的json字符串为:

   col1  col2
1     8     5
2     7     6
3     6     7
4     5     8

答案 1 :(得分:1)

也许这不是最优雅的解决方案,但是给了我想要的东西,或者至少我相信,如果出现问题,请随时警告

url = "https://cws01.worldstores.co.uk/api/product.php?product_sku=125T:FT0111"
data = urllib2.urlopen(url).read()
data = json.loads(data)
data = pd.DataFrame(data.items())
data = data.transpose()

答案 2 :(得分:0)

另一种解决方案是尝试使用。

json_path='https://cws01.worldstores.co.uk/api/product.php?product_sku=125T:FT0111'
try: a=pd.read_json(json_path)
except ValueError: a=pd.read_json("["+json_path+"]")

答案 3 :(得分:0)

迭代@firelynx的答案:

#! /usr/bin/env python3

from urllib.request import urlopen
import pandas as pd

products = ["125T:FT0111", "125T:FT0111", "125T:FT0111"]
raw_lines = ""
for sku in products:
    url = f"https://cws01.worldstores.co.uk/api/product.php?product_sku={sku}"
    raw_lines += urlopen(url).read() + "\n"

data = pd.read_json(raw_lines, lines=True)

这将支持任何返回单个JSON对象或一串换行符('\ n')的源。

或者这种单线工作应该相同:

#! /usr/bin/env python3

import pandas as pd

products = ["125T:FT0111", "125T:FT0111", "125T:FT0111"]
data = pd.concat(
    pd.read_json(
        f"https://cws01.worldstores.co.uk/api/product.php?product_sku={sku}",
        lines=True
    ) for sku in products
)

PS:python3仅在这里用于fstring支持,因此您应该使用str.format来实现python2兼容性。