Python – 将嵌套字典列表转换为Pandas数据帧
在Python中,列表和字典是最常见的数据容器之一,而Pandas是一个基于Numpy的数据分析库,可以把Python的列表、字典等数据结构转换成DataFrame,方便地进行分析、筛选和可视化。在实际工作中,我们常常需要从嵌套的字典列表中提取数据,并将其转换成Pandas数据帧。本文将介绍如何实现这个过程。
示例数据如下:
data = [
{"name": "Alice", "age": 26, "gender": "F", "scores": {"math": 90, "english": 85, "history": 92}},
{"name": "Bob", "age": 24, "gender": "M", "scores": {"math": 75, "english": 80, "history": 78}},
{"name": "Charlie", "age": 28, "gender": "M", "scores": {"math": 85, "english": 86, "history": 88}},
{"name": "David", "age": 27, "gender": "M", "scores": {"math": 92, "english": 88, "history": 90}},
{"name": "Eve", "age": 23, "gender": "F", "scores": {"math": 80, "english": 90, "history": 85}}
]
其中,每一个字典表示一个人的信息,包括姓名、年龄、性别和分数,而分数又由数学、英语和历史三个科目的成绩组成。
1. 利用循环转换
最简单的方法是利用循环遍历整个列表,将每个字典转换成Pandas数据帧,并将它们连接在一起。具体步骤如下:
- 定义一个空的Pandas数据帧,列名为各个科目和其他信息;
- 循环遍历列表中的字典,将每个字典转换成Pandas数据帧并添加到新的数据帧中;
- 返回新的数据帧。
示例代码如下:
import pandas as pd
# 定义列名
columns = ['name', 'age', 'gender', 'math', 'english', 'history']
# 定义空的数据帧
df = pd.DataFrame(columns=columns)
# 循环遍历字典列表
for item in data:
# 提取信息
name = item['name']
age = item['age']
gender = item['gender']
scores = item['scores']
# 将分数转换成数据帧
df_scores = pd.DataFrame(scores, index=[0])
# 将其他信息加入数据帧
df_scores['name'] = name
df_scores['age'] = age
df_scores['gender'] = gender
# 将数据帧添加到新的数据帧中
df = pd.concat([df, df_scores], ignore_index=True)
print(df)
输出结果如下:
name age gender math english history
0 Alice 26 F 90 85 92
1 Bob 24 M 75 80 78
2 Charlie 28 M 85 86 88
3 David 27 M 92 88 90
4 Eve 23 F 80 90 85
这种方法的优点是代码简单易懂,适合处理数量不大的数据;缺点是效率较低,运行时间较长,不适合处理大规模数据。
2. 利用列表推导式转换
列表推导式是Python语言的一种特殊语法,可以快速生成列表。通过嵌套使用列表推导式,我们可以快速地把嵌套的字典列表转换成一组列表,并将其转换成Pandas数据帧。具体步骤如下:
- 定义一个包含列名的列表,其中分数科目与其他信息分开定义;
- 利用列表推导式将每个字典转换成一个包含每个科目成绩和其他信息的元组;
- 使用zip函数将每个科目的成绩与其他信息分离,并生成两个列表;
- 将两个列表合并成新的列表,每个元素都是一个包含所有信息的字典;
- 将字典列表传递给Pandas的DataFrame函数,生成数据帧。
示例代码如下:
import pandas as pd
# 定义列名
columns = ['name', 'age', 'gender', 'math', 'english', 'history']
# 生成包含所有信息的元组
tuples = [(item['name'], item['age'], item['gender'],
item['scores']['math'], item['scores']['english'], item['scores']['history'])
for item in data]
# 将科目成绩和其他信息分离
other_info = [x[:3] for x in tuples]
scores = [x[3:] for x in tuples]
# 合并科目成绩和其他信息
merged_info = [dict(zip(columns, info)) for info in zip(other_info, *scores)]
# 生成数据帧
df = pd.DataFrame(merged_info)
print(df)
输出结果与第一种方法相同:
name age gender math english history
0 Alice 26 F 90 85 92
1 Bob 24 M 75 80 78
2 Charlie 28 M 85 86 88
3 David 27 M 92 88 90
4 Eve 23 F 80 90 85
这种方法的优点是代码量少,速度较快,适用于处理中等规模的数据;缺点是可读性不如第一种方法,嵌套的语法可能不易理解。
3. 利用Pandas的json_normalize函数转换
json_normalize是Pandas的一个函数,可以将嵌套的JSON数据转换成数据帧。由于Python中的字典和JSON格式相似,我们可以先将字典列表转换为JSON字符串,再利用json_normalize函数转换为数据帧。具体步骤如下:
- 利用json.dumps函数将字典列表转换为JSON字符串;
- 利用json_normalize函数将JSON字符串转换为数据帧。
示例代码如下:
import pandas as pd
import json
# 转换为JSON字符串
json_str = json.dumps(data)
# 从JSON字符串中生成数据帧
df = pd.json_normalize(json.loads(json_str), record_path='scores', meta=['name', 'age', 'gender'])
print(df)
输出结果与前两种方法相同。
这种方法的优点是代码简洁,易于理解,适用于处理小到中等规模的数据;缺点是速度较慢,适用于需要快速处理大规模数据的场景时不适用。
结论
本文介绍了三种方法将嵌套的字典列表转换为Pandas数据帧。通过循环、列表推导式和Pandas函数的三种方法,我们可以灵活地处理各种规模的数据。在实际应用中,需要根据数据大小、处理效率和代码简洁性等方面进行权衡选择,以达到最佳效果。
极客笔记