Python 如何将JSON列转换为数据帧?
我有一个混合列的.csv文件,其中一些包含JSON语法的条目(嵌套)。我想从这些列中提取相关数据,以获得数据更丰富的数据框架,以便进一步分析。我已经检查过了,但是没有得到想要的结果 为了更好地解释我的问题,我在下面准备了一个数据库的虚拟版本Python 如何将JSON列转换为数据帧?,python,json,pandas,Python,Json,Pandas,我有一个混合列的.csv文件,其中一些包含JSON语法的条目(嵌套)。我想从这些列中提取相关数据,以获得数据更丰富的数据框架,以便进一步分析。我已经检查过了,但是没有得到想要的结果 为了更好地解释我的问题,我在下面准备了一个数据库的虚拟版本 raw = {"team":["Team_1","Team_2"], "who":[[{"name":"Andy", "age":22},{"name":"Rick", "age":30}],[{"name":"Oli", "age":19},
raw = {"team":["Team_1","Team_2"],
"who":[[{"name":"Andy", "age":22},{"name":"Rick", "age":30}],[{"name":"Oli", "age":19},{"name":"Joe", "age":21}]]}
df = pd.DataFrame(raw)
我想生成以下列(或等效列):
我试过以下方法
代码1:
test_norm = json_normalize(data=df)
AttributeError: 'str' object has no attribute 'values'
test_norm = json_normalize(data=df, record_path='who')
TypeError: string indices must be integers
test_norm = json_normalize(data=df, record_path='who', meta=[team])
TypeError: string indices must be integers
代码2:
test_norm = json_normalize(data=df)
AttributeError: 'str' object has no attribute 'values'
test_norm = json_normalize(data=df, record_path='who')
TypeError: string indices must be integers
test_norm = json_normalize(data=df, record_path='who', meta=[team])
TypeError: string indices must be integers
代码3:
test_norm = json_normalize(data=df)
AttributeError: 'str' object has no attribute 'values'
test_norm = json_normalize(data=df, record_path='who')
TypeError: string indices must be integers
test_norm = json_normalize(data=df, record_path='who', meta=[team])
TypeError: string indices must be integers
有什么方法可以有效地做到这一点吗?我在其他stackoverflow主题中寻找了一个解决方案,但我找不到使用json_normalize的有效解决方案。我在
who
列中包含的DICT列表中使用json_normalize时也遇到了问题。我的解决方法是将每一行重新格式化为一个Dict,每个团队成员的姓名/年龄都有唯一的键(name\u 1
,age\u 1
,name\u 2
,等等)。在此之后,创建具有所需结构的数据帧是很简单的
这是我的步骤。从你的例子开始:
raw = {"team":["Team_1","Team_2"],
"who":[[{"name":"Andy", "age":22},{"name":"Rick", "age":30}],[{"name":"Oli", "age":19},{"name":"Joe", "age":21}]]}
df = pd.DataFrame(raw)
df
team who
0 Team_1 [{'name': 'Andy', 'age': 22}, {'name': 'Rick',...
1 Team_2 [{'name': 'Oli', 'age': 19}, {'name': 'Joe', '...
who
列中的每一行:who
列上使用json_normalize。然后确保规范化数据帧的列按所需顺序显示:who
列:如果您的real.csv文件有太多行,那么我的解决方案可能有点太贵(看看它是如何迭代每一行,然后迭代每一行中包含的列表中的每个条目的)。如果(希望)情况不是这样,也许我的方法就足够好了。一个选择是自己打开字典。像这样:
from pandas.io.json import json_normalize
raw = {"team":["Team_1","Team_2"],
"who":[[{"name":"Andy", "age":22},{"name":"Rick", "age":30}],[{"name":"Oli", "age":19},{"name":"Joe", "age":21}]]}
# add the corresponding team to the dictionary containing the person information
for idx, list_of_people in enumerate(raw['who']):
for person in list_of_people:
person['team'] = raw['team'][idx]
# flatten the dictionary
list_of_dicts = [dct for list_of_people in raw['who'] for dct in list_of_people]
# normalize to dataframe
json_normalize(list_of_dicts)
# due to unpacking of dict, this results in the same as doing
pd.DataFrame(list_of_dicts)
这输出有点不同。我的输出通常更便于进一步分析
输出:
age name team
22 Andy Team_1
30 Rick Team_1
19 Oli Team_2
21 Joe Team_2
age_0 name_0 age_1 name_1 team
22 Andy 30 Rick Team_1
19 Oli 21 Joe Team_2
您可以分别迭代
raw['who']
中的每个元素,但当您这样做时,生成的数据帧将在单独的行中包含两个对手
例如:
json_normalize(raw['who'][0])
Output:
age name
22 Andy
30 Rick
您可以将这些行展平为一行,然后连接所有行以获得最终输出
def flatten(df_temp):
df_temp.index = df_temp.index.astype(str)
flattened_df = df_temp.unstack().to_frame().sort_index(level=1).T
flattened_df.columns = flattened_df.columns.map('_'.join)
return flattened_df
df = pd.concat([flatten(pd.DataFrame(json_normalize(x))) for x in raw['who']])
df['team'] = raw['team']
输出:
age name team
22 Andy Team_1
30 Rick Team_1
19 Oli Team_2
21 Joe Team_2
age_0 name_0 age_1 name_1 team
22 Andy 30 Rick Team_1
19 Oli 21 Joe Team_2
可能重复的