Python ile yazılmış CSV dosyasında her satır arasında boş satır var


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)

Bu kod sonuçları okur thefile.csv, değiştirir ve sonuçları yazar thefile_subset1.

Ancak, ortaya çıkan csv'yi Microsoft Excel'de açtığımda, her kayıttan sonra fazladan bir boş satır var!

Fazladan boş bir çizgi koymamasının bir yolu var mı?


4
Lütfen bu kodu Windows'ta
John Machin


Yanıtlar:


887

Python 2'de, yerine outfilemod ile açın . Yazıyor doğrudan dosya içine. Dosyayı ikili modda açmazsanız, Windows metin modunda her birini çevireceğinden dosya yazılır .'wb''w'csv.writer\r\n\r\r\n\n\r\n

Python 3'te gerekli sözdizimi değişti (aşağıdaki belge bağlantılarına bakın), bunun yerine outfileek parametre newline=''(boş dize) ile açın .

Örnekler:

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

Dokümantasyon Bağlantıları


1
Her neyse @ @ Mark Tolonen'in cevabı, standart (csv kullanılmayan) bir metin dosyası kaydedilirken eklenen ekstra satırlarla ilgili birçok soruyu çözdü.
dlewin

1
2.6 / 2.7 ve 3 arasındaki uyumluluk io.openiçin newlinesargümanla birlikte kullanabilirsiniz . Hala 2.x yazıyorsanız, ileri uyumlu olduğu için bu daha iyi bir seçim gibi görünüyor.
jpmc26

@ jpmc26 Normalde bu iyi bir tavsiye, ancak csv modülü ile düzgün çalışmıyor io.open. unicodecsvPython 2.7 için daha iyi çalışan bir 3. taraf modülü var.
Mark Tolonen

newline=''Hile neden StringIO veya TemporaryFile ile python3 içinde çalışmaz?
fmoo

@fmoo define "çalışmıyor". İkisi de beklediğim gibi çalışıyor. StringIObir dosyaya kodlanacak kod noktalarını tamponlar ve parametreyi TemporaryFiledestekler newline, böylece olduğu gibi açılabilir open. Çalışmayan örnek bir programla soru sorun.
Mark Tolonen

65

Dosyayı "wb" ikili modunda açmak Python 3+ ile çalışmaz. Ya da daha önce, verilerinizi yazmadan önce ikili dosyaya dönüştürmeniz gerekir. Bu sadece bir güçlük.

Bunun yerine, metin modunda tutmalısınız, ancak yeni satırı boş olarak geçersiz kılmalısınız. Şöyle ki:

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

13

Basit cevap, csv dosyalarının giriş veya çıkış için her zaman ikili modda açılması gerektiğidir , aksi takdirde Windows'ta satır sonuyla ilgili sorunlar vardır. Özellikle çıkışta csv modülü yazacaktır \r\n(standart CSV satır sonlandırıcı) ve ardından (metin modunda) çalışma zamanı, sonucunu veren \nby \r\n(Windows standart satır sonlandırıcısı) yerine geçer \r\r\n.

Onunla uğraşmak lineterminatorçözüm DEĞİLDİR.


Konuştuğunuz bu CSV "standardı" nedir?
Dan Breslau

3
@ Dan: "Standart" ı bir sıfat olarak kullandım, bir isim değil, "olağan" veya "sıradan" anlamına geldim. Bir (isim) standardına yaklaşmak istiyorsanız, tools.ietf.org/html/rfc4180
John Machin

1
Mesele şu ki (ima ettiğiniz gibi) standart yok. RFE Bilgilendirici. \ R \ n Windows'ta "standart" olsa da, eminim Unix uygulamaları genellikle bu şekilde görmez.
Dan Breslau

2
@ Dan: Bu doğru - standart yok. Komut dosyaları istedikleri satırlayıcıyı [varsayılan olarak ROWterminator olarak adlandırılmış olmalıdır] belirtmeli ve komut dosyasının Windows üzerinde çalışması durumunda yine de ikili modu kullanmalıdır, aksi takdirde "satırlayıcı" doldurulmuş olabilir.
John Machin

8

Not: Ekstra satırın bir Windows sistemine nasıl eklendiğinden dolayı bu tercih edilen bir çözüm değildir. Python belgesinde belirtildiği gibi :

Csvfile bir dosya nesnesiyse, bunun fark yaratacağı platformlarda 'b' bayrağıyla açılması gerekir.

Windows, fark yaratan böyle bir platformdur. Aşağıda açıkladığım gibi satır sonlandırıcıyı değiştirmek sorunu çözmüş olsa da, dosyayı ikili modda açarak sorun tamamen önlenebilir. Bu çözümün daha "elegent" olduğu söylenebilir. Hat sonlandırıcısıyla "uğraşmak", bu durumda, bir unix sistemi üzerinde ikili modda bir dosyayı açmanın hiçbir etki yaratmayacağı bu durumda sistemler arasında kaydedilemez bir kodla sonuçlanırdı. yani. çapraz sistem uyumlu kod ile sonuçlanır.

Gönderen Python Dokümanlar :

Windows'ta, moda eklenen 'b' dosyayı ikili modda açar, bu nedenle 'rb', 'wb' ve 'r + b' gibi modlar da vardır. Windows üzerinde Python metin ve ikili dosyalar arasında bir ayrım yapar; metin dosyalarındaki satır sonu karakterleri, veriler okunduğunda veya yazıldığında otomatik olarak biraz değişir. Dosya verilerindeki bu perde arkasındaki değişiklik ASCII metin dosyaları için iyidir, ancak JPEG veya EXE dosyalarındaki böyle ikili verileri bozar. Bu tür dosyaları okurken ve yazarken ikili modu kullanmaya çok dikkat edin. Unix'te, moda bir 'b' eklemek zarar vermez, böylece tüm ikili dosyalar için platformdan bağımsız olarak kullanabilirsiniz.

Orijinal :

Fazladan boş satırlar alıyorsanız, csv.writer için isteğe bağlı paramaterlerin bir parçası olarak, çizgi işaretleyiciyi değiştirmeniz gerekebilir ( buradaki bilgiler ). Aşağıdaki örnek python sayfası csv belgelerinden uyarlanmıştır . '\ N' yerine olması gereken her şeyi değiştirin. Bu sorundaki karanlıkta sadece bir bıçak olduğu için bu işe yarayıp yaramayabilir, ama benim en iyi tahminim.

>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'w'), lineterminator='\n')
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

Bu konu hakkında mesaj göndermek üzereydim - lineterminator = '\ n' basit bir testte benim için çalıştı.
Dan Breslau

bunu yapabilir miyim? open ('/ pythonwork / thefile_subset11.csv', 'w') ile lineterminator = '\ n'
dış dosya

1
@I__: Gerçekten Python belgelerini incelemeye başlamalısın. Derek size bağlantıyı verdi: docs.python.org/library/csv.html
Dan Breslau

5

Başlangıçta aynı problemi yaşadığım için bu cevabı prthon 3'e yazıyorum.

Arduino'dan veri almam PySerialve bunları bir .csv dosyasına yazmam gerekiyordu . Benim durumumdaki her okuma ile sona erdi '\r\n', bu yüzden yeni satır her zaman her satırı ayırıyordu.

Benim durumumda, newline=''seçenek işe yaramadı. Çünkü şöyle bir hata gösterdi:

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

ValueError: illegal newline value: ''

Yani burada yeni satırın ihmalini kabul etmiyorlardı.

Sadece burada cevaplardan birini gördüğümde, yazar nesnesindeki satır sonlandırıcıdan bahsettim,

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

ve bu ekstra satırları atlamak için benim için çalıştı.


2
Bu yanlış. with open('my_file.csv', 'a',newline='') as csvfile: kesinlikle iyi çalışıyor. Cevabınızla ilgili sorun şurada, bunun ' 'yerine yazdığınız''
Nasrin

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

"Lineterminator = '\ r'", ikisi arasında boş satır olmadan bir sonraki satıra geçmeye izin verir.


1

Bu cevaptan ödünç almak , en temiz çözümü kullanmak gibi görünüyor io.TextIOWrapper. Bu sorunu kendim için aşağıdaki gibi çözmeyi başardım:

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)

Yukarıdaki cevap Python 2 ile uyumlu değildir. Uyumluluk için, sadece bir ifblokta tüm yazma mantığını sarmak gerektiğini varsayalım :

if sys.version_info < (3,):
    # Python 2 way of handling CSVs
else:
    # The above logic

0

CSV dosyasına veri yazmak için aşağıda tanımlanan yöntemi kullanın.

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

Sadece yöntemin newline=''içine ek bir parametre ekleyin open:

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

Bu, CSV satırlarını ek satırlar oluşturmadan yazacaktır!


-1

Python 3 kullanılırken, codecs modülü kullanılarak boş satırlar önlenebilir . Belgelerde belirtildiği gibi, dosyalar ikili modda açılır, bu nedenle yeni satır kwargında değişiklik yapılması gerekmez. Son zamanlarda aynı sorunu yaşıyordum ve bu benim için çalıştı:

with codecs.open( csv_file,  mode='w', encoding='utf-8') as out_csv:
     csv_out_file = csv.DictWriter(out_csv)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.