web-dev-qa-db-ja.com

Pythonで書かれたCSVファイルは各行の間に空白行があります

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に書き込みます。

しかし、結果のcsvファイルをMicrosoft Excelで開くと、各レコードの後に​​余分な空白行があります。

余分な空白行を置かないようにする方法はありますか?

Python 2では、'wb'ではなくモード'w'outfileを開きます。 csv.writer\r\nをファイルに直接書き込みます。ファイルをバイナリモードで開かないと、Windowsテキストモードでは各\r\r\nが次のように変換されるため、\nが書き込まれます。 \r\n

Python 3では必要な構文が変更されたので、代わりに追加パラメータnewline=''を付けてoutfileを開きます。

例:

# 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)

ドキュメントリンク

670
Mark Tolonen

バイナリモード "wb"でファイルを開くと、Python 3+では動作しません。あるいは、データを書き込む前にデータをバイナリに変換する必要があります。それはただ面倒です。

代わりに、それをテキストモードにしておくべきですが、改行を空として上書きします。そのようです:

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

単純な答えは、csvファイルは常にバイナリモードで開く必要があります入力用か出力用かにかかわらず、Windowsの場合は行末に問題があるためです。具体的には、出力時にcsvモジュールは\r\n(標準のCSV行終了記号)を書き込み、次に(テキストモードで)ランタイムは\n\r\n(Windows標準行終了記号)に置き換えて\r\r\nの結果を返します。

lineterminatorをいじるのは解決策ではありません。

12
John Machin

注:Windowsシステムで余分な行が追加されているため、これは推奨される解決策ではないようです。 pythonドキュメント に書かれているように:

Csvfileがファイルオブジェクトの場合は、違いがあるプラットフォームでは 'b'フラグを付けて開く必要があります。

Windowsはそれが違いを生むそのようなプラットフォームの1つです。以下で説明するように行の終端文字を変更することで問題が解決したかもしれませんが、バイナリモードでファイルを開くことで問題を完全に回避できます。この解決策はもっと "賢い"と言えるかもしれません。この場合、ラインターミネータを「いじる」とシステム間でコードを移植できなくなり、UNIXシステムでバイナリモードでファイルを開いても効果がなくなります。すなわち。システム間で互換性のあるコードになります。

Pythonドキュメントから:

Windowsでは、モードに追加された 'b'はファイルをバイナリモードで開くので、 'rb'、 'wb'、 'r + b'のようなモードもあります。 Windows上のPythonはテキストファイルとバイナリファイルを区別します。テキストファイルの行末文字は、データの読み書き時に自動的にわずかに変更されます。このような舞台裏でのファイルデータの変更はASCIIテキストファイルには問題ありませんが、JPEGファイルやEXEファイルのようにバイナリデータが破損する可能性があります。そのようなファイルを読み書きするときはバイナリモードを使うように十分注意してください。 Unixでは、モードに 'b'を追加してもかまいません。したがって、すべてのバイナリファイルに対してプラットフォームに依存せずに使用できます。

オリジナル

余分な空白行がある場合は、csv.writerのオプションのパラメータの一部として、行末記号を変更する必要があるかもしれません(info ここ )。下の例は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'])
6
Derek Litz

私はこの答えを書いています。私は最初は同じ問題を抱えていたので、Python 3に。

PySerialを使用してarduinoからデータを取得し、それらを.csvファイルに書き込むことになっていました。私の場合の各読みは'\r\n'で終わっていたので、改行は常に各行を分離していました。

私の場合、newline=''オプションは機能しませんでした。以下のようなエラーが表示されたためです。

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

ValueError: illegal newline value: ''

だからここでは改行の省略を受け入れていないようです。

ここでの答えの1つだけを見て、私はライターオブジェクト内の行末記号に言及しました。

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

それは余分な改行をスキップするために私のために働きました。

3
Debanjan Dey

CSVファイルにデータを書き込むには、以下に定義されている方法を使用します。

open('outputFile.csv', 'a',newline='')

openメソッド内に追加のnewline=''パラメータを追加するだけです。

def writePhoneSpecsToCSV():
    rowData=["field1", "field2"]
    with open('outputFile.csv', 'a',newline='') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(rowData)

これにより、追加の行を作成せずにCSV行が書き込まれます。

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

"lineterminator = '\ r'"は、2行の間に空の行を入れずに、次の行に渡すことを許可します。

0
SheRa

Python 3を使うとき、 codecs モジュールを使うことで空行を避けることができます。ドキュメントに記載されているように、ファイルはバイナリモードで開かれるので、改行kwargの変更は必要ありません。私は最近同じ問題にぶつかっていました、そしてそれは私のために働きました:

with codecs.open( csv_file,  mode='w', encoding='utf-8') as out_csv:
     csv_out_file = csv.DictWriter(out_csv)
0
JBa