Python으로 작성된 CSV 파일에는 각 행 사이에 빈 줄이 있습니다.


446
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를 열면 각 레코드 뒤에 빈 줄이 추가됩니다!

빈 줄을 넣지 않는 방법이 있습니까?


4
Windows
John Machin


이 스레드에서 답변을 참조하십시오 : stackoverflow.com/questions/3348460/...
Febin 매튜

답변:


887

Python 2에서는 대신 outfile모드로 엽니 다 . 는 글을 직접 파일로. 이진 모드 에서 파일을 열지 않으면 Windows 텍스트 모드에서 각 파일이 로 변환 되므로 파일 이 작성 됩니다 .'wb''w'csv.writer\r\n\r\r\n\n\r\n

Python 3에서 필요한 구문이 변경되었으므로 (아래 문서 링크 참조 ) 대신 outfile추가 매개 변수 newline=''(빈 문자열)로여십시오.

예 :

# Python 2
with open('/pythonwork/thefile_subset11.csv', 'wb') as outfile:
    writer = csv.writer(outfile)

# Python 3
with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:
    writer = csv.writer(outfile)

설명서 링크


1
어쨌든 @Mark Tolonen의 답변은 표준 (CSV 사용 안 함) 텍스트 파일을 저장할 때 추가 된 줄과 관련된 많은 질문을 해결했습니다.
dlewin

1
2.6 / 2.7과 3 사이의 호환성 io.open을 위해 newlines인수 와 함께 사용할 수 있습니다 . 여전히 2.x로 쓰고 있다면 앞으로 호환되므로 더 나은 선택처럼 보입니다.
jpmc26

@ jpmc26 일반적으로 좋은 조언이지만 csv 모듈은 제대로 작동하지 않습니다 io.open. unicodecsv더 잘 작동하는 Python 2.7 용 타사 모듈 이 있습니다 .
Mark Tolonen

newline=''python3에서 StringIO 또는 TemporaryFile을 사용 하여 트릭이 작동하지 않는 이유는 무엇입니까?
fmoo

@fmoo는 "작동하지 않습니다"를 정의합니다. 그들은 모두 내가 기대하는 방식으로 작동합니다. StringIO파일로 인코딩되는 동일한 코드 포인트를 버퍼링하고 매개 변수를 TemporaryFile지원 newline하므로로 열 수 있습니다 open. 작동하지 않는 샘플 프로그램으로 질문하십시오.
Mark Tolonen

65

바이너리 모드 "wb"에서 파일을 열면 Python 3+에서 작동하지 않습니다. 또는 데이터를 작성하기 전에 데이터를 이진으로 변환해야합니다. 그것은 번거 로움입니다.

대신 텍스트 모드로 유지해야하지만 개행을 비워 두십시오. 이렇게 :

with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:

13

간단한 대답은 csv 파일은 입력 또는 출력에 관계없이 항상 이진 모드로 열어야한다는 것입니다. 그렇지 않으면 Windows에서는 줄 끝에 문제가 있습니다. 특히 출력시 csv 모듈은 \r\n(표준 CSV 행 종결 자)를 쓴 다음 (텍스트 모드에서) 런타임이 \n\r\n(Windows 표준 줄 종결 자)를 대신하여 결과를 제공합니다 \r\r\n.

를 다루는 lineterminator것이 해결책이 아닙니다.


이 CSV "표준"은 무엇입니까?
Dan Breslau

3
@Dan : 저는 "표준"을 명사가 아닌 형용사로 사용했습니다. (명사) 표준에 대한 근사치를 원하면 tools.ietf.org/html/rfc4180
John Machin

1
요점은 표준이 없다는 것을 의미합니다. 그 RFE는 정보입니다. \ r \ n은 Windows에서 "표준"일 수 있지만 Unix 응용 프로그램은 일반적으로 그렇게 보이지 않습니다.
Dan Breslau

2
@ Dan : 맞습니다. 표준이 없습니다. 스크립트는 Windows에서 스크립트를 실행하는 경우 "기본값"이 아닌 경우 원하는 줄 바꿈 ([ROWterminator]로 지정해야 함)을 지정하고 여전히 바이너리 모드를 사용해야합니다. 그렇지 않으면 "줄 바꿈"이 채워질 수 있습니다.
John Machin

8

참고 : Windows 시스템에서 추가 회선이 추가 된 방식으로 인해 이것이 선호되는 솔루션이 아닌 것 같습니다. 파이썬 문서에 명시된 바와 같이 :

csvfile이 파일 객체 인 경우 차이가있는 플랫폼에서 'b'플래그로 열어야합니다.

Windows는 차별화 된 플랫폼 중 하나입니다. 아래 설명과 같이 줄 종결자를 변경하면 문제가 해결되었을 수 있지만 이진 모드로 파일을 열어서 문제를 완전히 피할 수 있습니다. 이 솔루션이 더 "유명"하다고 말할 수 있습니다. 이 경우 라인 터미네이터를 사용하여 "Fiddling"하면 시스템간에 이식 불가능한 코드가 생성 될 수 있습니다.이 경우 UNIX 시스템에서 2 진 모드로 파일을 열면 아무런 효과가 없습니다. 즉. 크로스 시스템 호환 코드가됩니다.

에서 파이썬 문서 :

Windows에서 모드에 추가 된 'b'는 파일을 이진 모드로 열리므로 'rb', 'wb'및 'r + b'와 같은 모드도 있습니다. Windows의 Python은 텍스트 파일과 이진 파일을 구분합니다. 텍스트 파일의 줄 끝 문자는 데이터를 읽거나 쓸 때 자동으로 약간 변경됩니다. 파일 데이터에 대한 이러한 비하인드 수정은 ASCII 텍스트 파일에 적합하지만 JPEG 또는 EXE 파일에서와 같은 이진 데이터를 손상시킵니다. 이러한 파일을 읽고 쓸 때 바이너리 모드를 사용하도록주의하십시오. 유닉스에서는 'b'를 모드에 추가하는 것이 아프지 않으므로 모든 바이너리 파일에 대해 플랫폼 독립적으로 사용할 수 있습니다.

원본 :

빈 줄이 더 있으면 csv.writer에 대한 선택적 매개 변수의 일부로 lineterminator (info here ) 를 변경해야 할 수도 있습니다 . 아래 예는 파이썬 페이지 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'])

이것에 대해 게시하려고했습니다. lineterminator = '\ n'간단한 테스트에서 저에게 효과적이었습니다.
Dan Breslau

이거 할 수 있어요> ?? open ( '/ pythonwork / thefile_subset11.csv', 'w'), lineterminator = '\ n'을
아웃 파일로 사용

1
@I__ : 당신은 정말 파이썬 문서를 숙독 시작해야합니다. 데릭은 당신에게 링크를 주었다 : docs.python.org/library/csv.html
Dan Breslau

5

나는 처음에 같은 문제가 있었 으므로이 답변을 파이썬 3에 작성하고 있습니다.

arduino에서을 사용하여 데이터를 가져 PySerial와서 .csv 파일로 작성해야했습니다. 필자의 경우 각 독서는로 끝났 '\r\n'으므로 줄 바꿈은 항상 각 줄을 분리했습니다.

제 경우에는 newline=''옵션이 작동하지 않았습니다. 다음과 같은 오류가 발생했기 때문에 :

with open('op.csv', 'a',newline=' ') as csv_file:

ValueError: illegal newline value: ''

그래서 그들은 여기에서 줄 바꿈 생략을 받아들이지 않는 것 같습니다.

여기서 답변 중 하나만보고 필자는 writer 객체에서 줄 종결자를 언급했습니다.

writer = csv.writer(csv_file, delimiter=' ',lineterminator='\r')

그리고 그것은 여분의 줄 바꿈을 건너 뛰기 위해 나를 위해 일했습니다.


2
이것은 올바르지 않습니다. with open('my_file.csv', 'a',newline='') as csvfile: 절대적으로 잘 작동합니다. 당신의 대답의 문제는 여기에 당신이 ' '대신 쓰는 것입니다''
Nasrin

2
with open(destPath+'\\'+csvXML, 'a+') as csvFile:
    writer = csv.writer(csvFile, delimiter=';', lineterminator='\r')
    writer.writerows(xmlList)

"lineterminator = '\ r'"는 두 행 사이에 빈 행없이 다음 행으로 전달할 수 있습니다.


1

이 답변 에서 차용 하면 가장 깨끗한 솔루션을 사용하는 것 같습니다 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

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 행을 작성합니다!


-1

Python 3을 사용할 때 코덱 모듈 을 사용하여 빈 줄을 피할 수 있습니다 . 문서에 명시된 바와 같이, 파일은 바이너리 모드로 열리므로 개행 kwarg를 변경할 필요가 없습니다. 최근에 같은 문제가 발생하여 저에게 효과적이었습니다.

with codecs.open( csv_file,  mode='w', encoding='utf-8') as out_csv:
     csv_out_file = csv.DictWriter(out_csv)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.