import csv
with open('thefile.csv', 'rb') as f:
data = list(csv.reader(f))
import collections
counter = collections.defaultdict(int)
for row in data:
counter[row[10]] += 1
with open('/pythonwork/thefile_subset11.csv', 'w') as outfile:
writer = csv.writer(outfile)
for row in data:
if counter[row[10]] >= 504:
writer.writerow(row)
此代码读取thefile.csv
,进行更改,并将结果写入thefile_subset1
。
但是,当我在Microsoft Excel中打开生成的csv时,每条记录后都会有一个额外的空行!
有没有办法让它不加一个额外的空白?
答案 0 :(得分:655)
在Python 2中,使用模式outfile
而不是'wb'
打开'w'
。 csv.writer
直接将\r\n
写入文件。如果您未在二进制模式下打开文件,它将写入\r\r\n
,因为在Windows 文本模式下会将每个\n
转换为{{ 1}}。
在Python 3中,所需语法已更改,因此请使用附加参数\r\n
打开outfile
。
newline=''
答案 1 :(得分:41)
以二进制模式打开文件“wb”在Python 3+中不起作用。或者更确切地说,在编写数据之前,您必须将数据转换为二进制数据。这只是一个麻烦。
相反,您应该将其保留在文本模式中,但将换行覆盖为空。像这样:
with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:
答案 2 :(得分:12)
简单的答案是 csv文件应始终以二进制模式打开,无论是输入还是输出,否则在Windows上存在行结尾的问题。特别是在输出时,csv模块将写入\r\n
(标准CSV行终止符),然后(在文本模式下)运行时将\n
替换为\r\n
(Windows标准行终止符)给出\r\r\n
的结果。
摆弄lineterminator
不是解决方案。
答案 3 :(得分:6)
注意:由于在Windows系统上添加额外行的方式,这似乎不是首选解决方案。如python document中所述:
如果csvfile是一个文件对象,那么它必须在平台上以“b”标志打开,这会产生影响。
Windows是一个有所作为的平台。虽然如下所述更改行终止符可能已经解决了问题,但是可以通过以二进制模式打开文件来完全避免该问题。有人可能会说这种解决方案更“优雅”。在这种情况下,使用行终止符“摆弄”可能会导致系统之间出现不可移植的代码,在unix系统上以二进制模式打开文件会导致无效。即。它导致交叉系统兼容的代码。
来自Python Docs:
在Windows上,“b”附加到模式 以二进制模式打开文件,所以 还有像'rb','wb'这样的模式, 和'r + b'。 Windows上的Python制作了一个 文本和二进制之间的区别 文件;中的行尾字符 文本文件会自动更改 稍微读取或写入数据时。 这种幕后修改 文件数据适用于ASCII文本 文件,但它会破坏二进制数据 像在JPEG或EXE文件中那样。是 非常小心使用二进制模式时 读写这样的文件。上 Unix,附加一个'b'也没有坏处 到模式,所以你可以使用它 平台 - 独立于所有二进制文件 文件。
<强>原始强>:
作为csv.writer的可选参数的一部分,如果您获得额外的空行,则可能需要更改lineterminator(info here)。以下示例改编自python页面csv docs.将其从'\ n'更改为它应该是什么。由于这只是在黑暗中解决问题,这可能会或可能不会奏效,但这是我最好的猜测。
>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'w'), lineterminator='\n')
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
答案 4 :(得分:3)
我写这个答案w.r.t.到python 3,因为我最初遇到了同样的问题。
我应该使用PySerial
从arduino获取数据,并将它们写在.csv文件中。我的案例中的每个阅读都以'\r\n'
结束,因此换行始终将每一行分开。
就我而言,newline=''
选项并不起作用。因为它显示了一些错误:
with open('op.csv', 'a',newline=' ') as csv_file:
ValueError: illegal newline value: ''
所以他们似乎不接受在这里遗漏新行。
仅在此处查看其中一个答案,我在编写器对象中提到了行终止符,如
writer = csv.writer(csv_file, delimiter=' ',lineterminator='\r')
这对于我跳过额外的换行符非常有用。
答案 5 :(得分:2)
自最初提出问题以来的十年中,许多其他答案已经过时。对于 Python3,答案就在 documentation 中:
<块引用>如果 csvfile 是一个文件对象,它应该用newline=''
打开
footnote 有更详细的解释:
<块引用>如果没有指定 newline='',嵌入在引用字段中的换行符将不会被正确解释,并且在写入时使用 \r\n linendings 的平台上将添加一个额外的 \r。指定 newline='' 应该始终是安全的,因为 csv 模块会执行自己的(通用)换行处理。
答案 6 :(得分:1)
从this answer借用,似乎最干净的解决方案是使用io.TextIOWrapper
。我设法为自己解决了以下问题:
from io import TextIOWrapper
...
with open(filename, 'wb') as csvfile, TextIOWrapper(csvfile, encoding='utf-8', newline='') as wrapper:
csvwriter = csv.writer(wrapper)
for data_row in data:
csvwriter.writerow(data_row)
以上答案与Python 2不兼容。要具有兼容性,我想一个人只需要将所有写逻辑包装在if
块中即可:
if sys.version_info < (3,):
# Python 2 way of handling CSVs
else:
# The above logic
答案 7 :(得分:0)
使用Python 3时,可以使用codecs模块来避免出现空行。如文档中所述,文件以二进制模式打开,因此不需要更改换行符kwarg。我最近遇到了同样的问题,对我有用:
with codecs.open( csv_file, mode='w', encoding='utf-8') as out_csv:
csv_out_file = csv.DictWriter(out_csv)
答案 8 :(得分:0)
使用下面定义的方法将数据写入CSV文件。
open('outputFile.csv', 'a',newline='')
只需在newline=''
方法内添加一个额外的open
参数:
def writePhoneSpecsToCSV():
rowData=["field1", "field2"]
with open('outputFile.csv', 'a',newline='') as csv_file:
writer = csv.writer(csv_file)
writer.writerow(rowData)
这将写入CSV行,而不会创建其他行!
答案 9 :(得分:0)
with open(destPath+'\\'+csvXML, 'a+') as csvFile:
writer = csv.writer(csvFile, delimiter=';', lineterminator='\r')
writer.writerows(xmlList)
“ lineterminator ='\ r'”允许传递到下一行,而两行之间不能有空行。