2017-07-27 76 views
0

你好,Pythonic愛好者。Python 3 - 使用熊貓編寫從構造的字典到excel

我遇到了一個相當有趣的小問題,由於缺乏經驗我一直無法解決。我正在基於圖表數據庫中的一組答案構建Python中的字典,並且遇到了一個有趣的困境。 (我正在運行的Python 3

當一切塵埃落定,我收到下面的示例輸出在我的Excel文件(這是從0列,每個條目是行:

實際Excel格式:

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 WRITER CODE:

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') 

要構建字典,我用下面的代碼: EDIT(刪除子除了字典項,因爲它是相同的,將被精簡成一個函數調用,一旦主要作品)。

詞典PREP CODE:

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: [{...}]}

+0

你的字典準備代碼的方式過於冗長。你能寫一個[最小,完整,可驗證的例子](https://stackoverflow.com/help/mcve),包括樣本數據嗎? – cmaher

+0

我可以進一步分解它,但這是一個建立在嵌套條目上的字典。我會盡我所能分解它。我想我可能知道問題在哪裏,但我不知道如何解決問題。 –

+0

@cmaher我刪除了額外的加(選2),因爲它是我在使它成爲一個功能,一旦我想通了,計劃選項1的幾乎一模一樣的副本是怎麼回事失控(我認爲它與方式做我「M追加到字典) –

回答

1

以書面形式向Excel中的問題是由於這樣的事實,在最後的字典中的值是字典本身的列表,所以你可能想仔細看看你是如何構建字典的。在其目前的形式,通過最後的字典pd.DataFrame.from_dict導致數據幀,看起來像這樣:

#        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'} 

所以數據幀行中的每個值本身就是一個字典。爲了解決這個問題,您可以拼合/傳遞到數據幀之前合併在最終字典內的字典:

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'}} 

然後,您可以通過這個字典成熊貓的對象,與附加參數orient=index(使數據框使用的密鑰在內部類型的字典爲列)獲得數據框,看起來像這樣:

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作爲你曾表示。

編輯:我不能測試這個沒有樣本數據,但從它的外觀,你可以通過建立一個字典,而不是一個字典列表來簡化你的字典準備。

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') 
+0

對不起,最近upvote是啊。那是我的不好。我不知道我爲什麼要輸入字典中的字典條目。這兩個都是很好的修復。我刪除了詞條的一部分,它的打印完全正確 - 非常感謝! –