Python: 将计数器写入CSV文件

6

我有一个包含以下列的数据csv文件:‘number’, ’colour’, ’number2’, ’foo’, ’bar’,看起来像这样:

12, red, 124, a, 15p
14, blue, 353, c, 7g
12, blue, 125, d, 65h
12, red, 124, c, 12d

我想要统计数字、颜色和数字2同时出现的次数。例如,以上列表的输出应为:'12,红色,124: 2','14,蓝色,353: 1','12,蓝色,125: 1'。我是通过以下方式实现的:

import csv
datafile=open('myfile.csv','r')
usefuldata=[] 
for line in datafile: 
    usefuldata.append(line) 
from collections import Counter
outfile1=Counter((line[1],line[2],line[3]) for line in usefuldata)  
print(outfile1)

这给我带来了:

Counter({(‘12’,’red’,’135’): 21, (‘15’,’blue’,’152’):18, (‘34’,’green’,’123’):16 etc})

这很不错,但是我想将它写入文件中。我希望该文件有4列:数字、颜色、数字2和计数。我意识到这是一个常见的问题,我尝试了其他线程上建议的几种不同方法,但都没有成功。

Newfile=open(‘newfile.csv’,’wb’)
fieldnames=['a','b']
csvwriter=csv.DictWriter(newfile, delimiter=',', fieldnames=fieldnames)
csvwriter.writerow(dict((fn,fn) for fn in fieldnames))
for row in outfile1:
    csvwriter.writerow(row)

And

with open('newfile.csv','wb') as csvfile:
    fieldnames=['number','colour','number2']
    writer=csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow(Counter((line[1],line[2],line[3]) for line in usefuldata))
    countwriter=csv.writer(csvfile, delimiter=', ')
    countwriter.writerow(outfile1)

两者都给我错误提示

    return self.writer.writerow(self._dict_to_list(rowdict))
TypeError: 'str' does not support the buffer interface

我也尝试使用pickle:

import pickle
with open('newfile.csv','wb') as outputfile:
    pickle.dump(outfile1, outputfile)

给我生成了一些无用的文件。

我的当前尝试是使用

writer=csv.DictWriter(newfile, outfile1)
for line in outfile1:
    writer.writerow(line)

但是这会给我一个有关字段名的错误。

我知道这是一个常见的问题,我也清楚我之所以只是在挣扎,是因为我真的不知道我在做什么——我已经好几年没有使用Python了,而且我忘记了很多东西。任何帮助都将不胜感激。


如果你正在传递一个生成器/序列,请使用"writerows"而不是"writerow"。Pickle文件对于人类来说是无意义的,但对于Pickle来说是可读的,如果你想在其他地方加载它们。DictWriter的参数是:csvfile、fieldnames等,因此你的第一个参数是文件,第二个参数是字段名称列表。 - swstephe
5个回答

6
首先,主要问题的原因是 -
TypeError: 'str' does not support the buffer interface

如果您以二进制模式打开文件,那么应该以文本模式(不带b)打开文件。

其次,我认为在您的情况下使用普通的csv.writer比使用csv.DictWriter()更容易,因为字典的创建方式不同。

将结果写入csv的一种方法是 -

#Assuming you have previously created the counter you want to write
#lets say you stored the counter in a variable called cnter
with open('newfile.csv','w') as csvfile:
    fieldnames=['number','colour','number2','count']
    writer=csv.writer(csvfile)
    writer.writerow(fieldnames)
    for key, value in cnter.items():
        writer.writerow(list(key) + [value]) 

3
import csv

假设count是一个Python 3的计数器。
如果key是一个字符串,不要将它分割为包含每个字符的子串 :

with open(root+'counter_test.csv','w') as csvfile:
    writer=csv.writer(csvfile)
    for key, value in count.items():
        writer.writerow([key] + [value])

更简单的方法(注意在writerows()函数中加上's'):

with open(root+'counter_test.csv','w') as csvfile:
    writer=csv.writer(csvfile)
    writer.writerows(count.items())

1
使用 pandas DataFrame,你可以使用这个简单的一行代码:
pd.DataFrame(Counter(my_list).most_common(), columns=["item", "count"]).to_csv("./myfile.csv")

熊猫可以从字典(和计数器)创建一个DataFrame,您必须在构造函数中指定DataFrame的列名(因此是columns=["item", "count"])。然后,DataFrame类有一个简单的to_csv()方法(在调用此方法时可能希望使用index=False)。

1

对我来说,上面的解决方案没有起作用。它将单词的所有字符分割到不同的列中,因此输出结果是“每个字符在一个单独的列中,然后是计数”,而不是整个单词在一列中,然后是计数。这可能是由于我可能犯了其他错误所致。 但是,下面的代码对我起作用:

    with open(outfile, encoding='utf-8-sig', mode='w') as fp:
        fp.write('KMC,freq\n')  
        for tag, count in cnt.items():  
            fp.write('{},{}\n'.format(tag, count))  

我希望这对其他人有所帮助


是的。谢谢分享这个替代方案。我也遇到了类似的问题。 - Mitali Patel

0

通过使用for循环,我们可以向CSV读取器添加序列计数器,以下代码将在csv文件中显示计数器。

import csv

x=0
reader = csv.reader(open("c:/path/abc.csv"))
for raw in reader:
    x += 1
    print(raw)
    print(x)

дЄКињ∞дї£з†Бе∞ЖжШЊз§Їдї•дЄЛиЊУеЗЇ

['id'пЉМ'fname'пЉМ'lname'] 1 ['1'пЉМ'a'пЉМ'x'] 2 ['2'пЉМ'b'пЉМ'y'] 3 ['3'пЉМ'c'пЉМ'z'] 4


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