【问题标题】:Write list of nested dictionaries to excel file in python将嵌套字典列表写入python中的excel文件
【发布时间】:2020-12-12 14:31:25
【问题描述】:

我有一个嵌套字典列表,如下所示:

[{'posts': {'item_1': 1,
                            'item_2': 8,
                            'item_3': 105,
                            'item_4': 324,
                            'item_5': 313, }},
                 {'edits': {'item_1': 1,
                            'item_2': 8,
                            'item_3': 61,
                            'item_4': 178,
                            'item_5': 163}},
                 {'views': {'item_1': 2345,
                            'item_2': 330649,
                            'item_3': 12920402,
                            'item_4': 46199102,
                            'item_5': 43094955}}]

我想以这种格式将其写入 excel 文件:

+--------+-------+-------+-----------+
|        | posts | edits |   views   |
+--------+-------+-------+-----------+
| item_1 |     1 |     1 |      2345 |
| item_2 |     8 |     8 |    330649 |
| item_3 |   105 |    61 |  12920402 |
| item_4 |   324 |   178 |  46199102 |
| item_5 |   313 |   163 | 430949955 |
+--------+-------+-------+-----------+

我正在使用 xlsxwriter 库并尝试以下内容以及以下内容的变体但未成功:

for item in data:
    for col_name, data in item.iteritems():
        col += 1
        worksheet.write(row, col, col_name)
        for row_name, row_data in data.iteritems():
            col += 1
            worksheet.write(row, col, row_name)
            worksheet.write(row + 1, col, row_data)

我想知道重做我的嵌套字典对象是否有意义,或者是否可以以当前形式写入 excel?

当我说没有太多成功时,我的意思是,我可以让它将某些内容写入 excel 文件,例如列名或行或数据,但我无法让它像上图那样写入。我没有收到错误,我怀疑我只是不知道如何正确解压缩这个对象以循环遍历它。在上面的代码中,我得到了第 1 行的行和列名称以及第 2 行的所有值的组合。

我上面代码的输出是:

+--+-------+--------+--------+--------+--------+--------+-------+--------+--------+--------+--------+--------+-------+----------+----------+--------+----------+--------+
|  | posts | item_4 | item_5 | item_2 | item_3 | item_1 | edits | item_4 | item_5 | item_2 | item_3 | item_1 | views |  item_4  |  item_5  | item_2 |  item_3  | item_1 |
+--+-------+--------+--------+--------+--------+--------+-------+--------+--------+--------+--------+--------+-------+----------+----------+--------+----------+--------+
|  |       |    324 |    313 |      8 |    105 |      1 |       |    178 |    163 |      8 |     61 |      1 |       | 46199102 | 43094955 | 330649 | 12920402 |   2345 |
+--+-------+--------+--------+--------+--------+--------+-------+--------+--------+--------+--------+--------+-------+----------+----------+--------+----------+--------+

【问题讨论】:

标签: python excel dictionary xlsxwriter


【解决方案1】:

作为替代方案,可以使用csv 解决此问题,如下所示:

import csv
import itertools

nested = [
    {'posts': {'item_1': 1, 'item_2': 8, 'item_3': 105, 'item_4': 324, 'item_5': 313,}},
    {'edits': {'item_1': 1, 'item_2': 8, 'item_3': 61, 'item_4': 178, 'item_5': 163}},
    {'views': {'item_1': 2345, 'item_2': 330649, 'item_3': 12920402, 'item_4': 46199102, 'item_5': 43094955}}]

headings = [d.keys()[0] for d in nested]
entries = [sorted(nested[index][col].items()) for index, col in enumerate(headings)]    

with open('output.csv', 'wb') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerow(['items'] + headings)

    for cols in itertools.izip_longest(*entries, fillvalue=['<n/a>']*len(entries[0])):
        csv_output.writerow([cols[0][0]] + [col[1] for col in cols])

这会给你output.csv,如下所示:

items,posts,edits,views
item_1,1,1,2345
item_2,8,8,330649
item_3,105,61,12920402
item_4,324,178,46199102
item_5,313,163,43094955

【讨论】:

  • 谢谢!它工作得几乎完美,但是有没有办法将标题向右移动一列?目前标题与行名重叠。
  • 我正在一个更大的数据集上尝试这个,其中行多于列,在这种情况下,一些行似乎被排除在 csv 写入之外。你认为这是你上面代码的副作用吗?
  • 是的,原始版本已硬编码到您的 3 个示例列中。我已经更新它以自动构建列,因此应该修复它,前提是整体结构保持不变。
  • 在行数多于列数的情况下,它似乎仍然没有列。我认为键上的枚举可以做到这一点。是否有另一种方法可以使行创建不依赖于列数?
  • 我无法重现它,你能给我一个导致它的示例数据的链接吗?
【解决方案2】:

目前,postseditsviews 中的每一个都有一个 dict,它们每个都与您的“项目”相关联,这似乎是多余的。

或者,创建一个以您的“项目”为键的字典,并将每个项目的 设为 postseditsviews 的字典,例如:

items = {}
items = {{'item_1': {'posts':1, 'edits':0, 'views':2345}
         {'item_2': {'posts':2, 'edits':8, 'views':330649}}

这样你可以简单地引用items['item_2']['edits'](应该产生8)或items['item_1']['views'](应该产生2345)等

在你的情况下,然后是这样的:

# write the headers -- this could be refined
row = 0
worksheet.write(0, 1, 'posts')
worksheet.write(0, 2, 'edits')
worksheet.write(0, 3, 'views')

# write the data:
for itm in items:
    row += 1
    worksheet.write(row, 0, itm)
    for col, prop in enmumerate(items[itm]):
        worksheet.write(row, col+1, prop)

【讨论】:

    【解决方案3】:
    import pandas as pd
    
    data = [{'posts': {'item_1': 1,
                       'item_2': 8,
                       'item_3': 105,
                       'item_4': 324,
                       'item_5': 313, }
             },
            {'edits': {'item_1': 1,
                       'item_2': 8,
                       'item_3': 61,
                       'item_4': 178,
                       'item_5': 163}
             },
            {'views': {'item_1': 2345,
                       'item_2': 330649,
                       'item_3': 12920402,
                       'item_4': 46199102,
                       'item_5': 43094955}
             }]
    
    final_df = pd.DataFrame()
    
    for id in range(0,len(data)):
        df = pd.DataFrame.from_dict(data[id])
        final_df = pd.concat([final_df, df], axis=1)
    
    print (final_df)
    
    final_df.to_excel('data.xlsx')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-06
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 2013-11-23
      • 2022-01-22
      • 1970-01-01
      相关资源
      最近更新 更多