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)
Ten kod czyta thefile.csv
, wprowadza zmiany i zapisuje wyniki thefile_subset1
.
Jednak gdy otwieram wynikowy plik csv w programie Microsoft Excel, po każdym rekordzie jest dodatkowy pusty wiersz!
Czy istnieje sposób, aby nie wstawiać dodatkowej pustej linii?
Odpowiedzi:
W Pythonie 2 otwórz
outfile
w trybie'wb'
zamiast'w'
.csv.writer
Zapisuje\r\n
do pliku bezpośrednio. Jeśli nie otworzysz pliku w trybie binarnym , zapisze,\r\r\n
ponieważ w systemie Windows tryb tekstowy przetłumaczy każdy\n
na\r\n
.W Pythonie 3 wymagana składnia uległa zmianie (patrz łącza do dokumentacji poniżej), więc zamiast tego otwórz
outfile
za pomocą dodatkowego parametrunewline=''
(pusty ciąg).Przykłady:
Linki do dokumentacji
źródło
io.open
znewlines
argumentu. Jeśli nadal piszesz w wersji 2.x, i tak wydaje się to lepszym wyborem, ponieważ jest kompatybilny z przyszłością.io.open
. Istniejeunicodecsv
moduł innej firmy dla Python 2.7, który działa lepiej.newline=''
sztuczka nie działa w Python3 z StringIO lub TemporaryFile?StringIO
buforuje te same punkty kodowe, które byłyby zakodowane w pliku, iTemporaryFile
obsługujenewline
parametr, dzięki czemu można go otworzyć tak jak za pomocąopen
. Zadaj pytanie za pomocą przykładowego programu, który nie działa.Otwarcie pliku w trybie binarnym „wb” nie będzie działać w Pythonie 3+. A raczej trzeba będzie przekonwertować dane na dane binarne przed ich zapisaniem. To tylko kłopot.
Zamiast tego powinieneś zachować go w trybie tekstowym, ale zastąpić nowy wiersz jako pusty. Tak jak:
źródło
Prosta odpowiedź jest taka, że pliki csv powinny zawsze być otwierane w trybie binarnym, zarówno na wejściu, jak i na wyjściu, ponieważ w przeciwnym razie w systemie Windows występują problemy z zakończeniem linii. Konkretnie na wyjściu modułu CSV napisze
\r\n
(standardowy terminator wiersza CSV), a następnie (w trybie tekstowym) runtime zastępujący\n
przez\r\n
(standardowej linii terminatora systemie Windows) daje wynik\r\r\n
.Grzebanie w
lineterminator
NIE jest rozwiązaniem.źródło
Uwaga: Wydaje się, że nie jest to preferowane rozwiązanie ze względu na sposób dodawania dodatkowej linii w systemie Windows. Jak stwierdzono w dokumencie python :
Windows to jedna z takich platform, na której to robi różnicę. Chociaż zmiana terminatora linii, jak opisano poniżej, mogła rozwiązać problem, problemu można całkowicie uniknąć, otwierając plik w trybie binarnym. Można powiedzieć, że to rozwiązanie jest bardziej „eleganckie”. „Błąkanie się” za pomocą terminatora linii prawdopodobnie spowodowałoby w tym przypadku niemożliwy do przeniesienia kod między systemami, w którym otwarcie pliku w trybie binarnym w systemie uniksowym nie daje żadnego efektu. to znaczy. powoduje kod kompatybilny z wieloma systemami.
Z Python Docs :
Oryginał :
Jako część opcjonalnych parametrów dla csv.writer, jeśli otrzymujesz dodatkowe puste linie, być może będziesz musiał zmienić lineterminator (informacje tutaj ). Przykład poniżej dostosowany ze strony csv docs strony python . Zmień to z „\ n” na cokolwiek powinno być. Ponieważ jest to po prostu kłótnia w ciemności na problem, to może, ale nie musi działać, ale to moje najlepsze przypuszczenie.
źródło
Piszę tę odpowiedź wrt do Pythona 3, ponieważ początkowo mam ten sam problem.
Miałem pobrać dane z arduino
PySerial
i zapisać je w pliku .csv. Każde czytanie w moim przypadku kończyło się'\r\n'
, więc nowa linia zawsze oddzielała każdą linię.W moim przypadku
newline=''
opcja nie działała. Ponieważ pokazał błąd:Wydawało się więc, że nie akceptują tutaj pominięcia nowej linii.
Widząc tylko jedną z odpowiedzi tutaj, wspomniałem terminator linii w obiekcie piszącym, np .:
writer = csv.writer(csv_file, delimiter=' ',lineterminator='\r')
i to zadziałało dla mnie, pomijając dodatkowe nowe linie.
źródło
with open('my_file.csv', 'a',newline='') as csvfile:
działa absolutnie dobrze. Problem z twoją odpowiedzią polega na tym, że piszesz tutaj' '
zamiast''
„Lineterminator = '\ r” ”pozwala przejść do następnego wiersza bez pustego wiersza między dwoma.
źródło
Pożyczanie od tej odpowiedzi , wydaje się, że najczystszym rozwiązaniem jest użycie
io.TextIOWrapper
. Udało mi się rozwiązać ten problem dla siebie w następujący sposób:Powyższa odpowiedź nie jest kompatybilna z Pythonem 2. Aby mieć kompatybilność, przypuszczam, że wystarczy po prostu zawrzeć całą logikę pisania w
if
bloku:źródło
Użyj metody zdefiniowanej poniżej, aby zapisać dane do pliku CSV.
Wystarczy dodać dodatkowy
newline=''
parametr wopen
metodzie:Spowoduje to zapisanie wierszy CSV bez tworzenia dodatkowych wierszy!
źródło
Korzystając z Python 3, można uniknąć pustych linii za pomocą modułu kodeków . Jak stwierdzono w dokumentacji, pliki są otwierane w trybie binarnym, więc żadna zmiana kwarg nowej linii nie jest konieczna. Ostatnio miałem ten sam problem i to działało dla mnie:
źródło