展平嵌套 json 使每个项目一行
Flattening nested json to have one row per item
我有一个嵌套的 json,我正试图将其展平:
[
{
"name": "table1",
"count": 123,
"columns": {
"col1": "string",
"col2": "string"
},
"partitions": 2
},
{
"name": "table2",
"count": 234,
"columns": {
"col3": "int",
"col4": "string",
"col5": "int"
},
"partitions": 4
}
]
我正在尝试将其扁平化为如下所示:
name count col_name col_type partitions
table1 123 col1 string 2
table1 123 col2 string 2
table2 234 col3 int 4
table2 234 col4 string 4
table2 234 col5 int 4
正在将 json 读入 pandas 数据帧。
with open("file.json") as datafile:
data = json.load(datafile)
dataframe = pd.DataFrame(data)
pd.json_normalize
不起作用,因为我不想创建太多列。
相反,我正在尝试创建更多行。
有人可以指导我如何在 python 或使用 pandas 中最好地实现这一目标吗?
感谢任何帮助。
谢谢。
您可以使用 wide_to_long
:
df = pd.json_normalize(data)
cols = [c for c in df.columns if not c.startswith('columns')]
out = (pd.wide_to_long(df, stubnames='columns', i=cols, j='col_name',
sep='.', suffix='col\d+')
.rename(columns={'columns': 'col_type'})
.query('col_type.notna()').reset_index())
print(out)
# Output
name count partitions col_name col_type
0 table1 123 2 col1 string
1 table1 123 2 col2 string
2 table2 234 4 col3 int
3 table2 234 4 col4 string
4 table2 234 4 col5 int
这是直接的解决方案,您从相应的键中形成一堆字典,然后从中创建一个数据框。
import json
import pandas as pd
with open("abc.json") as datafile:
data = json.load(datafile)
print(data)
d = [{'name': x['name'],'count':x['count'],'colname':k,'coltype':x['columns'][k], 'partitions':x['partitions']} for x in data for k in x['columns'].keys()]
df = pd.DataFrame.from_dict(d)
print(df)
输出
[{'name': 'table1', 'count': 123, 'columns': {'col1': 'string', 'col2': 'string'}, 'partitions': 2}, {'name': 'table2', 'count': 234, 'columns': {'col3': 'int', 'col4': 'string', 'col5': 'int'}, 'partitions': 4}]
name count colname coltype partitions
0 table1 123 col1 string 2
1 table1 123 col2 string 2
2 table2 234 col3 int 4
3 table2 234 col4 string 4
4 table2 234 col5 int 4
我有一个嵌套的 json,我正试图将其展平:
[
{
"name": "table1",
"count": 123,
"columns": {
"col1": "string",
"col2": "string"
},
"partitions": 2
},
{
"name": "table2",
"count": 234,
"columns": {
"col3": "int",
"col4": "string",
"col5": "int"
},
"partitions": 4
}
]
我正在尝试将其扁平化为如下所示:
name count col_name col_type partitions
table1 123 col1 string 2
table1 123 col2 string 2
table2 234 col3 int 4
table2 234 col4 string 4
table2 234 col5 int 4
正在将 json 读入 pandas 数据帧。
with open("file.json") as datafile:
data = json.load(datafile)
dataframe = pd.DataFrame(data)
pd.json_normalize
不起作用,因为我不想创建太多列。
相反,我正在尝试创建更多行。
有人可以指导我如何在 python 或使用 pandas 中最好地实现这一目标吗?
感谢任何帮助。 谢谢。
您可以使用 wide_to_long
:
df = pd.json_normalize(data)
cols = [c for c in df.columns if not c.startswith('columns')]
out = (pd.wide_to_long(df, stubnames='columns', i=cols, j='col_name',
sep='.', suffix='col\d+')
.rename(columns={'columns': 'col_type'})
.query('col_type.notna()').reset_index())
print(out)
# Output
name count partitions col_name col_type
0 table1 123 2 col1 string
1 table1 123 2 col2 string
2 table2 234 4 col3 int
3 table2 234 4 col4 string
4 table2 234 4 col5 int
这是直接的解决方案,您从相应的键中形成一堆字典,然后从中创建一个数据框。
import json
import pandas as pd
with open("abc.json") as datafile:
data = json.load(datafile)
print(data)
d = [{'name': x['name'],'count':x['count'],'colname':k,'coltype':x['columns'][k], 'partitions':x['partitions']} for x in data for k in x['columns'].keys()]
df = pd.DataFrame.from_dict(d)
print(df)
输出
[{'name': 'table1', 'count': 123, 'columns': {'col1': 'string', 'col2': 'string'}, 'partitions': 2}, {'name': 'table2', 'count': 234, 'columns': {'col3': 'int', 'col4': 'string', 'col5': 'int'}, 'partitions': 4}]
name count colname coltype partitions
0 table1 123 col1 string 2
1 table1 123 col2 string 2
2 table2 234 col3 int 4
3 table2 234 col4 string 4
4 table2 234 col5 int 4