用 Python 编写的 CSV 文件每行之间都有空行
- 2024-11-26 08:36:00
- admin 原创
- 181
问题描述:
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 时,每条记录后面都会有一个额外的空白行!
有没有办法让它不留多余的空行?
解决方案 1:
该csv.writer
模块直接控制行尾并`直接写入文件。在**Python 3**中,必须使用参数(空字符串)以未翻译的文本模式打开文件,
'w', newline=''否则它将
在 Windows 上写入,其中默认文本模式会将每个文件翻译
为
`。
#!python3
with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:
writer = csv.writer(outfile)
如果使用Path
模块:
from pathlib import Path
import csv
with Path('/pythonwork/thefile_subset11.csv').open('w', newline='') as outfile:
writer = csv.writer(outfile)
如果使用该StringIO
模块构建内存结果,结果字符串将包含翻译后的行终止符:
from io import StringIO
import csv
s = StringIO()
writer = csv.writer(s)
writer.writerow([1,2,3])
print(repr(s.getvalue())) # '1,2,3
' (Windows result)
如果稍后将该字符串写入文件,请记住使用newline=''
:
# built-in open()
with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as f:
f.write(s.getvalue())
# Path's open()
with Path('/pythonwork/thefile_subset11.csv').open('w', newline='') as f:
f.write(s.getvalue())
# Path's write_text() added the newline parameter to Python 3.10.
Path('/pythonwork/thefile_subset11.csv').write_text(s.getvalue(), newline='')
在Python 2中,使用二进制模式打开而不是outfile
模式,以防止 Windows 换行符转换。Python 2 也存在 Unicode 问题,需要其他解决方法才能写入非 ASCII 文本。如果您必须在 Python 2 上将 Unicode 字符串写入 CSV,请参阅下面的 Python 2 链接以及页面末尾的示例,或者查看第三方unicodecsv模块:'wb'
`'w'UnicodeReader
UnicodeWriter`
#!python2
with open('/pythonwork/thefile_subset11.csv', 'wb') as outfile:
writer = csv.writer(outfile)
文档链接
解决方案 2:
在 Python 3+ 中,以二进制模式“wb”打开文件将不起作用。或者,您必须先将数据转换为二进制,然后再写入。这很麻烦。
相反,你应该将其保留在文本模式,但将换行符覆盖为空。如下所示:
with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:
解决方案 3:
自最初问题提出以来的十年里,许多其他答案已经过时了。对于 Python3,答案就在文档中:
如果 csvfile 是文件对象,则应使用以下命令打开它
newline=''
脚注中更详细地解释道:
如果未指定 newline='',则无法正确解释引号字段内嵌入的换行符,并且在使用 \r\n 换行符的平台上,写入时会添加额外的 \r。指定 newline='' 应该始终是安全的,因为 csv 模块会执行其自己的(通用)换行符处理。
解决方案 4:
注意:由于在 Windows 系统上添加了额外的行,因此这似乎不是首选解决方案。如Python 文档中所述:
如果 csvfile 是一个文件对象,则必须在有区别的平台上使用“b”标志打开它。
Windows 就是这样一个平台,它会产生影响。虽然按照我下面所述更改行终止符可能已经解决了问题,但可以通过以二进制模式打开文件完全避免该问题。有人可能会说这个解决方案更“优雅”。在这种情况下,“摆弄”行终止符可能会导致系统之间无法移植的代码,而在 unix 系统上以二进制模式打开文件不会产生任何效果。即,它会产生跨系统兼容的代码。
来自Python文档:
在 Windows 上,模式后面附加“b”会以二进制模式打开文件,因此还有“rb”、“wb”和“r+b”等模式。Windows 上的 Python 区分文本文件和二进制文件;在读取或写入数据时,文本文件中的行尾字符会自动略微改变。这种对文件数据的幕后修改对于 ASCII 文本文件来说没问题,但它会损坏 JPEG 或 EXE 文件中的二进制数据。在读取和写入此类文件时,请务必小心使用二进制模式。在 Unix 上,将“b”附加到模式不会有什么坏处,因此您可以独立于平台地将其用于所有二进制文件。
原来的:
作为 csv.writer 的可选参数的一部分,如果您得到了额外的空白行,您可能需要更改 lineterminator(信息在这里)。下面的示例改编自 python 页面csv 文档。 将其从 '\n' 更改为任何应该的值。由于这只是对问题的盲目尝试,它可能有效也可能无效,但这是我最好的猜测。
>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'w'), lineterminator='
')
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
解决方案 5:
简单的答案是,csv 文件应始终以二进制模式打开,无论是输入还是输出,否则在 Windows 上会出现行尾问题。具体来说,在输出时,csv 模块将写入(标准 CSV 行终止符),然后(在文本模式下)运行时将用(Windows 标准行终止符)`替换,从而得到结果。
``
``
`
摆弄它lineterminator
并不是解决办法。
解决方案 6:
使用下面定义的方法将数据写入 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 行而无需创建额外的行!
解决方案 7:
我正在用 python 3 写这个答案,因为我最初遇到了同样的问题。
我应该使用 从 arduino 获取数据PySerial
,并将它们写入 .csv 文件中。在我的例子中,每个读数都以 结尾`'
'`,因此换行符总是将每行分隔开。
就我而言,newline=''
选项不起作用。因为它显示了一些错误,例如:
with open('op.csv', 'a',newline=' ') as csv_file:
ValueError: illegal newline value: ''
因此看起来他们不接受这里省略换行符。
只看到这里的一个答案,我在编写器对象中提到了行终止符,例如,
`writer = csv.writer(csv_file, delimiter=' ',lineterminator='
')`
这对我来说有助于跳过额外的换行符。
解决方案 8:
with open(destPath+'\\'+csvXML, 'a+') as csvFile:
writer = csv.writer(csvFile, delimiter=';', lineterminator='
')
writer.writerows(xmlList)
“lineterminator='\r'” 允许传递到下一行,两行之间没有空行。
解决方案 9:
借用这个答案,似乎最干净的解决方案是使用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
解决方案 10:
我使用了 writerow
def write_csv(writer, var1, var2, var3, var4):
"""
write four variables into a csv file
"""
writer.writerow([var1, var2, var3, var4])
numbers=set([1,2,3,4,5,6,7,2,4,6,8,10,12,14,16])
rules = list(permutations(numbers, 4))
#print(rules)
selection=[]
with open("count.csv", 'w',newline='') as csvfile:
writer = csv.writer(csvfile)
for rule in rules:
number1,number2,number3,number4=rule
if ((number1+number2+number3+number4)%5==0):
#print(rule)
selection.append(rule)
write_csv(writer,number1,number2,number3,number4)
解决方案 11:
使用 Python 3 时,可以使用codecs模块避免出现空行。如文档中所述,文件以二进制模式打开,因此无需更改换行符。我最近遇到了同样的问题,这种方法对我有用:
with codecs.open( csv_file, mode='w', encoding='utf-8') as out_csv:
csv_out_file = csv.DictWriter(out_csv)