【问题标题】:How to fix the following issue writing a dictionary into a csv?如何解决将字典写入 csv 的以下问题?
【发布时间】:2016-12-17 19:44:41
【问题描述】:

您好,我正在使用 sklearn 并使用 kmeans 进行自然语言处理,我使用 Kmeans 从 cmets 创建集群,然后我创建了一个字典,其中集群的数量作为 Key 和关联的 cmets 列表作为值如下:

dict_clusters = {}
for i in range(0,len(kmeans.labels_)):
    #print(kmeans.labels_[i])
    #print(listComments[i])
    if not kmeans.labels_[i] in dict_clusters:
        dict_clusters[kmeans.labels_[i]] = []
    dict_clusters[kmeans.labels_[i]].append(listComments[i])
print("dictionary constructed")

我想用我试过的这本字典写一个 csv:

Out = open("dictionary.csv", "wb")
w = csv.DictWriter(Out,dict_clusters.keys())
w.writerows(dict_clusters)
Out.close()

但是我不确定为什么会出错,因为我收到以下错误,此外我不确定此错误是否与 numpy 有关,因为 kmeans.labels_ 包含多个值,

Traceback (most recent call last):
  File "C:/Users/CleanFile.py", line 133, in <module>
    w.writerows(dict_clusters)
  File "C:\Program Files\Anaconda3\lib\csv.py", line 156, in writerows
    return self.writer.writerows(map(self._dict_to_list, rowdicts))
  File "C:\Program Files\Anaconda3\lib\csv.py", line 146, in _dict_to_list
    wrong_fields = [k for k in rowdict if k not in self.fieldnames]
TypeError: 'numpy.int32' object is not iterable

感谢您对此的支持,我希望用我的字典获得一个 csv,如下所示:

key1, value
key2, value
.
.
.
keyN, value

在收到这里的反馈后,我尝试了:

with open("dictionary.csv", mode="wb") as out_file:
    writer = csv.DictWriter(out_file, headers=dict_clusters.keys())
    writer.writerow(dict_clusters)

我明白了:

Traceback (most recent call last):
  File "C:/Users/CleanFile.py", line 129, in <module>
    writer = csv.DictWriter(out_file, headers=dict_clusters.keys())
TypeError: __init__() missing 1 required positional argument: 'fieldnames'

尝试2:

Out = open("dictionary.csv", "wb")
w = csv.DictWriter(Out,dict_clusters.keys())
w.writerows([dict_clusters])
Out.close()

输出:

Traceback (most recent call last):
  File "C:/Users/CleanFile.py", line 130, in <module>
    w.writerows([dict_clusters])
  File "C:\Program Files\Anaconda3\lib\csv.py", line 156, in writerows
    return self.writer.writerows(map(self._dict_to_list, rowdicts))
TypeError: a bytes-like object is required, not 'str'

attempt3,这个尝试需要很长时间来计算输出:

Out = open("dictionary.csv", "wb")
w = csv.DictWriter(Out,dict_clusters.keys())
w.writerow(dict_clusters)
Out.close()

我使用的python版本如下:

3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul  5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
3.5.2

在尝试了很多次之后,我决定使用更好的方法来构建我的字典,如下所示:

from collections import defaultdict
pairs = zip(y_pred, listComments)

dict_clusters2 = defaultdict(list)

for num, comment in pairs:
    dict_clusters2[num].append(comment)

但似乎某些字符导致 csv 文件的创建失败,如下所示:

with open('dict.csv', 'w') as csv_file:
    writer = csv.writer(csv_file)
    for key, value in dict_clusters2.items():
       writer.writerow([key, value])

输出:

Traceback (most recent call last):
  File "C:/Users/CleanFile.py", line 146, in <module>
    writer.writerow([key, value])
  File "C:\Program Files\Anaconda3\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f609' in position 6056: character maps to <undefined>

为了更清楚我执行了:

for k,v in dict_clusters2.items():
    print(k, v)

我得到了类似的东西:

1 ['hello this is','the car is red',....'performing test']
2 ['we already have','another comment',...'strings strings']
.
.
19 ['we have',' comment music',...'strings strings dance']

我的字典有一个键和几个 cmets 的列表我想要一个 csv 如下:

1,'hello this is','the car is red',....'performing test'
2,'we already have','another comment',...'strings strings'
.
.
19,'we have',' comment music',...'strings strings dance'

但是好像有些角色没有很好的映射,一切都失败了,我想得到支持谢谢支持。

【问题讨论】:

  • 与问题无关:您可能想查看enumeratedict.setdefault 第一个代码块可以写成for i, label in enumerate(kmeans.labels_): dict_clusters.setdefault(label, []).append(listComments[i]) 之类的东西(尽管最好分成几行)
  • 甚至比enumerate 更好,在这种情况下,您可能需要查看zip 以同时循环遍历listCommentskmeans.labels_。更多关于索引循环的信息:treyhunner.com/2016/04/how-to-loop-with-indexes-in-python
  • 作为dict.setdefault 的替代品,可以使用collections.defaultdict(list)。我通常更喜欢defaultdict 而不是dict.setdefault,但它们都达到了相同的目的。
  • 您打开文件以写入字节"wb",但 csv 模块正在尝试写入字符串,因此只需将其更改为 "w"
  • 等待.. 我认为您将数据以错误的格式放入 csv.DictWriter,您能否提供一个(小)基本示例,说明您开始使用的数据是什么样的以及 csv 如何应该看起来像输出?我认为您需要制作一个字典列表,其中每个值都代表一行,而不是一个包含每列列表的字典。

标签: python csv numpy dictionary anaconda


【解决方案1】:

你的特殊字符,在 Py3 Ipython 会话中呈现为:

In [31]:  '\U0001f609'
Out[31]: '?'

给我们一个字典的小样本,或者更好的是你用来构建它的值。

我与csv 合作的次数不多,csv.DictWriter 的合作更少。 numpy 用户经常用np.savetxt 编写csv 文件。这在编写纯数字数组时很容易使用。如果您想编写字符和数字列的混合,则需要使用结构化数组。

另一种选择是直接编写一个文本文件。只需打开它,然后使用f.write(...) 将格式化的行写入文件。事实上np.savetxt 基本上就是这样做的:

with open(filename, 'w') as f:
    for row in myArray:
       f.write(fmt % tuple(row))

savetxt 构造一个fmt 字符串,如%s, %d, %f\n。它也适用于字节串,需要wb 模式。因此,您的特殊角色可能会遇到更多问题。

这可能有助于专注于打印你的字典,一次一个键,例如

for k in mydict.keys():
   print(`%s, %s`%(k, mydict[k]))

首先。一旦你得到正确的print 格式,就很容易将其转换为文件写入。

================

我可以用你的代码编写一个假设的字典:

In [58]: adict={1:'\U0001f609'}
In [59]: with open('test.txt','w') as f:
    ...:     writer=csv.writer(f)
    ...:     for k,v in adict.items():
    ...:         writer.writerow([k,v])
    ...:         
In [60]: cat test.txt
1,?

【讨论】:

  • 感谢这破坏了 csv 文件的生成,您知道如何避免此异常吗?非常感谢您的支持
  • 感谢您的支持,如果您需要其他详细信息以帮助我,我添加了有关如何组成我的字典的更多详细信息,请告诉我非常感谢,以帮助我克服这种情况
【解决方案2】:

writerows method 必须获取字典列表:

Out = open("dictionary.csv", "wb")
w = csv.DictWriter(Out,dict_clusters.keys())
w.writerows([dict_clusters])
Out.close()

您可能正在寻找采用单个字典对象的writerow

Out = open("dictionary.csv", "wb")
w = csv.DictWriter(Out,dict_clusters.keys())
w.writerow(dict_clusters)
Out.close()

除此之外:您可能还想考虑使用open 作为上下文管理器(在with 块中)以确保正确关闭文件:

with open("dictionary.csv", mode="wb") as out_file:
    writer = csv.DictWriter(out_file, headers=dict_clusters.keys())
    writer.writerow(dict_clusters)

【讨论】:

  • @ Trey Hunner ,我尝试了 3 次,但无法获得所需的 csv 我不确定发生了什么,我想感谢支持,非常感谢您的关注,我的问题更新了@Tadhg McDonald-Jensen 的新尝试,
猜你喜欢
  • 1970-01-01
  • 2017-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
相关资源
最近更新 更多