Python 3 – 从构造的Dictionary中使用pandas写入excel

你好,Pythonic爱好者。

我遇到了一个相当有趣的小问题,由于缺乏经验,我无法解决。 我正在基于一组图表数据库中的答案构build一个字典,我已经遇到了一个有趣的困境。 (我正在运行Python 3

当所有的事情都说完之后,我会在excel文件中得到如下的输出示例(这是从第0列开始的,每一行都是一行:

实际表格格式:

0/{'RecordNo': 0} 1/{'Dept': 'DeptName'} 2/{'Option 1': 'Option1Value'} 3/{'Option 2': 'Option2Value'} 4/{'Question1': 'Answer1'} 5/{'Question2': 'Answer2'} 6/{'Question3': 'Answer3'} 

等等..

预期的EXCEL格式:

 0/Dept, Option 1, Option 2, Question 1, Question 2, Question 3 1/DeptName, Option1Value, Option2Value, Answer1, Answer2, Answer3 

字典的键应该是标题和值,每一行的内容,但是由于某种原因,当我使用下面的输出代码时,它将它写出来作为键和值:

EXCEL作者代码:

 ReportDF = pd.DataFrame.from_dict(DomainDict) WriteMe = pd.ExcelWriter('Filname.xlsx') ReportDF.to_excel(WriteMe, 'Sheet1') try: WriteMe.save() print('Save completed') except: print('Error in saving file') 

为了build立字典,我使用下面的代码:编辑(删除字典条目的子添加,因为它是相同的,将被简化为一次函数调用的主要作品)。

字典编码:

 for Dept in Depts: ABBR = Dept['dept.ABBR'] #print('Department: ' + ABBR) Forests = getForestDomains(Quarter,ABBR) for Forest in Forests: DictEntryList = [] DictEntryList.append({'RecordNo': DomainCount}) DictEntryList.append({'Dept': ABBR}) ForestName = Forest['d.DomainName'] DictEntryList.append({'Forest ': ForestName}) DictEntryList.append({'Domain': ''}) AnswerEntryList = [] QList = getApplicableQuestions(str(SA)) for Question in QList: FAnswer = '' QDesc = Question['Question'] AnswerResult = getAnswerOfQuestionForDomainForQuarter(QDesc, ForestName, Quarter) if AnswerResult: for A in AnswerResult: if(str(A['Answer']) != 'None'): if(isinstance(A, numbers.Number)): FAnswer = str(int(A['Answer'])) else: FAnswer = str(A['Answer']) else: FAnswer = 'Unknown' else: print('GOBBLEGOBBLE') FAnswer = 'Not recorded' AnswerEntryList.append({QDesc: FAnswer}) for Entry in AnswerEntryList: DictEntryList.append(Entry) DomainDict[DomainCount] = DictEntryList DomainCount+= 1 print('Ready to export') 

如果任何人都可以帮助我在Excel中获取我的数据导出到适当的格式,将不胜感激。

编辑:打印的最终字典出口到Excel的:

{0: [{'RecordNo': 0}, {'Dept': 'Clothing'}, {'Forest ': 'my.forest'}, {'Domain': 'my.domain'}, {'Question1': 'Answer1'}, {'Question2': 'Answer2'}, {'Question3': 'Answer3'}], 1: [{...}]}

写入Excel的问题是由于最终字典中的值是字典本身的列表,所以可能要仔细看看如何构build字典。 在当前的格式中,将最终的字典传递给pd.DataFrame.from_dict导致DataFrame如下所示:

 # 0 # 0 {u'RecordNo': 0} # 1 {u'Dept': u'Clothing'} # 2 {u'Forest ': u'my.forest'} # 3 {u'Domain': u'my.domain'} # 4 {u'Question1': u'Answer1'} # 5 {u'Question2': u'Answer2'} # 6 {u'Question3': u'Answer3'} 

所以DataFrame行中的每个值本身就是一个字典。 为了解决这个问题,你可以把最后一个字典中的内部字典压缩/合并,然后传递给DataFrame:

 modified_dict = {k:{x.keys()[0]:x.values()[0] for x in v} for k, v in final_dict.iteritems()} # {0: {'Domain': 'my.domain', 'RecordNo': 0, 'Dept': 'Clothing', 'Question1': 'Answer1', 'Question3': 'Answer3', 'Question2': 'Answer2', 'Forest ': 'my.forest'}} 

然后,可以将这个字典传递给一个Pandas对象,并使用额外的参数orient=index (以便DataFrame使用内部字典中的键作为列)来获得如下的DataFrame:

 ReportDF = pd.DataFrame.from_dict(modified_dict, orient='index') # Domain RecordNo Dept Question1 Question3 Question2 Forest # 0 my.domain 0 Clothing Answer1 Answer3 Answer2 my.forest 

从那里,你可以写你的Excel表示。

编辑:我不能testing这个没有样本数据,但从它的外观,你可以通过build立一个字典而不是一个字典列表来简化你的字典准备。

 for Dept in Depts: ABBR = Dept['dept.ABBR'] Forests = getForestDomains(Quarter,ABBR) for Forest in Forests: DictEntry = {} DictEntry['RecordNo'] = DomainCount DictEntry['Dept'] = ABBR DictEntry['Forest '] = Forest['d.DomainName'] DictEntry['Domain'] = '' QList = getApplicableQuestions(str(SA)) for Question in QList: # save yourself a line of code and make 'Not recorded' the default value FAnswer = 'Not recorded' QDesc = Question['Question'] AnswerResult = getAnswerOfQuestionForDomainForQuarter(QDesc, ForestName, Quarter) if AnswerResult: for A in AnswerResult: # don't convert None to string and then test for inequality to 'None' # if statements evaluate None as False already if A['Answer']: if isinstance(A, numbers.Number): FAnswer = str(int(A['Answer'])) else: FAnswer = str(A['Answer']) else: FAnswer = 'Unknown' else: print('GOBBLEGOBBLE') DictEntry[QDesc] = FAnswer DomainDict[DomainCount] = DictEntry DomainCount += 1 print('Ready to export')