如何将半结构化 JSON 数据规范化为平面表?

JSON是JavaScript Object Notation的缩写,主要用于网页之间传输数据。JSON 与语言无关,这意味着它可以与任何编程语言一起使用。

JSON 是一种广泛使用的文件格式,因为它是一种易于人类和机器理解和解析的轻量级数据交换格式。

JSON 的主要优点是它可以用作 Web 应用程序中客户端和服务器之间的数据交换媒介。它还用于配置文件、日志和数据存储。

JSON 在数据表示方面类似于Python 中的字典

查看下面给出的 JSON 示例。

1
2
3
4
5
6
{
    "name": "John Smith",
    "age": 35,
    "isMarried": true,
    "hobbies": ["reading", "hiking", "cooking"]
}

因此,在上面的示例中,将属性“name”、“age”、“isMarried”和“hobbies”作为键。‘:’后面的数据被视为一个值。我们可以说 JSON 以键:值对的形式存储数据。


嵌套 JSON

正如它的自我描述一样,嵌套 JSON 是一个大 JSON 对象,它是其他 JSON 对象的集合。

以下是嵌套 JSON 对象的示例。

{
    "firstName": "John",
    "lastName": "Doe",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "CA",
        "zip": "12345"
    },
    "phoneNumbers": [
        {
            "type": "home",
            "number": "555-555-1212"
        },
        {
            "type": "work",
            "number": "555-555-2121"
        }
    ]
}

在此示例中,顶级对象具有五个属性:“firstName”、“lastName”、“age”、“address”和“phoneNumbers”。“address”属性本身是一个具有四个嵌套属性的对象:“street”、“city”、“state”和“zip”。“phoneNumbers”属性是一个由两个对象组成的数组,每个对象都有两个属性:“type”和“number”。

嵌套创建了一个分层结构,对于组织和表示复杂数据很有用。


为什么要标准化 JSON?

虽然使用 JSON 和嵌套 JSON 在数据的分层存储中很有用,但处理复杂数据可能会变得困难。JSON 的主要缺点是它的数据类型有限,我们可能必须处理这种格式不支持的一些数据类型。因此,当我们将JSON标准化为平面表结构时,处理复杂的数据就更容易了,并且标准化后还可以转换为其他结构,例如数据框。

JSON 规范化也可能有助于提高数据的安全性。


Pandas.json_normalize简介

可以对 JSON 对象进行规范化,以减少操作的冗余和复杂性。标准化为平面表允许对数据进行查询和索引。

Pandas 库提供了一种标准化 JSON 数据的方法。

如果您不熟悉 Pandas 库及其基本数据结构,请阅读这篇有关Pandas 简介的文章。

语法如下。

pandas.json_normalize(data, record_path=None, meta=None, meta_prefix=None, record_prefix=None, errors='raise', sep='.', max_level=None)

语法的重要参数是:

数字 争论 描述 默认值/类型 需求性
1 数据 未序列化的 JSON 对象,必须转换为表
此参数可以是嵌套的 JSON、JSON 对象列表或 JSON 字符串
字典或字典列表 必需的
2 记录路径 该参数用于指定需要扁平化的 JSON 记录的路径
当存在该参数时,将扁平化该参数给出的记录
如果不传递,则扁平化所有记录
str 或 str 列表,
默认 – 无
必需的
3 用作结果表中每条记录的元数据的字段
这些记录不会被展平,并用于描述被展平的其他字段
str 或 str 列表,
默认 – 无
必需的
4 元前缀 该字段用作字符串来命名字段meta str,
默认值 – 无
必需的
5 记录前缀 该字段用作字符串以在前面添加列record_path str,
默认值 – 无
必需的
6 错误 ‘ignore’:如果元中列出的键不总是存在,将忽略 KeyError
‘raise’:如果元中列出的键不总是存在,将引发 KeyError
‘提高’,’忽略’,
默认 – 无
必需的
7 九月 展平嵌套数据时使用的分隔符 str,
默认-‘.’
必需的
8 最大级别 要标准化的最大级别数
它可用于限制发生的扁平化量
如果没有,则标准化所有级别。
int,
默认值 – 无
必需的
论据json_normalize

返回类型:返回一个 DataFrame。


使用 Pandas.json_normalize 的示例

在这篇文章中,我们将研究创建一个嵌套的 JSON 对象,然后对其进行规范化。我们还将看到加载 JSON 文件作为文件路径并将其规范化为平面表。

我们将看到如何使用record_path来标准化特定的列。


示例 1:规范化嵌套 JSON

让我们借助键:值对格式创建一个嵌套的 JSON 并对其进行规范化。

下面给出了创建 JSON 的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 号
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import pandas as pd
import json
#creating json
data = [
    {"Roll no": 44,
     "first_name": "Kalyan",
     "last_name": "Sai",
     "Sanskrit": "85",
     "English": "100",
     "French": "67",
     "Biology": 35,
     "Physics": 70,
     "Math": 82
     },
    {"Roll no": 45,
     "first_name": "Sai",
     "last_name": None,
     "Sanskrit": "95",
     "English": "88",
     "French": None,
     "Biology": None,
     "Physics": None,
     "Math": None
     },
    {"Roll no": 46,
     "first_name": "John",
     "last_name": None,
     "Sanskrit": None,
     "English": None,
     "French": "90",
     "Biology": "82",
     "Physics": None,
     "Math": None
     },
    {"Roll no": 47,
     "first_name": "Alyssa",
     "last_name": "Choi",
     "Sanskrit": None,
     "English": None,
     "French": None,
     "Biology": None,
     "Physics": "73",
     "Math": "98"
     }
]
 
print(data)

让我们分解一下代码。

在第一行中,我们将 Pandas 库导入为 pd,这对于标准化 JSON 至关重要。

接下来,我们导入 json 包以便能够使用 JSON 对象。

因此,我们创建一个嵌套字典,存储在名为 data 的变量中。

我们正在使用 打印此内容print()

我们使用“None”指定某些键没有记录。这有助于降低数据的复杂性,不这样做可能会引发一些错误。

字典

数据还不是 JSON 格式。我们需要将这个字典转换为 JSON。

代码如下。

1
2
3
json_data = json.dumps(data)
dict_data = json.loads(json_data)
print(dict_data)

json.dumps是 json 包的一个方法,用于将任何 python 对象转换为 json 格式的字符串。它存储在名为 json_data 的变量中。

如果您看过语法 json.normalize,您可能知道此方法仅接受字典或字典列表。因此,我们使用 json.loads 创建 json 的字典对象,并将其存储在 dict_data 中。

在下面的行中,我们将打印这些数据

JSON

尽管两个输出看起来本质上相同,但实际上并非如此。第一个输出是 python 对象,第二个输出是 json 对象。

现在,我们需要将 json 规范化为表。

#normalizing
df = pd.json_normalize(json_data)
print(df)

我们正在使用该json_normalize方法将 json 扁平化为数据框。

获得展平后的表格如下所示。

JSON-DF1

虽然获得了表格或数据框,但需要对其进行修改以增加可读性。

我们可以用零替换 NaN 值并执行一些清理。

阅读这篇关于如何用 0 替换 Pandas 数据框中的 NaN 值的文章。


示例 2:从文件路径读取 JSON 进行规范化

让我们获取一个 JSON 格式的数据集,从其文件路径读取它,然后对其进行规范化。

我们将处理的 JSON 文件是对财务数据进行数值推理的数据集。

下载后,JSON 文件将如下所示。

JSON 文件

代码如下。

1
2
3
4
5
6
7
8
import pandas as pd
import json
#loading a json file
df=pd.read_json('/content/test.json')
 with open('/content/test.json') as f:
  d=json.load(f)
df=pd.json_normalize(d)
print(df.head())

首先,我们导入 Pandas 库及其标准别名 pd。

接下来,我们导入 json 包。

在下面的行中,我们使用 读取 json 文件pd.read_json并将其存储在对象“df”中。

接下来,我们使用短访问关键字“d”打开此文件。

json.load():由于json_normalize只接受字典,因此使用load方法将这个json转换为类似字典的对象。

您可能会发现上一示例与此示例之间的一个区别是 的用法json.dumps由于本例中的数据已经是 JSON 格式,因此我们不需要使用该dumps方法。但在前面的示例中,我们希望展平的数据是一个 python 对象。所以我们用来dumps将其转换为JSON对象。

接下来,我们将此 json 文件规范化为数据框。

在下面的行中,我们将打印数据帧的前五个条目。

标准化后的表如下所示。

JSON-DF2

您已经了解了读取 JSON 文件的多种方法之一。

查看这篇关于将 JSON 文件读取为路径的方法的文章。


示例 3:使用 Pandas.json_normalize() 的 record_path 参数

让我们从上面的示例中获取相同的数据集并使用record_path.

我们遵循与上面示例相同的代码,但使用record_pathin 语法。
此参数用于规范化文件中的特定列。

1
2
3
4
5
6
7
8
9
import pandas as pd
import json
#loading a json file
df=pd.read_json('/content/test.json')
with open('/content/test.json') as f:
  d=json.load(f)
#normalizing the 'pre_text' column
df1=pd.json_normalize(d,record_path='pre_text')
print(df1.head())

前两行导入使用 json 所需的库和包。

在第四行中,我们使用 .json 文件作为路径读取read_json

接下来,我们将此 json 字符串转换为字典,以便load能够对其进行规范化。

但是,在第八行中,我们仅标准化数据集的一列,即“pre_text”。

因此在输出中,我们只能看到“pre_text”列已标准化。

记录路径1

现在假设您想同时标准化两列。这可以使用 来完成pd.concat

首先,我们需要分别规范化两列,然后将它们连接起来。

#normalizing column2
df2=pd.json_normalize(d,record_path='table_ori')
print(df2.head())

在此代码片段中,我们正在规范化数据集中的另一列,即“table_ori”。它存储在名为 df2 的变量中。

我们正在使用该方法打印该列的前五个条目df2.head()

记录路径2

现在,让我们将它们连接起来。

dff=pd.concat([df1,df2],axis=1)
print(dff)

我们使用该pd.concat方法组合两个标准化列并将它们存储在名为 dff 的新数据框中。

记录路径3

结论

在这篇文章中,我们了解了什么是 JSON 文件、它在 Web API 中的广泛应用以及它与 Python 中字典的相似之处。

接下来,我们看到了嵌套 JSON 的示例,以及如何使用嵌套 json 来分层存储数据。

接下来,我们了解了为什么要标准化这种格式,最重要的原因之一是 JSON 中缺乏数据结构。

我们已经看到了 的语法pd.json_normalize及其参数。

来看示例,我们了解了如何从 python 字典创建 JSON,然后借助json.loads和对其进行规范化json.dumps

接下来,我们将一个 JSON 文件作为路径,读取它并对其进行规范化。

在下一个示例中,我们看到了如何使用record_path来标准化指定的列。pd.concat我们还看到了在一个数据框中获取两个标准化列的用法。


参考

在这里找到 JSON 文件

请参阅 Pandas 官方文档