从嵌套字典到CSV文件

5
我有一个嵌套字典(长度大于70,000):
users_item = {
    "sessionId1": {
        "12345645647": 1.0, 
        "9798654": 5.0 

    },         
    "sessionId2":{
        "3445657657": 1.0

    },
    "sessionId3": {
        "87967976": 5.0, 
        "35325626436": 1.0, 
        "126789435": 1.0, 
        "72139856": 5.0      
    },
    "sessionId4": {
        "4582317": 1.0         
    }
......
}

我希望从我的嵌套字典中创建CSV文件,我的结果将如下所示:
sessionId1 item rating
sessionId1 item rating
sessionId2 item rating
sessionId3 item rating
sessionId3 item rating
sessionId3 item rating
sessionId3 item rating
.......

我找到了这篇文章:将嵌套字典转换为CSV表格

它和我的问题相似,但当我尝试所有答案时,pandas库会消耗内存。

我该如何用我的数据创建CSV文件?


@Ev.Kounis,抱歉我的问题不清楚。我已经编辑了我的问题! - Paldro
如果你使用实际的值而不是 itemrating,那么从一开始就会更清晰明了。 - Ma0
@ĐứcPhan 你试过根据你提供的链接中被接受的答案进行适应吗(它不使用panda而是使用csv.DictWriter)? - Frodon
即使您的嵌套字典只有1层深度,一个简单的CSV写入器也应该可以工作。也就是说,循环外部字典的“key”和“value”,并在内部字典中执行另一个循环以获取“k”和“v”,然后为“writer.writerow([key,k,v])”编写行。 - Anzel
请查看此链接:https://docs.python.org/3/library/csv.html#csv.DictWriter - Ma0
我尝试了两个答案:第一个答案出现了很多错误: rows = [a]+[[q]+[user_item[p].get(q, '-') for p in a[1:]] for q in x] TypeError: 'dict_keys' object is not subscriptable 第二个答案也出现了错误: writer = csv.DictWriter(outf, [" "] + user_item.keys()) TypeError: can only concatenate list (not "dict_keys") to list - Paldro
4个回答

1
只需循环遍历字典并使用 Python csv writer 将其写入 csv 文件即可。
with open('output.csv', 'w') as csv_file:
    csvwriter = csv.writer(csv_file, delimiter='\t')
    for session in users_item:
        for item in users_item[session]:
            csvwriter.writerow([session, item, users_item[session][item]])

你应该知道 writerow 只接受一个参数,但是在你的代码中却给了3个。 - Paldro
@Đức Phan 抱歉,忘记了外部括号,现在已经修复。 - mowcow
这是你的代码出现的错误:writer.writerow([session, item, user_item[session][item]]) TypeError: 'str'不支持缓冲区接口。 - Paldro
啊,我在Python 2中打开文件时习惯使用“wb”。在Python 3中打开CSV文件时请改用“w”。代码又变了。 - mowcow

1
for session, ratings in users_item.items():
    for rating, value in ratings.items():
        print("{} {}".format(session, value))

输出:

sessionId3 5.0
sessionId3 1.0
sessionId3 5.0
sessionId3 1.0
sessionId1 5.0
sessionId1 1.0
sessionId4 1.0
sessionId2 1.0

请注意,dictuser_items没有顺序。因此,除非您使用其他方式指定行的顺序,否则输出将按照dict在内部使用的顺序排列。 编辑:这种方法对包含70k条目的文件没有问题。 编辑:如果您想写入CSV文件,请使用csv模块或将输出重定向到文件。

但我需要将数据写入CSV文件,而不是打印出来! - Paldro
你可以轻松地通过使用 https://docs.python.org/3/library/csv.html 来适应我的答案。 - user5547025

0

假设您希望每个会话作为一行,每行的列数将是所有会话字典中唯一键的总数。根据您提供的数据,我猜测唯一键的数量是天文数字。

这就是为什么您在使用此讨论中提供的解决方案时遇到内存问题的原因。这只是太多的数据一次性保存在内存中。

如果我的假设是正确的,那么您唯一的选择就是分而治之。将数据分成较小的块,并以csv格式写入文件。然后在最后合并csv文件。


0

如果您迭代地编写文件,则不应出现内存问题:

import csv

users_item = {
    "sessionId1": {
        "12345645647": 1.0,
        "9798654": 5.0

    },
    "sessionId2":{
        "3445657657": 1.0

    },
    "sessionId3": {
        "87967976": 5.0,
        "35325626436": 1.0,
        "126789435": 1.0,
        "72139856": 5.0
    },
    "sessionId4": {
        "4582317": 1.0
    }
}

with open('nested_dict.csv', 'w') as output:
    writer = csv.writer(output, delimiter='\t')
    for sessionId in sorted(users_item):
        ratings = users_item[sessionId]
        for item in ratings:
            writer.writerow([sessionId, item, ratings[item]])

输出文件的结果内容(其中»表示制表符):

sessionId1»  12345645647»  1.0
sessionId1»  9798654»      5.0
sessionId2»  3445657657»   1.0
sessionId3»  126789435»    1.0
sessionId3»  87967976»     5.0
sessionId3»  35325626436»  1.0
sessionId3»  72139856»     5.0
sessionId4»  4582317»      1.0

感谢您的帮助,但如果出现错误:'str' does not support the buffer interface,那么这是在sessionIdstr时出现的错误。 - Paldro
sessionId 应该是一个字符串,因为 users_item 字典的键是字符串 - 所以我不理解这个错误。 - martineau
在Python 3中,将“wb”更改为“w”将解决错误。然后它会正常工作! - Paldro
你应该将你的问题标记为Python 3(就像我刚刚为你所做的那样)。 - martineau
抱歉!下次我会更加小心地提问。 - Paldro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接