【发布时间】:2017-05-08 01:55:29
【问题描述】:
我正在尝试找到一种从平面 Pandas DataFrame 实例创建(可能很深)嵌套字典的通用方法。
假设我有以下 DataFrame:
dat = pd.DataFrame({'name' : ['John', 'John', 'John', 'John', 'Henry', 'Henry'],
'age' : [24, 24, 24, 24, 31, 31],
'gender' : ['Male','Male','Male','Male','Male','Male'],
'study' : ['Mathematics', 'Mathematics', 'Mathematics', 'Philosophy', 'Physics', 'Physics'],
'course' : ['Calculus 101', 'Calculus 101', 'Calculus 102', 'Aristotelean Ethics', 'Quantum mechanics', 'Quantum mechanics'],
'test' : ['Exam', 'Essay','Exam','Essay', 'Exam1','Exam2'],
'pass' : [True, True, True, True, True, True],
'grade' : ['A', 'A', 'B', 'A', 'C', 'C']})
dat = dat[['name', 'age', 'gender', 'study', 'course', 'test', 'grade', 'pass']] #re-order columns to better reflect data structure
我想创建一个深度嵌套的字典(或嵌套字典的列表),它“尊重”这些数据的底层结构。也就是说,成绩是关于测试的信息,它是课程的一部分,是学习的一部分,是一个人所做的。此外,年龄和性别是关于同一个人的信息。
期望的输出示例如下:
[{'John': {'age': 24,
'gender': 'Male',
'study': {'Mathematics': {'Calculus 101': {'Exam': {'grade': 'B',
'pass': True}}},
'Philosophy': {'Aristotelean Ethics': {'Essay': {'grade': 'A',
'pass': True}}}}}},
{'Henry': {'age': 31,
'gender': 'Male',
'study': {'Physics': {'Quantum mechanics': {'Exam1': {'Grade': 'C',
'Pass': True},
'Exam2': {'Grade': 'C',
'Pass': True}}}}}}]
(尽管可能有其他类似的方式来构建此类数据)。
我尝试使用 groupby,它可以很容易地例如在“test”下嵌套“grade”和“pass”,在“course”下嵌套“test”,在“study”下嵌套“course”和“研究”在“名称”下。但是,那么我看不到如何在“姓名”下添加“性别”和“年龄”?像这样的东西是我想出的最好的:
dic = {}
for ind, row in dat.groupby(['name', 'study', 'course', 'test'])['grade', 'pass']:
#this is ugly and not very generic, but just as an example
if not ind[0] in dic:
dic[ind[0]] = {}
if not ind[1] in dic[ind[0]]:
dic[ind[0]][ind[1]] = {}
if not ind[2] in dic[ind[0]][ind[1]]:
dic[ind[0]][ind[1]][ind[2]] = {}
if not ind[3] in dic[ind[0]][ind[1]][ind[2]]:
dic[ind[0]][ind[1]][ind[2]][ind[3]] = {}
dic[ind[0]][ind[1]][ind[2]][ind[3]]['grade'] = row['grade'].values[0]
dic[ind[0]][ind[1]][ind[2]][ind[3]]['pass'] = row['pass'].values[0]
但在这种情况下,'age' 和 'gender' 没有嵌套在 'name' 下。我似乎无法理解如何做到这一点......
另一个选项是设置 MultiIndex 并进行 .to_dict('index') 调用。但是话又说回来,我看不到如何将字典和非字典嵌套在一个键下......
我的问题与此类似: Convert pandas DataFrame to a nested dict,但我正在寻找更复杂的嵌套(例如,不仅仅是应该嵌套在所有其他列下的最后一列)。 Stackoverflow 上的大多数其他问题都要求相反:从深度嵌套的字典创建(可能是 MultiIndex)DataFrame。
编辑:这个问题也类似于这个q:Pandas convert Dataframe to Nested Json,但是在那个问题中,只有last列(例如,列n)应该被嵌套在所有其他列下(n-1、n-2 等;完全递归嵌套)。 在我的问题中,列 n 和 n-1 应该嵌套在 n-2 下,但列 n-2 和 n-3 应该嵌套在 n-4 下(因此,重要的是,n-2 是 not嵌套在 n-3 下但在 n-4 下)。 Mohammad Yusuf Ghazi 提供的 MultiIndex 部分解决方案很好地描绘了结构。
【问题讨论】:
标签: python pandas dictionary dataframe nested