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ます。

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

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


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 2015

1
2.6 / 2.7と3の間の互換性のためio.openに、newlines引数とともに使用できます。それでも2.xで書いている場合は、上位互換性があるため、いずれにせよそれがより良い選択のように思えます。
jpmc26 2017

@ jpmc26通常、これは良いアドバイスですが、csvモジュールはで正しく動作しませんio.openunicodecsvPython 2.7用のサードパーティモジュールがあり、より適切に動作します。
Mark Tolonen、2018

newline=''トリックがStringIOまたはTemporaryFileのpython3で機能しない理由はありますか?
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
@ダン:正解です。標準はありません。スクリプトは、希望する(デフォルトでない場合は)ROWterminatorという名前のlineterminatorを指定し、Windowsでスクリプトを実行する場合はバイナリモードを使用する必要があります。そうしないと、「lineterminator」が詰まる可能性があります。
John Machin、

8

注:Windowsシステムで余分な行が追加されていたため、これは推奨されるソリューションではないようです。Pythonドキュメントで述べたように:

csvfileがファイルオブジェクトの場合、違いがあるプラットフォームでは、「b」フラグを使用して開く必要があります。

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

Pythonドキュメントから:

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

オリジナル

csv.writerのオプションのパラメーターの一部として、余分な空白行を取得している場合は、lineterminatorを変更する必要がある場合があります(詳細はこちら)。下記の例は、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'])

これについて投稿しようとしていました-lineterminator = '\ n'は簡単なテストでうまくいきました。
Dan Breslau

これはできますか?open( '/ pythonwork / thefile_subset11.csv'、 'w')、lineterminator = '\ n'を
出力ファイル

1
@I__:あなたは本当に Pythonのドキュメントを熟読開始する必要があります。デレクはあなたにリンクを与えました:docs.python.org/library/csv.html
Dan Breslau

5

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

私はを使用してarduinoからデータを取得PySerialし、.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')

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


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'"は、2つの行の間に空の行がなくても、次の行に渡すことを許可します。


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.